From b7080c8e96625177072137d504eb8e9c9d748e49 Mon Sep 17 00:00:00 2001
From: Apple <opensource@apple.com>
Date: Tue, 10 Apr 2001 09:43:13 +0000
Subject: [PATCH] network_cmds-76.tar.gz

---
 Makefile                                      |   59 +
 Makefile.include                              |   12 +
 Makefile.preamble                             |    1 +
 PB.project                                    |   82 +
 alias/Makefile                                |   59 +
 alias/Makefile.postamble                      |  100 +
 alias/Makefile.preamble                       |  138 +
 alias/PB.project                              |   39 +
 alias/alias.c                                 | 1318 ++++++++
 alias/alias.h                                 |  166 +
 alias/alias_cuseeme.c                         |  120 +
 alias/alias_db.c                              | 2330 +++++++++++++
 alias/alias_ftp.c                             |  229 ++
 alias/alias_irc.c                             |  316 ++
 alias/alias_local.h                           |  170 +
 alias/alias_nbt.c                             |  711 ++++
 alias/alias_proxy.c                           |  805 +++++
 alias/alias_util.c                            |  137 +
 arp.tproj/Makefile                            |   48 +
 arp.tproj/Makefile.postamble                  |  115 +
 arp.tproj/Makefile.preamble                   |  113 +
 arp.tproj/PB.project                          |   41 +
 arp.tproj/arp.8                               |  122 +
 arp.tproj/arp.c                               |  554 +++
 arp.tproj/arp4.4                              |  124 +
 bootparams/Makefile                           |   46 +
 bootparams/Makefile.postamble                 |  100 +
 bootparams/Makefile.preamble                  |  138 +
 bootparams/PB.project                         |   22 +
 bootparams/bootparamd.tproj/Makefile          |   48 +
 .../bootparamd.tproj/Makefile.postamble       |  100 +
 bootparams/bootparamd.tproj/Makefile.preamble |  140 +
 bootparams/bootparamd.tproj/PB.project        |   27 +
 bootparams/bootparamd.tproj/bootparam_proc.c  |  210 ++
 bootparams/bootparamd.tproj/bootparamd.c      |  147 +
 bootparams/bootparams/Makefile                |   52 +
 bootparams/bootparams/Makefile.postamble      |  109 +
 bootparams/bootparams/Makefile.preamble       |  144 +
 bootparams/bootparams/PB.project              |   30 +
 bootparams/bootparams/bootparam_prot.x        |  119 +
 bootparams/bpwhoami.tproj/Makefile            |   48 +
 bootparams/bpwhoami.tproj/Makefile.postamble  |  100 +
 bootparams/bpwhoami.tproj/Makefile.preamble   |  139 +
 bootparams/bpwhoami.tproj/PB.project          |   27 +
 bootparams/bpwhoami.tproj/bpwhoami.c          |  246 ++
 domainname.tproj/Makefile                     |   48 +
 domainname.tproj/Makefile.dist                |    6 +
 domainname.tproj/PB.project                   |   36 +
 domainname.tproj/domainname.1                 |   60 +
 domainname.tproj/domainname.c                 |   97 +
 ftp.tproj/Makefile                            |   52 +
 ftp.tproj/Makefile.postamble                  |  123 +
 ftp.tproj/Makefile.preamble                   |  130 +
 ftp.tproj/PB.project                          |   34 +
 ftp.tproj/cmds.c                              | 2236 ++++++++++++
 ftp.tproj/cmdtab.c                            |  207 ++
 ftp.tproj/domacro.c                           |  168 +
 ftp.tproj/extern.h                            |  176 +
 ftp.tproj/ftp.1                               | 1157 +++++++
 ftp.tproj/ftp.c                               | 1542 +++++++++
 ftp.tproj/ftp_var.c                           |  135 +
 ftp.tproj/ftp_var.h                           |  149 +
 ftp.tproj/h.template                          |   11 +
 ftp.tproj/m.template                          |   18 +
 ftp.tproj/main.c                              |  528 +++
 ftp.tproj/pathnames.h                         |   62 +
 ftp.tproj/ruserpass.c                         |  300 ++
 ftpd.tproj/Makefile                           |   53 +
 ftpd.tproj/Makefile.postamble                 |  111 +
 ftpd.tproj/Makefile.preamble                  |  119 +
 ftpd.tproj/PB.project                         |   40 +
 ftpd.tproj/extern.h                           |   88 +
 ftpd.tproj/ftpcmd.y                           | 1269 +++++++
 ftpd.tproj/ftpd.8                             |  291 ++
 ftpd.tproj/ftpd.c                             | 1686 ++++++++++
 ftpd.tproj/logwtmp.c                          |   98 +
 ftpd.tproj/pathnames.h                        |   63 +
 ftpd.tproj/popen.c                            |  194 ++
 ftpd.tproj/vers.c                             |   62 +
 identd.tproj/CREDITS                          |   52 +
 identd.tproj/Makefile                         |   50 +
 identd.tproj/Makefile.dist                    |   10 +
 identd.tproj/Makefile.preamble                |    2 +
 identd.tproj/PB.project                       |   40 +
 identd.tproj/README                           |  129 +
 identd.tproj/config.c                         |   71 +
 identd.tproj/error.h                          |   67 +
 identd.tproj/identd.8                         |  238 ++
 identd.tproj/identd.c                         |  643 ++++
 identd.tproj/identd.h                         |   68 +
 identd.tproj/netbsd.c                         |  265 ++
 identd.tproj/parse.c                          |  425 +++
 identd.tproj/proxy.c                          |  123 +
 identd.tproj/version.c                        |   25 +
 identd.tproj/xpaths.h                         |   89 +
 ifconfig.tproj/Makefile                       |   51 +
 ifconfig.tproj/Makefile.dist                  |    6 +
 ifconfig.tproj/Makefile.postamble             |    3 +
 ifconfig.tproj/Makefile.preamble              |    3 +
 ifconfig.tproj/PB.project                     |   32 +
 ifconfig.tproj/ifconfig.8                     |  320 ++
 ifconfig.tproj/ifconfig.c                     |  870 +++++
 ifconfig.tproj/ifconfig.h                     |   46 +
 ifconfig.tproj/ifmedia.c                      |  554 +++
 inetd.tproj/Makefile                          |   50 +
 inetd.tproj/Makefile.postamble                |  110 +
 inetd.tproj/Makefile.preamble                 |  113 +
 inetd.tproj/PB.project                        |   41 +
 inetd.tproj/inetd.8                           |  381 +++
 inetd.tproj/inetd.c                           | 1293 +++++++
 inetd.tproj/pathnames.h                       |   67 +
 ipfw.tproj/Makefile                           |   48 +
 ipfw.tproj/Makefile.postamble                 |  104 +
 ipfw.tproj/Makefile.preamble                  |  140 +
 ipfw.tproj/PB.project                         |   25 +
 ipfw.tproj/ipfw.8                             |  733 ++++
 ipfw.tproj/ipfw.c                             | 1613 +++++++++
 logger.tproj/Makefile                         |   49 +
 logger.tproj/Makefile.postamble               |  123 +
 logger.tproj/Makefile.preamble                |  130 +
 logger.tproj/PB.project                       |   34 +
 logger.tproj/h.template                       |   11 +
 logger.tproj/logger.1                         |  102 +
 logger.tproj/logger.c                         |  205 ++
 logger.tproj/m.template                       |   18 +
 makedbm.tproj/Makefile                        |   48 +
 makedbm.tproj/Makefile.postamble              |  101 +
 makedbm.tproj/Makefile.preamble               |  123 +
 makedbm.tproj/PB.project                      |   27 +
 makedbm.tproj/db.c                            |   98 +
 makedbm.tproj/db.h                            |   66 +
 makedbm.tproj/makedbm.8                       |   97 +
 makedbm.tproj/makedbm.c                       |  444 +++
 makedbm.tproj/ypdb.c                          |  297 ++
 makedbm.tproj/ypdb.h                          |  100 +
 makedbm.tproj/ypdef.h                         |   94 +
 natd.tproj/Makefile                           |   50 +
 natd.tproj/Makefile.postamble                 |  104 +
 natd.tproj/Makefile.preamble                  |  140 +
 natd.tproj/PB.project                         |   27 +
 natd.tproj/icmp.c                             |  126 +
 natd.tproj/natd.8                             |  426 +++
 natd.tproj/natd.c                             | 1578 +++++++++
 natd.tproj/natd.h                             |   24 +
 netstat.tproj/DERIVED_FILES                   |    1 +
 netstat.tproj/Makefile                        |   54 +
 netstat.tproj/Makefile.postamble              |    2 +
 netstat.tproj/Makefile.preamble               |    4 +
 netstat.tproj/PB.project                      |   49 +
 netstat.tproj/data.c                          |   28 +
 netstat.tproj/if.c                            |  511 +++
 netstat.tproj/inet.c                          |  616 ++++
 netstat.tproj/iso.c                           |  866 +++++
 netstat.tproj/main.c                          |  667 ++++
 netstat.tproj/mbuf.c                          |  155 +
 netstat.tproj/mroute.c                        |  210 ++
 netstat.tproj/netstat.1                       |  289 ++
 netstat.tproj/netstat.h                       |  149 +
 netstat.tproj/route.c                         |  918 +++++
 netstat.tproj/tp_astring.c                    |   74 +
 netstat.tproj/unix.c                          |  184 +
 newclient.tproj/Makefile                      |   36 +
 newclient.tproj/Makefile.preamble             |    1 +
 newclient.tproj/PB.project                    |   34 +
 newclient.tproj/newclient.csh                 |  233 ++
 nfsd.tproj/Makefile                           |   51 +
 nfsd.tproj/Makefile.dist                      |    9 +
 nfsd.tproj/Makefile.preamble                  |    2 +
 nfsd.tproj/PB.project                         |   32 +
 nfsd.tproj/nfsd.8                             |  115 +
 nfsd.tproj/nfsd.c                             |  657 ++++
 nfsiod.tproj/Makefile                         |   51 +
 nfsiod.tproj/Makefile.dist                    |    7 +
 nfsiod.tproj/Makefile.preamble                |    2 +
 nfsiod.tproj/PB.project                       |   32 +
 nfsiod.tproj/nfsiod.8                         |   74 +
 nfsiod.tproj/nfsiod.c                         |  184 +
 nfsstat.tproj/Makefile                        |   51 +
 nfsstat.tproj/Makefile.postamble              |    2 +
 nfsstat.tproj/Makefile.preamble               |    3 +
 nfsstat.tproj/PB.project                      |   31 +
 nfsstat.tproj/nfsstat.1                       |   88 +
 nfsstat.tproj/nfsstat.c                       |  445 +++
 pcap/Makefile                                 |   63 +
 pcap/Makefile.postamble                       |  122 +
 pcap/Makefile.preamble                        |  130 +
 pcap/PB.project                               |   48 +
 pcap/bpf_filter.c                             |  546 +++
 pcap/bpf_image.c                              |  315 ++
 pcap/etherent.c                               |  182 +
 pcap/ethertype.h                              |  100 +
 pcap/gencode.c                                | 1843 ++++++++++
 pcap/gencode.h                                |  196 ++
 pcap/grammar.y                                |  280 ++
 pcap/inet.c                                   |  249 ++
 pcap/nametoaddr.c                             |  394 +++
 pcap/optimize.c                               | 2029 +++++++++++
 pcap/pcap-bpf.c                               |  273 ++
 pcap/pcap-int.h                               |  129 +
 pcap/pcap-namedb.h                            |  101 +
 pcap/pcap.c                                   |  219 ++
 pcap/pcap.h                                   |  166 +
 pcap/savefile.c                               |  362 ++
 pcap/scanner.l                                |  198 ++
 ping.tproj/Makefile                           |   51 +
 ping.tproj/Makefile.dist                      |    8 +
 ping.tproj/Makefile.postamble                 |    1 +
 ping.tproj/Makefile.preamble                  |    2 +
 ping.tproj/PB.project                         |   31 +
 ping.tproj/ping.8                             |  328 ++
 ping.tproj/ping.c                             | 1018 ++++++
 portmap.tproj/Makefile                        |   48 +
 portmap.tproj/Makefile.postamble              |  110 +
 portmap.tproj/Makefile.preamble               |  113 +
 portmap.tproj/PB.project                      |   41 +
 portmap.tproj/portmap.8                       |  110 +
 portmap.tproj/portmap.c                       |  661 ++++
 rarpd.tproj/Makefile                          |   52 +
 rarpd.tproj/Makefile.dist                     |   10 +
 rarpd.tproj/Makefile.preamble                 |    2 +
 rarpd.tproj/PB.project                        |   37 +
 rarpd.tproj/rarpd.8                           |   92 +
 rarpd.tproj/rarpd.c                           |  831 +++++
 rbootd.tproj/Makefile                         |   50 +
 rbootd.tproj/Makefile.postamble               |  111 +
 rbootd.tproj/Makefile.preamble                |  119 +
 rbootd.tproj/PB.project                       |   39 +
 rbootd.tproj/bpf.c                            |  445 +++
 rbootd.tproj/conf.c                           |  113 +
 rbootd.tproj/defs.h                           |  208 ++
 rbootd.tproj/parseconf.c                      |  382 +++
 rbootd.tproj/pathnames.h                      |   74 +
 rbootd.tproj/rbootd.8                         |  156 +
 rbootd.tproj/rbootd.c                         |  531 +++
 rbootd.tproj/rmp.h                            |  118 +
 rbootd.tproj/rmp_var.h                        |  267 ++
 rbootd.tproj/rmpproto.c                       |  616 ++++
 rbootd.tproj/utils.c                          |  580 ++++
 rcp.tproj/Makefile                            |   51 +
 rcp.tproj/Makefile.dist                       |   13 +
 rcp.tproj/Makefile.postamble                  |    5 +
 rcp.tproj/Makefile.preamble                   |    5 +
 rcp.tproj/PB.project                          |   29 +
 rcp.tproj/extern.h                            |   73 +
 rcp.tproj/pathnames.h                         |   62 +
 rcp.tproj/rcp.1                               |  159 +
 rcp.tproj/rcp.c                               |  938 ++++++
 rcp.tproj/util.c                              |  187 ++
 revnetgroup.tproj/Makefile                    |   48 +
 revnetgroup.tproj/Makefile.postamble          |  101 +
 revnetgroup.tproj/Makefile.preamble           |  123 +
 revnetgroup.tproj/PB.project                  |   27 +
 revnetgroup.tproj/hash.c                      |  244 ++
 revnetgroup.tproj/hash.h                      |   91 +
 revnetgroup.tproj/parse_netgroup.c            |  394 +++
 revnetgroup.tproj/revnetgroup.8               |  138 +
 revnetgroup.tproj/revnetgroup.c               |  221 ++
 rexecd.tproj/Makefile                         |   48 +
 rexecd.tproj/Makefile.postamble               |  111 +
 rexecd.tproj/Makefile.preamble                |  119 +
 rexecd.tproj/PB.project                       |   42 +
 rexecd.tproj/rexecd.8                         |  149 +
 rexecd.tproj/rexecd.c                         |  285 ++
 rlogin.tproj/Makefile                         |   55 +
 rlogin.tproj/Makefile.postamble               |    1 +
 rlogin.tproj/Makefile.preamble                |    3 +
 rlogin.tproj/PB.project                       |   42 +
 rlogin.tproj/des_rw.c                         |  226 ++
 rlogin.tproj/kcmd.c                           |  329 ++
 rlogin.tproj/krb.h                            |   74 +
 rlogin.tproj/krcmd.c                          |  178 +
 rlogin.tproj/rlogin.1                         |  188 ++
 rlogin.tproj/rlogin.c                         | 1011 ++++++
 rlogind.tproj/Makefile                        |   55 +
 rlogind.tproj/Makefile.postamble              |    2 +
 rlogind.tproj/Makefile.preamble               |    3 +
 rlogind.tproj/PB.project                      |   41 +
 rlogind.tproj/pathnames.h                     |   61 +
 rlogind.tproj/rlogind.8                       |  168 +
 rlogind.tproj/rlogind.c                       |  783 +++++
 route.tproj/Makefile                          |   53 +
 route.tproj/Makefile.dist                     |   25 +
 route.tproj/Makefile.postamble                |    1 +
 route.tproj/Makefile.preamble                 |    2 +
 route.tproj/PB.project                        |   43 +
 route.tproj/ccitt_addr.c                      |  199 ++
 route.tproj/keywords.h                        |  109 +
 route.tproj/route.8                           |  325 ++
 route.tproj/route.c                           | 1523 +++++++++
 routed.tproj/Makefile                         |   51 +
 routed.tproj/Makefile.dist                    |   22 +
 routed.tproj/Makefile.preamble                |    2 +
 routed.tproj/PB.project                       |   53 +
 routed.tproj/af.c                             |  193 ++
 routed.tproj/af.h                             |   88 +
 routed.tproj/defs.c                           |   26 +
 routed.tproj/defs.h                           |  131 +
 routed.tproj/if.c                             |  170 +
 routed.tproj/inet.c                           |  267 ++
 routed.tproj/input.c                          |  383 +++
 routed.tproj/interface.h                      |  113 +
 routed.tproj/main.c                           |  367 ++
 routed.tproj/output.c                         |  194 ++
 routed.tproj/pathnames.h                      |   61 +
 routed.tproj/routed.8                         |  358 ++
 routed.tproj/startup.c                        |  537 +++
 routed.tproj/table.h                          |  131 +
 routed.tproj/tables.c                         |  450 +++
 routed.tproj/timer.c                          |  149 +
 routed.tproj/trace.c                          |  448 +++
 routed.tproj/trace.h                          |  119 +
 rpc_yppasswdd.tproj/Makefile                  |   49 +
 rpc_yppasswdd.tproj/Makefile.postamble        |  101 +
 rpc_yppasswdd.tproj/Makefile.preamble         |  123 +
 rpc_yppasswdd.tproj/PB.project                |   27 +
 rpc_yppasswdd.tproj/passwd.c                  |  461 +++
 rpc_yppasswdd.tproj/rpc.yppasswdd.8           |   97 +
 rpc_yppasswdd.tproj/rpc.yppasswdd.c           |  208 ++
 rpc_yppasswdd.tproj/yppasswd.h                |  113 +
 rpc_yppasswdd.tproj/yppasswdd_mkpw.c          |  321 ++
 rpc_yppasswdd.tproj/yppasswdd_proc.c          |   89 +
 rpcinfo.tproj/Makefile                        |   49 +
 rpcinfo.tproj/Makefile.postamble              |  111 +
 rpcinfo.tproj/Makefile.preamble               |  119 +
 rpcinfo.tproj/PB.project                      |   45 +
 rpcinfo.tproj/h.template                      |    9 +
 rpcinfo.tproj/m.template                      |   18 +
 rpcinfo.tproj/rpcinfo.c                       |  690 ++++
 rsh.tproj/Makefile                            |   50 +
 rsh.tproj/Makefile.postamble                  |    5 +
 rsh.tproj/Makefile.preamble                   |    4 +
 rsh.tproj/PB.project                          |   30 +
 rsh.tproj/pathnames.h                         |   59 +
 rsh.tproj/rsh.1                               |  187 ++
 rsh.tproj/rsh.c                               |  504 +++
 rshd.tproj/Makefile                           |   48 +
 rshd.tproj/Makefile.postamble                 |  113 +
 rshd.tproj/Makefile.preamble                  |  119 +
 rshd.tproj/PB.project                         |   42 +
 rshd.tproj/rshd.8                             |  209 ++
 rshd.tproj/rshd.c                             |  809 +++++
 ruptime.tproj/Makefile                        |   49 +
 ruptime.tproj/Makefile.dist                   |    5 +
 ruptime.tproj/Makefile.postamble              |  123 +
 ruptime.tproj/Makefile.preamble               |  130 +
 ruptime.tproj/PB.project                      |   35 +
 ruptime.tproj/h.template                      |   11 +
 ruptime.tproj/m.template                      |   18 +
 ruptime.tproj/ruptime.1                       |   81 +
 ruptime.tproj/ruptime.c                       |  301 ++
 rwho.tproj/Makefile                           |   49 +
 rwho.tproj/Makefile.dist                      |    5 +
 rwho.tproj/Makefile.postamble                 |  123 +
 rwho.tproj/Makefile.preamble                  |  130 +
 rwho.tproj/PB.project                         |   27 +
 rwho.tproj/rwho.1                             |   80 +
 rwho.tproj/rwho.c                             |  204 ++
 rwhod.tproj/Makefile                          |   48 +
 rwhod.tproj/Makefile.postamble                |  110 +
 rwhod.tproj/Makefile.preamble                 |  113 +
 rwhod.tproj/PB.project                        |   41 +
 rwhod.tproj/rwhod.8                           |  146 +
 rwhod.tproj/rwhod.c                           |  562 ++++
 slattach.tproj/Makefile                       |   48 +
 slattach.tproj/Makefile.dist                  |    7 +
 slattach.tproj/Makefile.preamble              |    2 +
 slattach.tproj/PB.project                     |   32 +
 slattach.tproj/slattach.8                     |   90 +
 slattach.tproj/slattach.c                     |  188 ++
 sliplogin.tproj/Makefile                      |   51 +
 sliplogin.tproj/Makefile.postamble            |  110 +
 sliplogin.tproj/Makefile.preamble             |  113 +
 sliplogin.tproj/PB.project                    |   48 +
 sliplogin.tproj/pathnames.h                   |   69 +
 sliplogin.tproj/slip.hosts                    |   11 +
 sliplogin.tproj/slip.login                    |   12 +
 sliplogin.tproj/sliplogin.8                   |  220 ++
 sliplogin.tproj/sliplogin.c                   |  404 +++
 spray.tproj/Makefile                          |   49 +
 spray.tproj/Makefile.dist                     |    7 +
 spray.tproj/Makefile.postamble                |  126 +
 spray.tproj/Makefile.preamble                 |    4 +
 spray.tproj/PB.project                        |   37 +
 spray.tproj/spray.c                           |  247 ++
 spray.tproj/spray.x                           |   24 +
 startslip.tproj/Makefile                      |   48 +
 startslip.tproj/Makefile.dist                 |    6 +
 startslip.tproj/Makefile.preamble             |    2 +
 startslip.tproj/PB.project                    |   32 +
 startslip.tproj/startslip.1                   |  105 +
 startslip.tproj/startslip.c                   |  466 +++
 stdethers.tproj/Makefile                      |   46 +
 stdethers.tproj/Makefile.postamble            |  101 +
 stdethers.tproj/Makefile.preamble             |  123 +
 stdethers.tproj/PB.project                    |   27 +
 stdethers.tproj/stdethers.8                   |   55 +
 stdethers.tproj/stdethers.c                   |  220 ++
 stdhosts.tproj/Makefile                       |   46 +
 stdhosts.tproj/Makefile.postamble             |  101 +
 stdhosts.tproj/Makefile.preamble              |  123 +
 stdhosts.tproj/PB.project                     |   26 +
 stdhosts.tproj/stdhosts.8                     |   55 +
 stdhosts.tproj/stdhosts.c                     |  172 +
 syslogd.tproj/Makefile                        |   51 +
 syslogd.tproj/Makefile.postamble              |  111 +
 syslogd.tproj/Makefile.preamble               |  115 +
 syslogd.tproj/PB.project                      |   41 +
 syslogd.tproj/pathnames.h                     |   63 +
 syslogd.tproj/syslog.conf.5                   |  224 ++
 syslogd.tproj/syslogd.8                       |  122 +
 syslogd.tproj/syslogd.c                       | 1162 +++++++
 talk.tproj/Makefile                           |   51 +
 talk.tproj/Makefile.preamble                  |    3 +
 talk.tproj/PB.project                         |   37 +
 talk.tproj/ctl.c                              |  133 +
 talk.tproj/ctl_transact.c                     |  133 +
 talk.tproj/display.c                          |  210 ++
 talk.tproj/get_addrs.c                        |  103 +
 talk.tproj/get_names.c                        |  138 +
 talk.tproj/init_disp.c                        |  169 +
 talk.tproj/invite.c                           |  208 ++
 talk.tproj/io.c                               |  162 +
 talk.tproj/look_up.c                          |  135 +
 talk.tproj/msgs.c                             |   98 +
 talk.tproj/talk.1                             |  129 +
 talk.tproj/talk.c                             |   94 +
 talk.tproj/talk.h                             |   81 +
 talk.tproj/talk_ctl.h                         |   66 +
 talkd.tproj/Makefile                          |   51 +
 talkd.tproj/Makefile.dist                     |    8 +
 talkd.tproj/Makefile.postamble                |  113 +
 talkd.tproj/Makefile.preamble                 |  120 +
 talkd.tproj/PB.project                        |   39 +
 talkd.tproj/announce.c                        |  191 ++
 talkd.tproj/print.c                           |  111 +
 talkd.tproj/process.c                         |  246 ++
 talkd.tproj/table.c                           |  263 ++
 talkd.tproj/talkd.8                           |   75 +
 talkd.tproj/talkd.c                           |  153 +
 talkd.tproj/talkd.h                           |   32 +
 tcpdump.tproj/Makefile                        |   63 +
 tcpdump.tproj/Makefile.postamble              |  123 +
 tcpdump.tproj/Makefile.preamble               |  130 +
 tcpdump.tproj/PB.project                      |   98 +
 tcpdump.tproj/addrtoname.c                    |  779 +++++
 tcpdump.tproj/addrtoname.h                    |   59 +
 tcpdump.tproj/appletalk.h                     |  190 ++
 tcpdump.tproj/bootp.h                         |  132 +
 tcpdump.tproj/bpf_dump.c                      |   88 +
 tcpdump.tproj/decnet.h                        |  476 +++
 tcpdump.tproj/ethertype.h                     |   99 +
 tcpdump.tproj/extract.h                       |   80 +
 tcpdump.tproj/fddi.h                          |   92 +
 tcpdump.tproj/gnuc.h                          |   66 +
 tcpdump.tproj/igrp.h                          |   59 +
 tcpdump.tproj/interface.h                     |  230 ++
 tcpdump.tproj/ipx.h                           |   52 +
 tcpdump.tproj/llc.h                           |  143 +
 tcpdump.tproj/machdep.c                       |   72 +
 tcpdump.tproj/machdep.h                       |   50 +
 tcpdump.tproj/mib.h                           | 1279 +++++++
 tcpdump.tproj/netbios.h                       |   39 +
 tcpdump.tproj/nfs.h                           |  470 +++
 tcpdump.tproj/nfsfh.h                         |   57 +
 tcpdump.tproj/nfsv2.h                         |  285 ++
 tcpdump.tproj/ntp.h                           |  140 +
 tcpdump.tproj/os-solaris2.h                   |   77 +
 tcpdump.tproj/os-sunos4.h                     |  238 ++
 tcpdump.tproj/os-ultrix4.h                    |   62 +
 tcpdump.tproj/ospf.h                          |  246 ++
 tcpdump.tproj/parsenfsfh.c                    |  443 +++
 tcpdump.tproj/print-arp.c                     |  153 +
 tcpdump.tproj/print-atalk.c                   |  595 ++++
 tcpdump.tproj/print-atm.c                     |  171 +
 tcpdump.tproj/print-bootp.c                   |  371 ++
 tcpdump.tproj/print-decnet.c                  |  798 +++++
 tcpdump.tproj/print-domain.c                  |  423 +++
 tcpdump.tproj/print-dvmrp.c                   |  383 +++
 tcpdump.tproj/print-egp.c                     |  377 +++
 tcpdump.tproj/print-ether.c                   |  219 ++
 tcpdump.tproj/print-fddi.c                    |  377 +++
 tcpdump.tproj/print-gre.c                     |  164 +
 tcpdump.tproj/print-icmp.c                    |  377 +++
 tcpdump.tproj/print-igrp.c                    |  161 +
 tcpdump.tproj/print-ip.c                      |  547 +++
 tcpdump.tproj/print-ipx.c                     |  238 ++
 tcpdump.tproj/print-isoclns.c                 |  340 ++
 tcpdump.tproj/print-krb.c                     |  317 ++
 tcpdump.tproj/print-llc.c                     |  216 ++
 tcpdump.tproj/print-netbios.c                 |  122 +
 tcpdump.tproj/print-nfs.c                     |  891 +++++
 tcpdump.tproj/print-ntp.c                     |  307 ++
 tcpdump.tproj/print-null.c                    |  142 +
 tcpdump.tproj/print-ospf.c                    |  603 ++++
 tcpdump.tproj/print-pim.c                     |  123 +
 tcpdump.tproj/print-ppp.c                     |  128 +
 tcpdump.tproj/print-rip.c                     |  182 +
 tcpdump.tproj/print-skip.c                    |  943 ++++++
 tcpdump.tproj/print-sl.c                      |  280 ++
 tcpdump.tproj/print-snmp.c                    | 1063 ++++++
 tcpdump.tproj/print-sunrpc.c                  |  155 +
 tcpdump.tproj/print-tcp.c                     |  383 +++
 tcpdump.tproj/print-tftp.c                    |  162 +
 tcpdump.tproj/print-udp.c                     |  464 +++
 tcpdump.tproj/print-wb.c                      |  456 +++
 tcpdump.tproj/strcasecmp.c                    |  112 +
 tcpdump.tproj/tcpdump.c                       |  451 +++
 tcpdump.tproj/util.c                          |  352 ++
 tcpdump.tproj/version.c                       |   27 +
 tcpdump.tproj/vfprintf.c                      |   85 +
 telnet.tproj/Makefile                         |   57 +
 telnet.tproj/Makefile.dist                    |   73 +
 telnet.tproj/Makefile.preamble                |    4 +
 telnet.tproj/PB.project                       |   47 +
 telnet.tproj/README                           |  743 ++++
 telnet.tproj/authenc.c                        |  134 +
 telnet.tproj/commands.c                       | 2990 +++++++++++++++++
 telnet.tproj/defines.h                        |   84 +
 telnet.tproj/externs.h                        |  505 +++
 telnet.tproj/fdset.h                          |   72 +
 telnet.tproj/general.h                        |   68 +
 telnet.tproj/krb4-proto.h                     |  230 ++
 telnet.tproj/main.c                           |  345 ++
 telnet.tproj/network.c                        |  200 ++
 telnet.tproj/ring.c                           |  385 +++
 telnet.tproj/ring.h                           |  128 +
 telnet.tproj/sys_bsd.c                        | 1243 +++++++
 telnet.tproj/telnet.1                         | 1366 ++++++++
 telnet.tproj/telnet.c                         | 2673 +++++++++++++++
 telnet.tproj/terminal.c                       |  263 ++
 telnet.tproj/tn3270.c                         |  434 +++
 telnet.tproj/types.h                          |   75 +
 telnet.tproj/utilities.c                      |  962 ++++++
 telnetd.tproj/Makefile                        |   56 +
 telnetd.tproj/Makefile.postamble              |  111 +
 telnetd.tproj/Makefile.preamble               |  119 +
 telnetd.tproj/PB.project                      |   50 +
 telnetd.tproj/authenc.c                       |  114 +
 telnetd.tproj/defs.h                          |  323 ++
 telnetd.tproj/ext.h                           |  267 ++
 telnetd.tproj/global.c                        |   71 +
 telnetd.tproj/pathnames.h                     |   78 +
 telnetd.tproj/slc.c                           |  514 +++
 telnetd.tproj/state.c                         | 1635 +++++++++
 telnetd.tproj/sys_term.c                      | 2306 +++++++++++++
 telnetd.tproj/telnetd.8                       |  607 ++++
 telnetd.tproj/telnetd.c                       | 1640 +++++++++
 telnetd.tproj/telnetd.h                       |   73 +
 telnetd.tproj/termstat.c                      |  683 ++++
 telnetd.tproj/utility.c                       | 1215 +++++++
 tftp.tproj/Makefile                           |   52 +
 tftp.tproj/Makefile.preamble                  |    3 +
 tftp.tproj/PB.project                         |   27 +
 tftp.tproj/extern.h                           |   60 +
 tftp.tproj/main.c                             |  753 +++++
 tftp.tproj/tftp.1                             |  173 +
 tftp.tproj/tftp.c                             |  474 +++
 tftp.tproj/tftpsubs.c                         |  293 ++
 tftp.tproj/tftpsubs.h                         |   71 +
 tftpd.tproj/Makefile                          |   51 +
 tftpd.tproj/Makefile.postamble                |  112 +
 tftpd.tproj/Makefile.preamble                 |  121 +
 tftpd.tproj/PB.project                        |   41 +
 tftpd.tproj/tftpd.8                           |  106 +
 tftpd.tproj/tftpd.c                           |  673 ++++
 timed.tproj/Makefile                          |   44 +
 timed.tproj/Makefile.postamble                |  109 +
 timed.tproj/Makefile.preamble                 |  121 +
 timed.tproj/PB.project                        |   21 +
 timed.tproj/timed.tproj/Makefile              |   49 +
 timed.tproj/timed.tproj/Makefile.postamble    |  122 +
 timed.tproj/timed.tproj/Makefile.preamble     |  130 +
 timed.tproj/timed.tproj/PB.project            |   38 +
 timed.tproj/timed.tproj/acksend.c             |  155 +
 timed.tproj/timed.tproj/byteorder.c           |  109 +
 timed.tproj/timed.tproj/candidate.c           |  190 ++
 timed.tproj/timed.tproj/cksum.c               |  110 +
 timed.tproj/timed.tproj/correct.c             |  317 ++
 timed.tproj/timed.tproj/extern.h              |  112 +
 timed.tproj/timed.tproj/globals.h             |  209 ++
 timed.tproj/timed.tproj/master.c              |  930 +++++
 timed.tproj/timed.tproj/measure.c             |  376 +++
 timed.tproj/timed.tproj/networkdelta.c        |  297 ++
 timed.tproj/timed.tproj/pathnames.h           |   67 +
 timed.tproj/timed.tproj/readmsg.c             |  511 +++
 timed.tproj/timed.tproj/slave.c               |  738 ++++
 timed.tproj/timed.tproj/timed.8               |  219 ++
 timed.tproj/timed.tproj/timed.c               | 1006 ++++++
 timed.tproj/timedc.tproj/Makefile             |   51 +
 timed.tproj/timedc.tproj/Makefile.postamble   |  123 +
 timed.tproj/timedc.tproj/Makefile.preamble    |  130 +
 timed.tproj/timedc.tproj/PB.project           |   27 +
 timed.tproj/timedc.tproj/cmds.c               |  549 +++
 timed.tproj/timedc.tproj/cmdtab.c             |   80 +
 timed.tproj/timedc.tproj/extern.h             |   75 +
 timed.tproj/timedc.tproj/h.template           |   11 +
 timed.tproj/timedc.tproj/m.template           |   18 +
 timed.tproj/timedc.tproj/timedc.c             |  284 ++
 timed.tproj/timedc.tproj/timedc.h             |   89 +
 traceroute.tproj/Makefile                     |   49 +
 traceroute.tproj/Makefile.postamble           |  110 +
 traceroute.tproj/Makefile.preamble            |  113 +
 traceroute.tproj/PB.project                   |   49 +
 traceroute.tproj/README                       |  126 +
 traceroute.tproj/mean.awk                     |   50 +
 traceroute.tproj/median.awk                   |   67 +
 traceroute.tproj/traceroute.8                 |  337 ++
 traceroute.tproj/traceroute.c                 |  858 +++++
 trpt.tproj/Makefile                           |   48 +
 trpt.tproj/Makefile.postamble                 |  110 +
 trpt.tproj/Makefile.preamble                  |  113 +
 trpt.tproj/PB.project                         |   41 +
 trpt.tproj/trpt.8                             |  151 +
 trpt.tproj/trpt.c                             |  440 +++
 trsp.tproj/Makefile                           |   48 +
 trsp.tproj/Makefile.postamble                 |  110 +
 trsp.tproj/Makefile.preamble                  |  113 +
 trsp.tproj/PB.project                         |   41 +
 trsp.tproj/trsp.8                             |  141 +
 trsp.tproj/trsp.c                             |  458 +++
 uucpd.tproj/Makefile                          |   50 +
 uucpd.tproj/Makefile.postamble                |  111 +
 uucpd.tproj/Makefile.preamble                 |  119 +
 uucpd.tproj/PB.project                        |   42 +
 uucpd.tproj/pathnames.h                       |   61 +
 uucpd.tproj/uucpd.c                           |  323 ++
 wall.tproj/Makefile                           |   49 +
 wall.tproj/Makefile.dist                      |    8 +
 wall.tproj/Makefile.postamble                 |  123 +
 wall.tproj/Makefile.preamble                  |  130 +
 wall.tproj/PB.project                         |   27 +
 wall.tproj/ttymsg.c                           |  183 +
 wall.tproj/wall.1                             |   63 +
 wall.tproj/wall.c                             |  221 ++
 ypbind.tproj/Makefile                         |   49 +
 ypbind.tproj/Makefile.dist                    |    8 +
 ypbind.tproj/Makefile.postamble               |  108 +
 ypbind.tproj/Makefile.preamble                |  129 +
 ypbind.tproj/PB.project                       |   36 +
 ypbind.tproj/yp.x                             |   24 +
 ypbind.tproj/ypbind.c                         | 1289 +++++++
 ypcat.tproj/Makefile                          |   48 +
 ypcat.tproj/Makefile.dist                     |    6 +
 ypcat.tproj/Makefile.preamble                 |    2 +
 ypcat.tproj/PB.project                        |   36 +
 ypcat.tproj/ypcat.1                           |   70 +
 ypcat.tproj/ypcat.c                           |  169 +
 ypinit.tproj/Makefile                         |   46 +
 ypinit.tproj/Makefile.main                    |    6 +
 ypinit.tproj/Makefile.yp                      |  327 ++
 ypinit.tproj/ypinit.sh                        |  402 +++
 ypmatch.tproj/Makefile                        |   48 +
 ypmatch.tproj/Makefile.dist                   |    6 +
 ypmatch.tproj/Makefile.preamble               |    2 +
 ypmatch.tproj/PB.project                      |   36 +
 ypmatch.tproj/ypmatch.1                       |   71 +
 ypmatch.tproj/ypmatch.c                       |  160 +
 yppoll.tproj/Makefile                         |   48 +
 yppoll.tproj/Makefile.dist                    |    7 +
 yppoll.tproj/Makefile.preamble                |    2 +
 yppoll.tproj/PB.project                       |   36 +
 yppoll.tproj/yppoll.8                         |   63 +
 yppoll.tproj/yppoll.c                         |  210 ++
 yppush.tproj/Makefile                         |   49 +
 yppush.tproj/Makefile.postamble               |  101 +
 yppush.tproj/Makefile.preamble                |  123 +
 yppush.tproj/PB.project                       |   35 +
 yppush.tproj/ypdb.c                           |  297 ++
 yppush.tproj/ypdb.h                           |  100 +
 yppush.tproj/ypdef.h                          |   94 +
 yppush.tproj/yplib_host.c                     |  427 +++
 yppush.tproj/yplib_host.h                     |   82 +
 yppush.tproj/yppush.8                         |   68 +
 yppush.tproj/yppush.c                         |  382 +++
 yppush.tproj/yppush.h                         |  133 +
 yppush.tproj/yppush_err.c                     |  100 +
 yppush.tproj/yppush_proc.c                    |   96 +
 yppush.tproj/yppush_svc.c                     |  155 +
 yppush.tproj/yppush_xdr.c                     |  171 +
 ypserv.tproj/Makefile                         |   52 +
 ypserv.tproj/Makefile.postamble               |  101 +
 ypserv.tproj/Makefile.preamble                |  123 +
 ypserv.tproj/PB.project                       |   45 +
 ypserv.tproj/acl.c                            |  641 ++++
 ypserv.tproj/acl.h                            |  110 +
 ypserv.tproj/securenet                        |    4 +
 ypserv.tproj/securenet.5                      |   74 +
 ypserv.tproj/yp.h                             |  612 ++++
 ypserv.tproj/ypdb.c                           |  297 ++
 ypserv.tproj/ypdb.h                           |  100 +
 ypserv.tproj/ypdef.h                          |   94 +
 ypserv.tproj/yplog.c                          |  149 +
 ypserv.tproj/yplog.h                          |   65 +
 ypserv.tproj/ypserv.acl                       |   44 +
 ypserv.tproj/ypserv.acl.5                     |  182 +
 ypserv.tproj/ypserv.c                         |  559 +++
 ypserv.tproj/ypserv_db.c                      |  811 +++++
 ypserv.tproj/ypserv_proc.c                    | 1061 ++++++
 ypserv.tproj/ypserv_xdr.c                     |  489 +++
 ypserv.tproj/ypserv_xdr_v1.c                  |  130 +
 ypserv.tproj/ypv1.h                           |  264 ++
 ypset.tproj/Makefile                          |   48 +
 ypset.tproj/Makefile.dist                     |    7 +
 ypset.tproj/Makefile.preamble                 |    2 +
 ypset.tproj/PB.project                        |   36 +
 ypset.tproj/ypset.c                           |  187 ++
 ypwhich.tproj/Makefile                        |   48 +
 ypwhich.tproj/Makefile.dist                   |    6 +
 ypwhich.tproj/Makefile.preamble               |    2 +
 ypwhich.tproj/PB.project                      |   36 +
 ypwhich.tproj/ypwhich.1                       |   94 +
 ypwhich.tproj/ypwhich.c                       |  311 ++
 ypxfr.tproj/Makefile                          |   49 +
 ypxfr.tproj/Makefile.postamble                |  101 +
 ypxfr.tproj/Makefile.preamble                 |  123 +
 ypxfr.tproj/PB.project                        |   36 +
 ypxfr.tproj/ypdb.c                            |  297 ++
 ypxfr.tproj/ypdb.h                            |  100 +
 ypxfr.tproj/ypdef.h                           |   94 +
 ypxfr.tproj/yplib_host.c                      |  427 +++
 ypxfr.tproj/yplib_host.h                      |   82 +
 ypxfr.tproj/yplog.c                           |  149 +
 ypxfr.tproj/yplog.h                           |   65 +
 ypxfr.tproj/ypxfr.8                           |   92 +
 ypxfr.tproj/ypxfr.c                           |  668 ++++
 ypxfr.tproj/ypxfr_1perday.sh                  |   15 +
 ypxfr.tproj/ypxfr_1perhour.sh                 |   11 +
 ypxfr.tproj/ypxfr_2perday.sh                  |   10 +
 ypxfr.tproj/ypxfr_xdr.c                       |  115 +
 729 files changed, 160182 insertions(+)
 create mode 100644 Makefile
 create mode 100644 Makefile.include
 create mode 100644 Makefile.preamble
 create mode 100644 PB.project
 create mode 100644 alias/Makefile
 create mode 100644 alias/Makefile.postamble
 create mode 100644 alias/Makefile.preamble
 create mode 100644 alias/PB.project
 create mode 100644 alias/alias.c
 create mode 100644 alias/alias.h
 create mode 100644 alias/alias_cuseeme.c
 create mode 100644 alias/alias_db.c
 create mode 100644 alias/alias_ftp.c
 create mode 100644 alias/alias_irc.c
 create mode 100644 alias/alias_local.h
 create mode 100644 alias/alias_nbt.c
 create mode 100644 alias/alias_proxy.c
 create mode 100644 alias/alias_util.c
 create mode 100644 arp.tproj/Makefile
 create mode 100644 arp.tproj/Makefile.postamble
 create mode 100644 arp.tproj/Makefile.preamble
 create mode 100644 arp.tproj/PB.project
 create mode 100644 arp.tproj/arp.8
 create mode 100644 arp.tproj/arp.c
 create mode 100644 arp.tproj/arp4.4
 create mode 100644 bootparams/Makefile
 create mode 100644 bootparams/Makefile.postamble
 create mode 100644 bootparams/Makefile.preamble
 create mode 100644 bootparams/PB.project
 create mode 100644 bootparams/bootparamd.tproj/Makefile
 create mode 100644 bootparams/bootparamd.tproj/Makefile.postamble
 create mode 100644 bootparams/bootparamd.tproj/Makefile.preamble
 create mode 100644 bootparams/bootparamd.tproj/PB.project
 create mode 100644 bootparams/bootparamd.tproj/bootparam_proc.c
 create mode 100644 bootparams/bootparamd.tproj/bootparamd.c
 create mode 100644 bootparams/bootparams/Makefile
 create mode 100644 bootparams/bootparams/Makefile.postamble
 create mode 100644 bootparams/bootparams/Makefile.preamble
 create mode 100644 bootparams/bootparams/PB.project
 create mode 100644 bootparams/bootparams/bootparam_prot.x
 create mode 100644 bootparams/bpwhoami.tproj/Makefile
 create mode 100644 bootparams/bpwhoami.tproj/Makefile.postamble
 create mode 100644 bootparams/bpwhoami.tproj/Makefile.preamble
 create mode 100644 bootparams/bpwhoami.tproj/PB.project
 create mode 100644 bootparams/bpwhoami.tproj/bpwhoami.c
 create mode 100644 domainname.tproj/Makefile
 create mode 100644 domainname.tproj/Makefile.dist
 create mode 100644 domainname.tproj/PB.project
 create mode 100644 domainname.tproj/domainname.1
 create mode 100644 domainname.tproj/domainname.c
 create mode 100644 ftp.tproj/Makefile
 create mode 100644 ftp.tproj/Makefile.postamble
 create mode 100644 ftp.tproj/Makefile.preamble
 create mode 100644 ftp.tproj/PB.project
 create mode 100644 ftp.tproj/cmds.c
 create mode 100644 ftp.tproj/cmdtab.c
 create mode 100644 ftp.tproj/domacro.c
 create mode 100644 ftp.tproj/extern.h
 create mode 100644 ftp.tproj/ftp.1
 create mode 100644 ftp.tproj/ftp.c
 create mode 100644 ftp.tproj/ftp_var.c
 create mode 100644 ftp.tproj/ftp_var.h
 create mode 100644 ftp.tproj/h.template
 create mode 100644 ftp.tproj/m.template
 create mode 100644 ftp.tproj/main.c
 create mode 100644 ftp.tproj/pathnames.h
 create mode 100644 ftp.tproj/ruserpass.c
 create mode 100644 ftpd.tproj/Makefile
 create mode 100644 ftpd.tproj/Makefile.postamble
 create mode 100644 ftpd.tproj/Makefile.preamble
 create mode 100644 ftpd.tproj/PB.project
 create mode 100644 ftpd.tproj/extern.h
 create mode 100644 ftpd.tproj/ftpcmd.y
 create mode 100644 ftpd.tproj/ftpd.8
 create mode 100644 ftpd.tproj/ftpd.c
 create mode 100644 ftpd.tproj/logwtmp.c
 create mode 100644 ftpd.tproj/pathnames.h
 create mode 100644 ftpd.tproj/popen.c
 create mode 100644 ftpd.tproj/vers.c
 create mode 100644 identd.tproj/CREDITS
 create mode 100644 identd.tproj/Makefile
 create mode 100644 identd.tproj/Makefile.dist
 create mode 100644 identd.tproj/Makefile.preamble
 create mode 100644 identd.tproj/PB.project
 create mode 100644 identd.tproj/README
 create mode 100644 identd.tproj/config.c
 create mode 100644 identd.tproj/error.h
 create mode 100644 identd.tproj/identd.8
 create mode 100644 identd.tproj/identd.c
 create mode 100644 identd.tproj/identd.h
 create mode 100644 identd.tproj/netbsd.c
 create mode 100644 identd.tproj/parse.c
 create mode 100644 identd.tproj/proxy.c
 create mode 100644 identd.tproj/version.c
 create mode 100644 identd.tproj/xpaths.h
 create mode 100644 ifconfig.tproj/Makefile
 create mode 100644 ifconfig.tproj/Makefile.dist
 create mode 100644 ifconfig.tproj/Makefile.postamble
 create mode 100644 ifconfig.tproj/Makefile.preamble
 create mode 100644 ifconfig.tproj/PB.project
 create mode 100644 ifconfig.tproj/ifconfig.8
 create mode 100644 ifconfig.tproj/ifconfig.c
 create mode 100644 ifconfig.tproj/ifconfig.h
 create mode 100644 ifconfig.tproj/ifmedia.c
 create mode 100644 inetd.tproj/Makefile
 create mode 100644 inetd.tproj/Makefile.postamble
 create mode 100644 inetd.tproj/Makefile.preamble
 create mode 100644 inetd.tproj/PB.project
 create mode 100644 inetd.tproj/inetd.8
 create mode 100644 inetd.tproj/inetd.c
 create mode 100644 inetd.tproj/pathnames.h
 create mode 100644 ipfw.tproj/Makefile
 create mode 100644 ipfw.tproj/Makefile.postamble
 create mode 100644 ipfw.tproj/Makefile.preamble
 create mode 100644 ipfw.tproj/PB.project
 create mode 100644 ipfw.tproj/ipfw.8
 create mode 100644 ipfw.tproj/ipfw.c
 create mode 100644 logger.tproj/Makefile
 create mode 100644 logger.tproj/Makefile.postamble
 create mode 100644 logger.tproj/Makefile.preamble
 create mode 100644 logger.tproj/PB.project
 create mode 100644 logger.tproj/h.template
 create mode 100644 logger.tproj/logger.1
 create mode 100644 logger.tproj/logger.c
 create mode 100644 logger.tproj/m.template
 create mode 100644 makedbm.tproj/Makefile
 create mode 100644 makedbm.tproj/Makefile.postamble
 create mode 100644 makedbm.tproj/Makefile.preamble
 create mode 100644 makedbm.tproj/PB.project
 create mode 100644 makedbm.tproj/db.c
 create mode 100644 makedbm.tproj/db.h
 create mode 100644 makedbm.tproj/makedbm.8
 create mode 100644 makedbm.tproj/makedbm.c
 create mode 100644 makedbm.tproj/ypdb.c
 create mode 100644 makedbm.tproj/ypdb.h
 create mode 100644 makedbm.tproj/ypdef.h
 create mode 100644 natd.tproj/Makefile
 create mode 100644 natd.tproj/Makefile.postamble
 create mode 100644 natd.tproj/Makefile.preamble
 create mode 100644 natd.tproj/PB.project
 create mode 100644 natd.tproj/icmp.c
 create mode 100644 natd.tproj/natd.8
 create mode 100644 natd.tproj/natd.c
 create mode 100644 natd.tproj/natd.h
 create mode 100644 netstat.tproj/DERIVED_FILES
 create mode 100644 netstat.tproj/Makefile
 create mode 100644 netstat.tproj/Makefile.postamble
 create mode 100644 netstat.tproj/Makefile.preamble
 create mode 100644 netstat.tproj/PB.project
 create mode 100644 netstat.tproj/data.c
 create mode 100644 netstat.tproj/if.c
 create mode 100644 netstat.tproj/inet.c
 create mode 100644 netstat.tproj/iso.c
 create mode 100644 netstat.tproj/main.c
 create mode 100644 netstat.tproj/mbuf.c
 create mode 100644 netstat.tproj/mroute.c
 create mode 100644 netstat.tproj/netstat.1
 create mode 100644 netstat.tproj/netstat.h
 create mode 100644 netstat.tproj/route.c
 create mode 100644 netstat.tproj/tp_astring.c
 create mode 100644 netstat.tproj/unix.c
 create mode 100644 newclient.tproj/Makefile
 create mode 100644 newclient.tproj/Makefile.preamble
 create mode 100644 newclient.tproj/PB.project
 create mode 100644 newclient.tproj/newclient.csh
 create mode 100644 nfsd.tproj/Makefile
 create mode 100644 nfsd.tproj/Makefile.dist
 create mode 100644 nfsd.tproj/Makefile.preamble
 create mode 100644 nfsd.tproj/PB.project
 create mode 100644 nfsd.tproj/nfsd.8
 create mode 100644 nfsd.tproj/nfsd.c
 create mode 100644 nfsiod.tproj/Makefile
 create mode 100644 nfsiod.tproj/Makefile.dist
 create mode 100644 nfsiod.tproj/Makefile.preamble
 create mode 100644 nfsiod.tproj/PB.project
 create mode 100644 nfsiod.tproj/nfsiod.8
 create mode 100644 nfsiod.tproj/nfsiod.c
 create mode 100644 nfsstat.tproj/Makefile
 create mode 100644 nfsstat.tproj/Makefile.postamble
 create mode 100644 nfsstat.tproj/Makefile.preamble
 create mode 100644 nfsstat.tproj/PB.project
 create mode 100644 nfsstat.tproj/nfsstat.1
 create mode 100644 nfsstat.tproj/nfsstat.c
 create mode 100644 pcap/Makefile
 create mode 100644 pcap/Makefile.postamble
 create mode 100644 pcap/Makefile.preamble
 create mode 100644 pcap/PB.project
 create mode 100644 pcap/bpf_filter.c
 create mode 100644 pcap/bpf_image.c
 create mode 100644 pcap/etherent.c
 create mode 100644 pcap/ethertype.h
 create mode 100644 pcap/gencode.c
 create mode 100644 pcap/gencode.h
 create mode 100644 pcap/grammar.y
 create mode 100644 pcap/inet.c
 create mode 100644 pcap/nametoaddr.c
 create mode 100644 pcap/optimize.c
 create mode 100644 pcap/pcap-bpf.c
 create mode 100644 pcap/pcap-int.h
 create mode 100644 pcap/pcap-namedb.h
 create mode 100644 pcap/pcap.c
 create mode 100644 pcap/pcap.h
 create mode 100644 pcap/savefile.c
 create mode 100644 pcap/scanner.l
 create mode 100644 ping.tproj/Makefile
 create mode 100644 ping.tproj/Makefile.dist
 create mode 100644 ping.tproj/Makefile.postamble
 create mode 100644 ping.tproj/Makefile.preamble
 create mode 100644 ping.tproj/PB.project
 create mode 100644 ping.tproj/ping.8
 create mode 100644 ping.tproj/ping.c
 create mode 100644 portmap.tproj/Makefile
 create mode 100644 portmap.tproj/Makefile.postamble
 create mode 100644 portmap.tproj/Makefile.preamble
 create mode 100644 portmap.tproj/PB.project
 create mode 100644 portmap.tproj/portmap.8
 create mode 100644 portmap.tproj/portmap.c
 create mode 100644 rarpd.tproj/Makefile
 create mode 100644 rarpd.tproj/Makefile.dist
 create mode 100644 rarpd.tproj/Makefile.preamble
 create mode 100644 rarpd.tproj/PB.project
 create mode 100644 rarpd.tproj/rarpd.8
 create mode 100644 rarpd.tproj/rarpd.c
 create mode 100644 rbootd.tproj/Makefile
 create mode 100644 rbootd.tproj/Makefile.postamble
 create mode 100644 rbootd.tproj/Makefile.preamble
 create mode 100644 rbootd.tproj/PB.project
 create mode 100644 rbootd.tproj/bpf.c
 create mode 100644 rbootd.tproj/conf.c
 create mode 100644 rbootd.tproj/defs.h
 create mode 100644 rbootd.tproj/parseconf.c
 create mode 100644 rbootd.tproj/pathnames.h
 create mode 100644 rbootd.tproj/rbootd.8
 create mode 100644 rbootd.tproj/rbootd.c
 create mode 100644 rbootd.tproj/rmp.h
 create mode 100644 rbootd.tproj/rmp_var.h
 create mode 100644 rbootd.tproj/rmpproto.c
 create mode 100644 rbootd.tproj/utils.c
 create mode 100644 rcp.tproj/Makefile
 create mode 100644 rcp.tproj/Makefile.dist
 create mode 100644 rcp.tproj/Makefile.postamble
 create mode 100644 rcp.tproj/Makefile.preamble
 create mode 100644 rcp.tproj/PB.project
 create mode 100644 rcp.tproj/extern.h
 create mode 100644 rcp.tproj/pathnames.h
 create mode 100644 rcp.tproj/rcp.1
 create mode 100644 rcp.tproj/rcp.c
 create mode 100644 rcp.tproj/util.c
 create mode 100644 revnetgroup.tproj/Makefile
 create mode 100644 revnetgroup.tproj/Makefile.postamble
 create mode 100644 revnetgroup.tproj/Makefile.preamble
 create mode 100644 revnetgroup.tproj/PB.project
 create mode 100644 revnetgroup.tproj/hash.c
 create mode 100644 revnetgroup.tproj/hash.h
 create mode 100644 revnetgroup.tproj/parse_netgroup.c
 create mode 100644 revnetgroup.tproj/revnetgroup.8
 create mode 100644 revnetgroup.tproj/revnetgroup.c
 create mode 100644 rexecd.tproj/Makefile
 create mode 100644 rexecd.tproj/Makefile.postamble
 create mode 100644 rexecd.tproj/Makefile.preamble
 create mode 100644 rexecd.tproj/PB.project
 create mode 100644 rexecd.tproj/rexecd.8
 create mode 100644 rexecd.tproj/rexecd.c
 create mode 100644 rlogin.tproj/Makefile
 create mode 100644 rlogin.tproj/Makefile.postamble
 create mode 100644 rlogin.tproj/Makefile.preamble
 create mode 100644 rlogin.tproj/PB.project
 create mode 100644 rlogin.tproj/des_rw.c
 create mode 100644 rlogin.tproj/kcmd.c
 create mode 100644 rlogin.tproj/krb.h
 create mode 100644 rlogin.tproj/krcmd.c
 create mode 100644 rlogin.tproj/rlogin.1
 create mode 100644 rlogin.tproj/rlogin.c
 create mode 100644 rlogind.tproj/Makefile
 create mode 100644 rlogind.tproj/Makefile.postamble
 create mode 100644 rlogind.tproj/Makefile.preamble
 create mode 100644 rlogind.tproj/PB.project
 create mode 100644 rlogind.tproj/pathnames.h
 create mode 100644 rlogind.tproj/rlogind.8
 create mode 100644 rlogind.tproj/rlogind.c
 create mode 100644 route.tproj/Makefile
 create mode 100644 route.tproj/Makefile.dist
 create mode 100644 route.tproj/Makefile.postamble
 create mode 100644 route.tproj/Makefile.preamble
 create mode 100644 route.tproj/PB.project
 create mode 100644 route.tproj/ccitt_addr.c
 create mode 100644 route.tproj/keywords.h
 create mode 100644 route.tproj/route.8
 create mode 100644 route.tproj/route.c
 create mode 100644 routed.tproj/Makefile
 create mode 100644 routed.tproj/Makefile.dist
 create mode 100644 routed.tproj/Makefile.preamble
 create mode 100644 routed.tproj/PB.project
 create mode 100644 routed.tproj/af.c
 create mode 100644 routed.tproj/af.h
 create mode 100644 routed.tproj/defs.c
 create mode 100644 routed.tproj/defs.h
 create mode 100644 routed.tproj/if.c
 create mode 100644 routed.tproj/inet.c
 create mode 100644 routed.tproj/input.c
 create mode 100644 routed.tproj/interface.h
 create mode 100644 routed.tproj/main.c
 create mode 100644 routed.tproj/output.c
 create mode 100644 routed.tproj/pathnames.h
 create mode 100644 routed.tproj/routed.8
 create mode 100644 routed.tproj/startup.c
 create mode 100644 routed.tproj/table.h
 create mode 100644 routed.tproj/tables.c
 create mode 100644 routed.tproj/timer.c
 create mode 100644 routed.tproj/trace.c
 create mode 100644 routed.tproj/trace.h
 create mode 100644 rpc_yppasswdd.tproj/Makefile
 create mode 100644 rpc_yppasswdd.tproj/Makefile.postamble
 create mode 100644 rpc_yppasswdd.tproj/Makefile.preamble
 create mode 100644 rpc_yppasswdd.tproj/PB.project
 create mode 100644 rpc_yppasswdd.tproj/passwd.c
 create mode 100644 rpc_yppasswdd.tproj/rpc.yppasswdd.8
 create mode 100644 rpc_yppasswdd.tproj/rpc.yppasswdd.c
 create mode 100644 rpc_yppasswdd.tproj/yppasswd.h
 create mode 100644 rpc_yppasswdd.tproj/yppasswdd_mkpw.c
 create mode 100644 rpc_yppasswdd.tproj/yppasswdd_proc.c
 create mode 100644 rpcinfo.tproj/Makefile
 create mode 100644 rpcinfo.tproj/Makefile.postamble
 create mode 100644 rpcinfo.tproj/Makefile.preamble
 create mode 100644 rpcinfo.tproj/PB.project
 create mode 100644 rpcinfo.tproj/h.template
 create mode 100644 rpcinfo.tproj/m.template
 create mode 100644 rpcinfo.tproj/rpcinfo.c
 create mode 100644 rsh.tproj/Makefile
 create mode 100644 rsh.tproj/Makefile.postamble
 create mode 100644 rsh.tproj/Makefile.preamble
 create mode 100644 rsh.tproj/PB.project
 create mode 100644 rsh.tproj/pathnames.h
 create mode 100644 rsh.tproj/rsh.1
 create mode 100644 rsh.tproj/rsh.c
 create mode 100644 rshd.tproj/Makefile
 create mode 100644 rshd.tproj/Makefile.postamble
 create mode 100644 rshd.tproj/Makefile.preamble
 create mode 100644 rshd.tproj/PB.project
 create mode 100644 rshd.tproj/rshd.8
 create mode 100644 rshd.tproj/rshd.c
 create mode 100644 ruptime.tproj/Makefile
 create mode 100644 ruptime.tproj/Makefile.dist
 create mode 100644 ruptime.tproj/Makefile.postamble
 create mode 100644 ruptime.tproj/Makefile.preamble
 create mode 100644 ruptime.tproj/PB.project
 create mode 100644 ruptime.tproj/h.template
 create mode 100644 ruptime.tproj/m.template
 create mode 100644 ruptime.tproj/ruptime.1
 create mode 100644 ruptime.tproj/ruptime.c
 create mode 100644 rwho.tproj/Makefile
 create mode 100644 rwho.tproj/Makefile.dist
 create mode 100644 rwho.tproj/Makefile.postamble
 create mode 100644 rwho.tproj/Makefile.preamble
 create mode 100644 rwho.tproj/PB.project
 create mode 100644 rwho.tproj/rwho.1
 create mode 100644 rwho.tproj/rwho.c
 create mode 100644 rwhod.tproj/Makefile
 create mode 100644 rwhod.tproj/Makefile.postamble
 create mode 100644 rwhod.tproj/Makefile.preamble
 create mode 100644 rwhod.tproj/PB.project
 create mode 100644 rwhod.tproj/rwhod.8
 create mode 100644 rwhod.tproj/rwhod.c
 create mode 100644 slattach.tproj/Makefile
 create mode 100644 slattach.tproj/Makefile.dist
 create mode 100644 slattach.tproj/Makefile.preamble
 create mode 100644 slattach.tproj/PB.project
 create mode 100644 slattach.tproj/slattach.8
 create mode 100644 slattach.tproj/slattach.c
 create mode 100644 sliplogin.tproj/Makefile
 create mode 100644 sliplogin.tproj/Makefile.postamble
 create mode 100644 sliplogin.tproj/Makefile.preamble
 create mode 100644 sliplogin.tproj/PB.project
 create mode 100644 sliplogin.tproj/pathnames.h
 create mode 100644 sliplogin.tproj/slip.hosts
 create mode 100644 sliplogin.tproj/slip.login
 create mode 100644 sliplogin.tproj/sliplogin.8
 create mode 100644 sliplogin.tproj/sliplogin.c
 create mode 100644 spray.tproj/Makefile
 create mode 100644 spray.tproj/Makefile.dist
 create mode 100644 spray.tproj/Makefile.postamble
 create mode 100644 spray.tproj/Makefile.preamble
 create mode 100644 spray.tproj/PB.project
 create mode 100644 spray.tproj/spray.c
 create mode 100644 spray.tproj/spray.x
 create mode 100644 startslip.tproj/Makefile
 create mode 100644 startslip.tproj/Makefile.dist
 create mode 100644 startslip.tproj/Makefile.preamble
 create mode 100644 startslip.tproj/PB.project
 create mode 100644 startslip.tproj/startslip.1
 create mode 100644 startslip.tproj/startslip.c
 create mode 100644 stdethers.tproj/Makefile
 create mode 100644 stdethers.tproj/Makefile.postamble
 create mode 100644 stdethers.tproj/Makefile.preamble
 create mode 100644 stdethers.tproj/PB.project
 create mode 100644 stdethers.tproj/stdethers.8
 create mode 100644 stdethers.tproj/stdethers.c
 create mode 100644 stdhosts.tproj/Makefile
 create mode 100644 stdhosts.tproj/Makefile.postamble
 create mode 100644 stdhosts.tproj/Makefile.preamble
 create mode 100644 stdhosts.tproj/PB.project
 create mode 100644 stdhosts.tproj/stdhosts.8
 create mode 100644 stdhosts.tproj/stdhosts.c
 create mode 100644 syslogd.tproj/Makefile
 create mode 100644 syslogd.tproj/Makefile.postamble
 create mode 100644 syslogd.tproj/Makefile.preamble
 create mode 100644 syslogd.tproj/PB.project
 create mode 100644 syslogd.tproj/pathnames.h
 create mode 100644 syslogd.tproj/syslog.conf.5
 create mode 100644 syslogd.tproj/syslogd.8
 create mode 100644 syslogd.tproj/syslogd.c
 create mode 100644 talk.tproj/Makefile
 create mode 100644 talk.tproj/Makefile.preamble
 create mode 100644 talk.tproj/PB.project
 create mode 100644 talk.tproj/ctl.c
 create mode 100644 talk.tproj/ctl_transact.c
 create mode 100644 talk.tproj/display.c
 create mode 100644 talk.tproj/get_addrs.c
 create mode 100644 talk.tproj/get_names.c
 create mode 100644 talk.tproj/init_disp.c
 create mode 100644 talk.tproj/invite.c
 create mode 100644 talk.tproj/io.c
 create mode 100644 talk.tproj/look_up.c
 create mode 100644 talk.tproj/msgs.c
 create mode 100644 talk.tproj/talk.1
 create mode 100644 talk.tproj/talk.c
 create mode 100644 talk.tproj/talk.h
 create mode 100644 talk.tproj/talk_ctl.h
 create mode 100644 talkd.tproj/Makefile
 create mode 100644 talkd.tproj/Makefile.dist
 create mode 100644 talkd.tproj/Makefile.postamble
 create mode 100644 talkd.tproj/Makefile.preamble
 create mode 100644 talkd.tproj/PB.project
 create mode 100644 talkd.tproj/announce.c
 create mode 100644 talkd.tproj/print.c
 create mode 100644 talkd.tproj/process.c
 create mode 100644 talkd.tproj/table.c
 create mode 100644 talkd.tproj/talkd.8
 create mode 100644 talkd.tproj/talkd.c
 create mode 100644 talkd.tproj/talkd.h
 create mode 100644 tcpdump.tproj/Makefile
 create mode 100644 tcpdump.tproj/Makefile.postamble
 create mode 100644 tcpdump.tproj/Makefile.preamble
 create mode 100644 tcpdump.tproj/PB.project
 create mode 100644 tcpdump.tproj/addrtoname.c
 create mode 100644 tcpdump.tproj/addrtoname.h
 create mode 100644 tcpdump.tproj/appletalk.h
 create mode 100644 tcpdump.tproj/bootp.h
 create mode 100644 tcpdump.tproj/bpf_dump.c
 create mode 100644 tcpdump.tproj/decnet.h
 create mode 100644 tcpdump.tproj/ethertype.h
 create mode 100644 tcpdump.tproj/extract.h
 create mode 100644 tcpdump.tproj/fddi.h
 create mode 100644 tcpdump.tproj/gnuc.h
 create mode 100644 tcpdump.tproj/igrp.h
 create mode 100644 tcpdump.tproj/interface.h
 create mode 100644 tcpdump.tproj/ipx.h
 create mode 100644 tcpdump.tproj/llc.h
 create mode 100644 tcpdump.tproj/machdep.c
 create mode 100644 tcpdump.tproj/machdep.h
 create mode 100644 tcpdump.tproj/mib.h
 create mode 100644 tcpdump.tproj/netbios.h
 create mode 100644 tcpdump.tproj/nfs.h
 create mode 100644 tcpdump.tproj/nfsfh.h
 create mode 100644 tcpdump.tproj/nfsv2.h
 create mode 100644 tcpdump.tproj/ntp.h
 create mode 100644 tcpdump.tproj/os-solaris2.h
 create mode 100644 tcpdump.tproj/os-sunos4.h
 create mode 100644 tcpdump.tproj/os-ultrix4.h
 create mode 100644 tcpdump.tproj/ospf.h
 create mode 100644 tcpdump.tproj/parsenfsfh.c
 create mode 100644 tcpdump.tproj/print-arp.c
 create mode 100644 tcpdump.tproj/print-atalk.c
 create mode 100644 tcpdump.tproj/print-atm.c
 create mode 100644 tcpdump.tproj/print-bootp.c
 create mode 100644 tcpdump.tproj/print-decnet.c
 create mode 100644 tcpdump.tproj/print-domain.c
 create mode 100644 tcpdump.tproj/print-dvmrp.c
 create mode 100644 tcpdump.tproj/print-egp.c
 create mode 100644 tcpdump.tproj/print-ether.c
 create mode 100644 tcpdump.tproj/print-fddi.c
 create mode 100644 tcpdump.tproj/print-gre.c
 create mode 100644 tcpdump.tproj/print-icmp.c
 create mode 100644 tcpdump.tproj/print-igrp.c
 create mode 100644 tcpdump.tproj/print-ip.c
 create mode 100644 tcpdump.tproj/print-ipx.c
 create mode 100644 tcpdump.tproj/print-isoclns.c
 create mode 100644 tcpdump.tproj/print-krb.c
 create mode 100644 tcpdump.tproj/print-llc.c
 create mode 100644 tcpdump.tproj/print-netbios.c
 create mode 100644 tcpdump.tproj/print-nfs.c
 create mode 100644 tcpdump.tproj/print-ntp.c
 create mode 100644 tcpdump.tproj/print-null.c
 create mode 100644 tcpdump.tproj/print-ospf.c
 create mode 100644 tcpdump.tproj/print-pim.c
 create mode 100644 tcpdump.tproj/print-ppp.c
 create mode 100644 tcpdump.tproj/print-rip.c
 create mode 100644 tcpdump.tproj/print-skip.c
 create mode 100644 tcpdump.tproj/print-sl.c
 create mode 100644 tcpdump.tproj/print-snmp.c
 create mode 100644 tcpdump.tproj/print-sunrpc.c
 create mode 100644 tcpdump.tproj/print-tcp.c
 create mode 100644 tcpdump.tproj/print-tftp.c
 create mode 100644 tcpdump.tproj/print-udp.c
 create mode 100644 tcpdump.tproj/print-wb.c
 create mode 100644 tcpdump.tproj/strcasecmp.c
 create mode 100644 tcpdump.tproj/tcpdump.c
 create mode 100644 tcpdump.tproj/util.c
 create mode 100644 tcpdump.tproj/version.c
 create mode 100644 tcpdump.tproj/vfprintf.c
 create mode 100644 telnet.tproj/Makefile
 create mode 100644 telnet.tproj/Makefile.dist
 create mode 100644 telnet.tproj/Makefile.preamble
 create mode 100644 telnet.tproj/PB.project
 create mode 100644 telnet.tproj/README
 create mode 100644 telnet.tproj/authenc.c
 create mode 100644 telnet.tproj/commands.c
 create mode 100644 telnet.tproj/defines.h
 create mode 100644 telnet.tproj/externs.h
 create mode 100644 telnet.tproj/fdset.h
 create mode 100644 telnet.tproj/general.h
 create mode 100644 telnet.tproj/krb4-proto.h
 create mode 100644 telnet.tproj/main.c
 create mode 100644 telnet.tproj/network.c
 create mode 100644 telnet.tproj/ring.c
 create mode 100644 telnet.tproj/ring.h
 create mode 100644 telnet.tproj/sys_bsd.c
 create mode 100644 telnet.tproj/telnet.1
 create mode 100644 telnet.tproj/telnet.c
 create mode 100644 telnet.tproj/terminal.c
 create mode 100644 telnet.tproj/tn3270.c
 create mode 100644 telnet.tproj/types.h
 create mode 100644 telnet.tproj/utilities.c
 create mode 100644 telnetd.tproj/Makefile
 create mode 100644 telnetd.tproj/Makefile.postamble
 create mode 100644 telnetd.tproj/Makefile.preamble
 create mode 100644 telnetd.tproj/PB.project
 create mode 100644 telnetd.tproj/authenc.c
 create mode 100644 telnetd.tproj/defs.h
 create mode 100644 telnetd.tproj/ext.h
 create mode 100644 telnetd.tproj/global.c
 create mode 100644 telnetd.tproj/pathnames.h
 create mode 100644 telnetd.tproj/slc.c
 create mode 100644 telnetd.tproj/state.c
 create mode 100644 telnetd.tproj/sys_term.c
 create mode 100644 telnetd.tproj/telnetd.8
 create mode 100644 telnetd.tproj/telnetd.c
 create mode 100644 telnetd.tproj/telnetd.h
 create mode 100644 telnetd.tproj/termstat.c
 create mode 100644 telnetd.tproj/utility.c
 create mode 100644 tftp.tproj/Makefile
 create mode 100644 tftp.tproj/Makefile.preamble
 create mode 100644 tftp.tproj/PB.project
 create mode 100644 tftp.tproj/extern.h
 create mode 100644 tftp.tproj/main.c
 create mode 100644 tftp.tproj/tftp.1
 create mode 100644 tftp.tproj/tftp.c
 create mode 100644 tftp.tproj/tftpsubs.c
 create mode 100644 tftp.tproj/tftpsubs.h
 create mode 100644 tftpd.tproj/Makefile
 create mode 100644 tftpd.tproj/Makefile.postamble
 create mode 100644 tftpd.tproj/Makefile.preamble
 create mode 100644 tftpd.tproj/PB.project
 create mode 100644 tftpd.tproj/tftpd.8
 create mode 100644 tftpd.tproj/tftpd.c
 create mode 100644 timed.tproj/Makefile
 create mode 100644 timed.tproj/Makefile.postamble
 create mode 100644 timed.tproj/Makefile.preamble
 create mode 100644 timed.tproj/PB.project
 create mode 100644 timed.tproj/timed.tproj/Makefile
 create mode 100644 timed.tproj/timed.tproj/Makefile.postamble
 create mode 100644 timed.tproj/timed.tproj/Makefile.preamble
 create mode 100644 timed.tproj/timed.tproj/PB.project
 create mode 100644 timed.tproj/timed.tproj/acksend.c
 create mode 100644 timed.tproj/timed.tproj/byteorder.c
 create mode 100644 timed.tproj/timed.tproj/candidate.c
 create mode 100644 timed.tproj/timed.tproj/cksum.c
 create mode 100644 timed.tproj/timed.tproj/correct.c
 create mode 100644 timed.tproj/timed.tproj/extern.h
 create mode 100644 timed.tproj/timed.tproj/globals.h
 create mode 100644 timed.tproj/timed.tproj/master.c
 create mode 100644 timed.tproj/timed.tproj/measure.c
 create mode 100644 timed.tproj/timed.tproj/networkdelta.c
 create mode 100644 timed.tproj/timed.tproj/pathnames.h
 create mode 100644 timed.tproj/timed.tproj/readmsg.c
 create mode 100644 timed.tproj/timed.tproj/slave.c
 create mode 100644 timed.tproj/timed.tproj/timed.8
 create mode 100644 timed.tproj/timed.tproj/timed.c
 create mode 100644 timed.tproj/timedc.tproj/Makefile
 create mode 100644 timed.tproj/timedc.tproj/Makefile.postamble
 create mode 100644 timed.tproj/timedc.tproj/Makefile.preamble
 create mode 100644 timed.tproj/timedc.tproj/PB.project
 create mode 100644 timed.tproj/timedc.tproj/cmds.c
 create mode 100644 timed.tproj/timedc.tproj/cmdtab.c
 create mode 100644 timed.tproj/timedc.tproj/extern.h
 create mode 100644 timed.tproj/timedc.tproj/h.template
 create mode 100644 timed.tproj/timedc.tproj/m.template
 create mode 100644 timed.tproj/timedc.tproj/timedc.c
 create mode 100644 timed.tproj/timedc.tproj/timedc.h
 create mode 100644 traceroute.tproj/Makefile
 create mode 100644 traceroute.tproj/Makefile.postamble
 create mode 100644 traceroute.tproj/Makefile.preamble
 create mode 100644 traceroute.tproj/PB.project
 create mode 100644 traceroute.tproj/README
 create mode 100644 traceroute.tproj/mean.awk
 create mode 100644 traceroute.tproj/median.awk
 create mode 100644 traceroute.tproj/traceroute.8
 create mode 100644 traceroute.tproj/traceroute.c
 create mode 100644 trpt.tproj/Makefile
 create mode 100644 trpt.tproj/Makefile.postamble
 create mode 100644 trpt.tproj/Makefile.preamble
 create mode 100644 trpt.tproj/PB.project
 create mode 100644 trpt.tproj/trpt.8
 create mode 100644 trpt.tproj/trpt.c
 create mode 100644 trsp.tproj/Makefile
 create mode 100644 trsp.tproj/Makefile.postamble
 create mode 100644 trsp.tproj/Makefile.preamble
 create mode 100644 trsp.tproj/PB.project
 create mode 100644 trsp.tproj/trsp.8
 create mode 100644 trsp.tproj/trsp.c
 create mode 100644 uucpd.tproj/Makefile
 create mode 100644 uucpd.tproj/Makefile.postamble
 create mode 100644 uucpd.tproj/Makefile.preamble
 create mode 100644 uucpd.tproj/PB.project
 create mode 100644 uucpd.tproj/pathnames.h
 create mode 100644 uucpd.tproj/uucpd.c
 create mode 100644 wall.tproj/Makefile
 create mode 100644 wall.tproj/Makefile.dist
 create mode 100644 wall.tproj/Makefile.postamble
 create mode 100644 wall.tproj/Makefile.preamble
 create mode 100644 wall.tproj/PB.project
 create mode 100644 wall.tproj/ttymsg.c
 create mode 100644 wall.tproj/wall.1
 create mode 100644 wall.tproj/wall.c
 create mode 100644 ypbind.tproj/Makefile
 create mode 100644 ypbind.tproj/Makefile.dist
 create mode 100644 ypbind.tproj/Makefile.postamble
 create mode 100644 ypbind.tproj/Makefile.preamble
 create mode 100644 ypbind.tproj/PB.project
 create mode 100644 ypbind.tproj/yp.x
 create mode 100644 ypbind.tproj/ypbind.c
 create mode 100644 ypcat.tproj/Makefile
 create mode 100644 ypcat.tproj/Makefile.dist
 create mode 100644 ypcat.tproj/Makefile.preamble
 create mode 100644 ypcat.tproj/PB.project
 create mode 100644 ypcat.tproj/ypcat.1
 create mode 100644 ypcat.tproj/ypcat.c
 create mode 100644 ypinit.tproj/Makefile
 create mode 100644 ypinit.tproj/Makefile.main
 create mode 100644 ypinit.tproj/Makefile.yp
 create mode 100644 ypinit.tproj/ypinit.sh
 create mode 100644 ypmatch.tproj/Makefile
 create mode 100644 ypmatch.tproj/Makefile.dist
 create mode 100644 ypmatch.tproj/Makefile.preamble
 create mode 100644 ypmatch.tproj/PB.project
 create mode 100644 ypmatch.tproj/ypmatch.1
 create mode 100644 ypmatch.tproj/ypmatch.c
 create mode 100644 yppoll.tproj/Makefile
 create mode 100644 yppoll.tproj/Makefile.dist
 create mode 100644 yppoll.tproj/Makefile.preamble
 create mode 100644 yppoll.tproj/PB.project
 create mode 100644 yppoll.tproj/yppoll.8
 create mode 100644 yppoll.tproj/yppoll.c
 create mode 100644 yppush.tproj/Makefile
 create mode 100644 yppush.tproj/Makefile.postamble
 create mode 100644 yppush.tproj/Makefile.preamble
 create mode 100644 yppush.tproj/PB.project
 create mode 100644 yppush.tproj/ypdb.c
 create mode 100644 yppush.tproj/ypdb.h
 create mode 100644 yppush.tproj/ypdef.h
 create mode 100644 yppush.tproj/yplib_host.c
 create mode 100644 yppush.tproj/yplib_host.h
 create mode 100644 yppush.tproj/yppush.8
 create mode 100644 yppush.tproj/yppush.c
 create mode 100644 yppush.tproj/yppush.h
 create mode 100644 yppush.tproj/yppush_err.c
 create mode 100644 yppush.tproj/yppush_proc.c
 create mode 100644 yppush.tproj/yppush_svc.c
 create mode 100644 yppush.tproj/yppush_xdr.c
 create mode 100644 ypserv.tproj/Makefile
 create mode 100644 ypserv.tproj/Makefile.postamble
 create mode 100644 ypserv.tproj/Makefile.preamble
 create mode 100644 ypserv.tproj/PB.project
 create mode 100644 ypserv.tproj/acl.c
 create mode 100644 ypserv.tproj/acl.h
 create mode 100644 ypserv.tproj/securenet
 create mode 100644 ypserv.tproj/securenet.5
 create mode 100644 ypserv.tproj/yp.h
 create mode 100644 ypserv.tproj/ypdb.c
 create mode 100644 ypserv.tproj/ypdb.h
 create mode 100644 ypserv.tproj/ypdef.h
 create mode 100644 ypserv.tproj/yplog.c
 create mode 100644 ypserv.tproj/yplog.h
 create mode 100644 ypserv.tproj/ypserv.acl
 create mode 100644 ypserv.tproj/ypserv.acl.5
 create mode 100644 ypserv.tproj/ypserv.c
 create mode 100644 ypserv.tproj/ypserv_db.c
 create mode 100644 ypserv.tproj/ypserv_proc.c
 create mode 100644 ypserv.tproj/ypserv_xdr.c
 create mode 100644 ypserv.tproj/ypserv_xdr_v1.c
 create mode 100644 ypserv.tproj/ypv1.h
 create mode 100644 ypset.tproj/Makefile
 create mode 100644 ypset.tproj/Makefile.dist
 create mode 100644 ypset.tproj/Makefile.preamble
 create mode 100644 ypset.tproj/PB.project
 create mode 100644 ypset.tproj/ypset.c
 create mode 100644 ypwhich.tproj/Makefile
 create mode 100644 ypwhich.tproj/Makefile.dist
 create mode 100644 ypwhich.tproj/Makefile.preamble
 create mode 100644 ypwhich.tproj/PB.project
 create mode 100644 ypwhich.tproj/ypwhich.1
 create mode 100644 ypwhich.tproj/ypwhich.c
 create mode 100644 ypxfr.tproj/Makefile
 create mode 100644 ypxfr.tproj/Makefile.postamble
 create mode 100644 ypxfr.tproj/Makefile.preamble
 create mode 100644 ypxfr.tproj/PB.project
 create mode 100644 ypxfr.tproj/ypdb.c
 create mode 100644 ypxfr.tproj/ypdb.h
 create mode 100644 ypxfr.tproj/ypdef.h
 create mode 100644 ypxfr.tproj/yplib_host.c
 create mode 100644 ypxfr.tproj/yplib_host.h
 create mode 100644 ypxfr.tproj/yplog.c
 create mode 100644 ypxfr.tproj/yplog.h
 create mode 100644 ypxfr.tproj/ypxfr.8
 create mode 100644 ypxfr.tproj/ypxfr.c
 create mode 100755 ypxfr.tproj/ypxfr_1perday.sh
 create mode 100755 ypxfr.tproj/ypxfr_1perhour.sh
 create mode 100755 ypxfr.tproj/ypxfr_2perday.sh
 create mode 100644 ypxfr.tproj/ypxfr_xdr.c

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b8719cd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,59 @@
+#
+# Generated by the Apple Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = network_cmds
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Aggregate
+
+SUBPROJECTS = timed.tproj bootparams
+
+TOOLS = arp.tproj domainname.tproj ftp.tproj ftpd.tproj identd.tproj\
+        ifconfig.tproj inetd.tproj logger.tproj netstat.tproj\
+        nfsd.tproj nfsiod.tproj nfsstat.tproj ping.tproj portmap.tproj\
+        rarpd.tproj rbootd.tproj rcp.tproj rexecd.tproj rlogin.tproj\
+        rlogind.tproj route.tproj routed.tproj rpcinfo.tproj rsh.tproj\
+        rshd.tproj ruptime.tproj rwho.tproj rwhod.tproj slattach.tproj\
+        sliplogin.tproj spray.tproj startslip.tproj syslogd.tproj\
+        talk.tproj talkd.tproj tcpdump.tproj telnet.tproj\
+        telnetd.tproj tftp.tproj tftpd.tproj traceroute.tproj\
+        trpt.tproj trsp.tproj uucpd.tproj wall.tproj ypbind.tproj\
+        ypcat.tproj ypmatch.tproj yppoll.tproj yppush.tproj\
+        ypserv.tproj ypset.tproj ypwhich.tproj ypxfr.tproj\
+        makedbm.tproj revnetgroup.tproj rpc_yppasswdd.tproj\
+        stdethers.tproj stdhosts.tproj natd.tproj ipfw.tproj
+
+LIBRARIES = alias pcap
+
+LEGACIES = newclient.tproj ypinit.tproj
+
+OTHERSRCS = Makefile Makefile.include Makefile.preamble
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = aggregate.make
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/Makefile.include b/Makefile.include
new file mode 100644
index 0000000..ee97aa2
--- /dev/null
+++ b/Makefile.include
@@ -0,0 +1,12 @@
+##
+## Temporary flags for static Teflon builds
+##
+
+#CODE_GEN_STYLE = STATIC
+#OTHER_LDFLAGS = -nostdlib /lib/crt0.o -L/tmp/lennart/lib -L/usr/local/lib
+#OTHER_LIBS = -linfo -lc -lm
+
+#OTHER_LDFLAGS = -nostdlib /lib/crt1.o
+#OTHER_LIBS = -framework System
+
+CHFLAGS = true		# until we really have chflags on our system
diff --git a/Makefile.preamble b/Makefile.preamble
new file mode 100644
index 0000000..a6b1e76
--- /dev/null
+++ b/Makefile.preamble
@@ -0,0 +1 @@
+CLEAN_ALL_SUBPROJECTS = YES
diff --git a/PB.project b/PB.project
new file mode 100644
index 0000000..3015bd3
--- /dev/null
+++ b/PB.project
@@ -0,0 +1,82 @@
+{
+    FILESTABLE = {
+        OTHER_SOURCES = (Makefile, Makefile.include, Makefile.preamble); 
+        SUBPROJECTS = (
+            alias, 
+            pcap, 
+            timed.tproj, 
+            arp.tproj, 
+            bootparams, 
+            domainname.tproj, 
+            ftp.tproj, 
+            ftpd.tproj, 
+            identd.tproj, 
+            ifconfig.tproj, 
+            inetd.tproj, 
+            logger.tproj, 
+            netstat.tproj, 
+            newclient.tproj, 
+            nfsd.tproj, 
+            nfsiod.tproj, 
+            nfsstat.tproj, 
+            ping.tproj, 
+            portmap.tproj, 
+            rarpd.tproj, 
+            rbootd.tproj, 
+            rcp.tproj, 
+            rexecd.tproj, 
+            rlogin.tproj, 
+            rlogind.tproj, 
+            route.tproj, 
+            routed.tproj, 
+            rpcinfo.tproj, 
+            rsh.tproj, 
+            rshd.tproj, 
+            ruptime.tproj, 
+            rwho.tproj, 
+            rwhod.tproj, 
+            slattach.tproj, 
+            sliplogin.tproj, 
+            spray.tproj, 
+            startslip.tproj, 
+            syslogd.tproj, 
+            talk.tproj, 
+            talkd.tproj, 
+            tcpdump.tproj, 
+            telnet.tproj, 
+            telnetd.tproj, 
+            tftp.tproj, 
+            tftpd.tproj, 
+            traceroute.tproj, 
+            trpt.tproj, 
+            trsp.tproj, 
+            uucpd.tproj, 
+            wall.tproj, 
+            ypbind.tproj, 
+            ypcat.tproj, 
+            ypinit.tproj, 
+            ypmatch.tproj, 
+            yppoll.tproj, 
+            yppush.tproj, 
+            ypserv.tproj, 
+            ypset.tproj, 
+            ypwhich.tproj, 
+            ypxfr.tproj, 
+            makedbm.tproj, 
+            revnetgroup.tproj, 
+            rpc_yppasswdd.tproj, 
+            stdethers.tproj, 
+            stdhosts.tproj, 
+            natd.tproj, 
+            ipfw.tproj
+        ); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /usr/bin/gnumake; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PROJECTNAME = network_cmds; 
+    PROJECTTYPE = Aggregate; 
+    PROJECTVERSION = 2.8; 
+}
diff --git a/alias/Makefile b/alias/Makefile
new file mode 100644
index 0000000..f844cc3
--- /dev/null
+++ b/alias/Makefile
@@ -0,0 +1,59 @@
+#
+# Generated by the Apple Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = alias
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Library
+
+HFILES = alias.h alias_local.h
+
+CFILES = alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c\
+         alias_nbt.c alias_proxy.c alias_util.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CURRENTLY_ACTIVE_VERSION = YES
+DEPLOY_WITH_VERSION_NAME = A
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = library.make
+NEXTSTEP_INSTALLDIR = /usr/lib
+WINDOWS_INSTALLDIR = /Developer/Libraries
+PDO_UNIX_INSTALLDIR = /usr/lib
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+PROJECT_HEADERS = alias.h
+
+
+
+WINDOWS_PUBLIC_HEADERS_DIR = /Developer/Headers/$(NAME)
+
+PDO_UNIX_PUBLIC_HEADERS_DIR = /Developer/Headers/$(NAME)
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/alias/Makefile.postamble b/alias/Makefile.postamble
new file mode 100644
index 0000000..411cde6
--- /dev/null
+++ b/alias/Makefile.postamble
@@ -0,0 +1,100 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGES: langages in which the project is written (default "English")
+#  English_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/alias/Makefile.preamble b/alias/Makefile.preamble
new file mode 100644
index 0000000..f02898c
--- /dev/null
+++ b/alias/Makefile.preamble
@@ -0,0 +1,138 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+OTHER_LDFLAGS += -seg1addr 0xf9300000
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.  For library projects you should
+#       set this to something like /Developer/Headers/$(NAME).  Do not set
+#       this variable for framework projects unless you do not want the
+#       header files included in the framework.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. This defaults to
+#       DYNAMIC.
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Uncomment to suppress generation of a KeyValueCoding index when installing 
+# frameworks (This index is used by WOB and IB to determine keys available
+# for an object).  Set to YES by default.
+# PREINDEX_FRAMEWORK = NO
+
+# Change this definition to install projects somewhere other than the
+# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
+# and "" on other systems.
+DSTROOT = $(HOME)
diff --git a/alias/PB.project b/alias/PB.project
new file mode 100644
index 0000000..e87cc27
--- /dev/null
+++ b/alias/PB.project
@@ -0,0 +1,39 @@
+{
+    CURRENTLY_ACTIVE_VERSION = YES; 
+    DEPLOY_WITH_VERSION_NAME = A; 
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        H_FILES = (alias.h, alias_local.h); 
+        OTHER_LINKED = (
+            alias.c, 
+            alias_cuseeme.c, 
+            alias_db.c, 
+            alias_ftp.c, 
+            alias_irc.c, 
+            alias_nbt.c, 
+            alias_proxy.c, 
+            alias_util.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        PROJECT_HEADERS = (alias.h); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/lib; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_INSTALLDIR = /usr/lib; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PDO_UNIX_PUBLICHEADERSDIR = "/Developer/Headers/$(NAME)"; 
+    PROJECTNAME = alias; 
+    PROJECTTYPE = Library; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = /Developer/Libraries; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+    WINDOWS_PUBLICHEADERSDIR = "/Developer/Headers/$(NAME)"; 
+}
diff --git a/alias/alias.c b/alias/alias.c
new file mode 100644
index 0000000..10e0ccc
--- /dev/null
+++ b/alias/alias.c
@@ -0,0 +1,1318 @@
+/* -*- mode: c; tab-width: 8; c-basic-indent: 4; -*- */
+/*
+    Alias.c provides supervisory control for the functions of the
+    packet aliasing software.  It consists of routines to monitor
+    TCP connection state, protocol-specific aliasing routines,
+    fragment handling and the following outside world functional
+    interfaces: SaveFragmentPtr, GetFragmentPtr, FragmentAliasIn,
+    PacketAliasIn and PacketAliasOut.
+
+    The other C program files are briefly described. The data
+    structure framework which holds information needed to translate
+    packets is encapsulated in alias_db.c.  Data is accessed by
+    function calls, so other segments of the program need not know
+    about the underlying data structures.  Alias_ftp.c contains
+    special code for modifying the ftp PORT command used to establish
+    data connections, while alias_irc.c do the same for IRC
+    DCC. Alias_util.c contains a few utility routines.
+
+    This software is placed into the public domain with no restrictions
+    on its distribution.
+
+    Version 1.0 August, 1996  (cjm)
+
+    Version 1.1 August 20, 1996  (cjm)
+        PPP host accepts incoming connections for ports 0 to 1023.
+        (Gary Roberts pointed out the need to handle incoming
+         connections.)
+
+    Version 1.2 September 7, 1996 (cjm)
+        Fragment handling error in alias_db.c corrected.
+        (Tom Torrance helped fix this problem.)
+
+    Version 1.4 September 16, 1996 (cjm)
+        - A more generalized method for handling incoming
+          connections, without the 0-1023 restriction, is
+          implemented in alias_db.c
+        - Improved ICMP support in alias.c.  Traceroute
+          packet streams can now be correctly aliased.
+        - TCP connection closing logic simplified in
+          alias.c and now allows for additional 1 minute
+          "grace period" after FIN or RST is observed.
+
+    Version 1.5 September 17, 1996 (cjm)
+        Corrected error in handling incoming UDP packets with 0 checksum.
+        (Tom Torrance helped fix this problem.)
+
+    Version 1.6 September 18, 1996 (cjm)
+        Simplified ICMP aliasing scheme.  Should now support
+        traceroute from Win95 as well as FreeBSD.
+
+    Version 1.7 January 9, 1997 (cjm)
+        - Out-of-order fragment handling.
+        - IP checksum error fixed for ftp transfers
+          from aliasing host.
+        - Integer return codes added to all
+          aliasing/de-aliasing functions.
+        - Some obsolete comments cleaned up.
+        - Differential checksum computations for
+          IP header (TCP, UDP and ICMP were already
+          differential).
+
+    Version 2.1 May 1997 (cjm)
+        - Added support for outgoing ICMP error
+          messages.
+        - Added two functions PacketAliasIn2()
+          and PacketAliasOut2() for dynamic address
+          control (e.g. round-robin allocation of
+          incoming packets).
+
+    Version 2.2 July 1997 (cjm)
+        - Rationalized API function names to begin
+          with "PacketAlias..."
+        - Eliminated PacketAliasIn2() and
+          PacketAliasOut2() as poorly conceived.
+
+    Version 2.3 Dec 1998 (dillon)
+	- Major bounds checking additions, see FreeBSD/CVS
+
+    See HISTORY file for additional revisions.
+
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+
+#ifndef IPPROTO_GRE
+#define IPPROTO_GRE 47
+#endif
+
+#include "alias_local.h"
+#include "alias.h"
+
+#define NETBIOS_NS_PORT_NUMBER 137
+#define NETBIOS_DGM_PORT_NUMBER 138
+#define FTP_CONTROL_PORT_NUMBER 21
+#define IRC_CONTROL_PORT_NUMBER_1 6667
+#define IRC_CONTROL_PORT_NUMBER_2 6668
+#define CUSEEME_PORT_NUMBER 7648
+
+
+
+
+/* TCP Handling Routines
+
+    TcpMonitorIn()  -- These routines monitor TCP connections, and
+    TcpMonitorOut()    delete a link when a connection is closed.
+
+These routines look for SYN, ACK and RST flags to determine when TCP
+connections open and close.  When a TCP connection closes, the data
+structure containing packet aliasing information is deleted after
+a timeout period.
+*/
+
+/* Local prototypes */
+static void TcpMonitorIn(struct ip *, struct alias_link *);
+
+static void TcpMonitorOut(struct ip *, struct alias_link *);
+
+
+static void
+TcpMonitorIn(struct ip *pip, struct alias_link *link)
+{
+    struct tcphdr *tc;
+
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+    switch (GetStateIn(link))
+    {
+        case ALIAS_TCP_STATE_NOT_CONNECTED:
+            if (tc->th_flags & TH_SYN)
+                SetStateIn(link, ALIAS_TCP_STATE_CONNECTED);
+            break;
+        case ALIAS_TCP_STATE_CONNECTED:
+            if (tc->th_flags & TH_FIN
+                || tc->th_flags & TH_RST)
+                SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
+            break;
+    }
+}
+
+static void
+TcpMonitorOut(struct ip *pip, struct alias_link *link)
+{
+    struct tcphdr *tc;
+
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+     
+    switch (GetStateOut(link))
+    {
+        case ALIAS_TCP_STATE_NOT_CONNECTED:
+            if (tc->th_flags & TH_SYN)
+                SetStateOut(link, ALIAS_TCP_STATE_CONNECTED);
+            break;
+        case ALIAS_TCP_STATE_CONNECTED:
+            if (tc->th_flags & TH_FIN
+                || tc->th_flags & TH_RST)
+                SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
+            break;
+    }
+}
+
+
+
+
+
+/* Protocol Specific Packet Aliasing Routines 
+
+    IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2(), IcmpAliasIn3()
+    IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2(), IcmpAliasOut3()
+    UdpAliasIn(), UdpAliasOut()
+    TcpAliasIn(), TcpAliasOut()
+
+These routines handle protocol specific details of packet aliasing.
+One may observe a certain amount of repetitive arithmetic in these
+functions, the purpose of which is to compute a revised checksum
+without actually summing over the entire data packet, which could be
+unnecessarily time consuming.
+
+The purpose of the packet aliasing routines is to replace the source
+address of the outgoing packet and then correctly put it back for
+any incoming packets.  For TCP and UDP, ports are also re-mapped.
+
+For ICMP echo/timestamp requests and replies, the following scheme
+is used: the id number is replaced by an alias for the outgoing
+packet.
+
+ICMP error messages are handled by looking at the IP fragment
+in the data section of the message.
+
+For TCP and UDP protocols, a port number is chosen for an outgoing
+packet, and then incoming packets are identified by IP address and
+port numbers.  For TCP packets, there is additional logic in the event
+that sequence and ack numbers have been altered (as is the case for
+FTP data port commands).
+
+The port numbers used by the packet aliasing module are not true
+ports in the Unix sense.  No sockets are actually bound to ports.
+They are more correctly thought of as placeholders.
+
+All packets go through the aliasing mechanism, whether they come from
+the gateway machine or other machines on a local area network.
+*/
+
+
+/* Local prototypes */
+static int IcmpAliasIn1(struct ip *);
+static int IcmpAliasIn2(struct ip *);
+static int IcmpAliasIn3(struct ip *);
+static int IcmpAliasIn (struct ip *);
+
+static int IcmpAliasOut1(struct ip *);
+static int IcmpAliasOut2(struct ip *);
+static int IcmpAliasOut3(struct ip *);
+static int IcmpAliasOut (struct ip *);
+
+static int UdpAliasOut(struct ip *);
+static int UdpAliasIn (struct ip *);
+
+static int TcpAliasOut(struct ip *, int);
+static int TcpAliasIn (struct ip *);
+
+
+static int
+IcmpAliasIn1(struct ip *pip)
+{
+/*
+    De-alias incoming echo and timestamp replies
+*/
+    struct alias_link *link;
+    struct icmp *ic;
+
+    ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+
+/* Get source address from ICMP data field and restore original data */
+    link = FindIcmpIn(pip->ip_src, pip->ip_dst, ic->icmp_id);
+    if (link != NULL)
+    {
+        u_short original_id;
+        int accumulate;
+
+        original_id = GetOriginalPort(link);
+
+/* Adjust ICMP checksum */
+        accumulate  = ic->icmp_id;
+        accumulate -= original_id;
+        ADJUST_CHECKSUM(accumulate, ic->icmp_cksum)
+
+/* Put original sequence number back in */
+        ic->icmp_id = original_id;
+
+/* Put original address back into IP header */
+        {
+            struct in_addr original_address;
+
+            original_address = GetOriginalAddress(link);
+            DifferentialChecksum(&pip->ip_sum,
+                                 (u_short *) &original_address,
+                                 (u_short *) &pip->ip_dst,
+                                 2);
+            pip->ip_dst = original_address;
+        }
+
+        return(PKT_ALIAS_OK);
+    }
+    return(PKT_ALIAS_IGNORED);
+}
+
+static int
+IcmpAliasIn2(struct ip *pip)
+{
+/*
+    Alias incoming ICMP error messages containing
+    IP header and first 64 bits of datagram.
+*/
+    struct ip *ip;
+    struct icmp *ic, *ic2;
+    struct udphdr *ud;
+    struct tcphdr *tc;
+    struct alias_link *link;
+
+    ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+    ip = (struct ip *) ic->icmp_data;
+
+    ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2));
+    tc = (struct tcphdr *) ud;
+    ic2 = (struct icmp *) ud;
+
+    if (ip->ip_p == IPPROTO_UDP)
+        link = FindUdpTcpIn(ip->ip_dst, ip->ip_src,
+                            ud->uh_dport, ud->uh_sport,
+                            IPPROTO_UDP);
+    else if (ip->ip_p == IPPROTO_TCP)
+        link = FindUdpTcpIn(ip->ip_dst, ip->ip_src,
+                            tc->th_dport, tc->th_sport,
+                            IPPROTO_TCP);
+    else if (ip->ip_p == IPPROTO_ICMP) {
+        if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP)
+            link = FindIcmpIn(ip->ip_dst, ip->ip_src, ic2->icmp_id);
+         else
+            link = NULL;
+    } else
+        link = NULL;
+
+    if (link != NULL)
+    {
+        if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP)
+        {
+            u_short *sptr;
+            int accumulate;
+            struct in_addr original_address;
+            u_short original_port;
+
+            original_address = GetOriginalAddress(link);
+            original_port = GetOriginalPort(link);
+    
+/* Adjust ICMP checksum */
+            sptr = (u_short *) &(ip->ip_src);
+            accumulate  = *sptr++;
+            accumulate += *sptr;
+            sptr = (u_short *) &original_address;
+            accumulate -= *sptr++;
+            accumulate -= *sptr;
+            accumulate += ud->uh_sport;
+            accumulate -= original_port;
+            ADJUST_CHECKSUM(accumulate, ic->icmp_cksum)
+
+/* Un-alias address in IP header */
+            DifferentialChecksum(&pip->ip_sum,
+                                 (u_short *) &original_address,
+                                 (u_short *) &pip->ip_dst,
+                                 2);
+            pip->ip_dst = original_address;
+
+/* Un-alias address and port number of original IP packet
+fragment contained in ICMP data section */
+            ip->ip_src = original_address;
+            ud->uh_sport = original_port; 
+        }
+        else if (pip->ip_p == IPPROTO_ICMP)
+        {
+            u_short *sptr;
+            int accumulate;
+            struct in_addr original_address;
+            u_short original_id;
+
+            original_address = GetOriginalAddress(link);
+            original_id = GetOriginalPort(link);
+
+/* Adjust ICMP checksum */
+            sptr = (u_short *) &(ip->ip_src);
+            accumulate  = *sptr++;
+            accumulate += *sptr;
+            sptr = (u_short *) &original_address;
+            accumulate -= *sptr++;
+            accumulate -= *sptr;
+            accumulate += ic2->icmp_id;
+            accumulate -= original_id;
+            ADJUST_CHECKSUM(accumulate, ic->icmp_cksum)
+
+/* Un-alias address in IP header */
+            DifferentialChecksum(&pip->ip_sum,
+                                 (u_short *) &original_address,
+                                 (u_short *) &pip->ip_dst,
+                                 2);
+            pip->ip_dst = original_address;
+
+/* Un-alias address of original IP packet and seqence number of 
+   embedded icmp datagram */
+            ip->ip_src = original_address;
+            ic2->icmp_id = original_id;
+        }
+        return(PKT_ALIAS_OK);
+    }
+    return(PKT_ALIAS_IGNORED);
+}
+
+static int
+IcmpAliasIn3(struct ip *pip)
+{
+    struct in_addr original_address;
+
+    original_address = FindOriginalAddress(pip->ip_dst);
+    DifferentialChecksum(&pip->ip_sum,
+                         (u_short *) &original_address,
+                         (u_short *) &pip->ip_dst,
+                         2);
+    pip->ip_dst = original_address;
+
+    return PKT_ALIAS_OK;
+}
+
+
+static int
+IcmpAliasIn(struct ip *pip)
+{
+    int iresult;
+    struct icmp *ic;
+
+/* Return if proxy-only mode is enabled */
+    if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+        return PKT_ALIAS_OK;
+
+    ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+
+    iresult = PKT_ALIAS_IGNORED;
+    switch (ic->icmp_type)
+    {
+        case ICMP_ECHOREPLY:
+        case ICMP_TSTAMPREPLY:
+            if (ic->icmp_code == 0)
+            {
+                iresult = IcmpAliasIn1(pip);
+            }
+            break;
+        case ICMP_UNREACH:
+        case ICMP_SOURCEQUENCH:
+        case ICMP_TIMXCEED:
+        case ICMP_PARAMPROB:
+            iresult = IcmpAliasIn2(pip);
+            break;
+        case ICMP_ECHO:
+        case ICMP_TSTAMP:
+            iresult = IcmpAliasIn3(pip);
+            break;
+    }
+    return(iresult);
+}
+
+
+static int
+IcmpAliasOut1(struct ip *pip)
+{
+/*
+    Alias ICMP echo and timestamp packets
+*/
+    struct alias_link *link;
+    struct icmp *ic;
+
+    ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+
+/* Save overwritten data for when echo packet returns */
+    link = FindIcmpOut(pip->ip_src, pip->ip_dst, ic->icmp_id);
+    if (link != NULL)
+    {
+        u_short alias_id;
+        int accumulate;
+
+        alias_id = GetAliasPort(link);
+
+/* Since data field is being modified, adjust ICMP checksum */
+        accumulate  = ic->icmp_id;
+        accumulate -= alias_id;
+        ADJUST_CHECKSUM(accumulate, ic->icmp_cksum)
+
+/* Alias sequence number */
+        ic->icmp_id = alias_id;
+
+/* Change source address */
+        {
+            struct in_addr alias_address;
+
+            alias_address = GetAliasAddress(link);
+            DifferentialChecksum(&pip->ip_sum,
+                                 (u_short *) &alias_address,
+                                 (u_short *) &pip->ip_src,
+                                 2);
+            pip->ip_src = alias_address;
+        }
+
+        return(PKT_ALIAS_OK);
+    }
+    return(PKT_ALIAS_IGNORED);
+}
+
+
+static int
+IcmpAliasOut2(struct ip *pip)
+{
+/*
+    Alias outgoing ICMP error messages containing
+    IP header and first 64 bits of datagram.
+*/
+    struct in_addr alias_addr;
+    struct ip *ip;
+    struct icmp *ic;
+
+    ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+    ip = (struct ip *) ic->icmp_data;
+
+    alias_addr = FindAliasAddress(ip->ip_src);
+
+/* Alias destination address in IP fragment */
+    DifferentialChecksum(&ic->icmp_cksum,
+                         (u_short *) &alias_addr,
+                         (u_short *) &ip->ip_dst,
+                         2);
+    ip->ip_dst = alias_addr;
+
+/* alias source address in IP header */
+    DifferentialChecksum(&pip->ip_sum,
+                         (u_short *) &alias_addr,
+                         (u_short *) &pip->ip_src,
+                         2);
+    pip->ip_src = alias_addr;
+
+    return PKT_ALIAS_OK;
+}
+
+
+static int
+IcmpAliasOut3(struct ip *pip)
+{
+/*
+  Handle outgoing echo and timestamp replies.  The
+  only thing which is done in this case is to alias
+  the source IP address of the packet.
+*/
+    struct in_addr alias_addr;
+
+    alias_addr = FindAliasAddress(pip->ip_src);
+    DifferentialChecksum(&pip->ip_sum,
+                         (u_short *) &alias_addr,
+                         (u_short *) &pip->ip_src,
+                         2);
+    pip->ip_src = alias_addr;
+
+    return PKT_ALIAS_OK;
+}
+
+
+static int
+IcmpAliasOut(struct ip *pip)
+{
+    int iresult;
+    struct icmp *ic;
+
+/* Return if proxy-only mode is enabled */
+    if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+        return PKT_ALIAS_OK;
+
+    ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+
+    iresult = PKT_ALIAS_IGNORED;
+    switch (ic->icmp_type)
+    {
+        case ICMP_ECHO:
+        case ICMP_TSTAMP:
+            if (ic->icmp_code == 0)
+            {
+                iresult = IcmpAliasOut1(pip);
+            }
+            break;
+        case ICMP_UNREACH:
+        case ICMP_SOURCEQUENCH:
+        case ICMP_TIMXCEED:
+        case ICMP_PARAMPROB:
+            iresult = IcmpAliasOut2(pip);
+            break;
+        case ICMP_ECHOREPLY:
+        case ICMP_TSTAMPREPLY:
+            iresult = IcmpAliasOut3(pip);
+    }
+    return(iresult);
+}
+
+
+
+static int
+PptpAliasIn(struct ip *pip)
+{
+/*
+  Handle incoming PPTP packets. The
+  only thing which is done in this case is to alias
+  the dest IP address of the packet to our inside
+  machine.
+*/
+    struct in_addr alias_addr;
+
+    if (!GetPptpAlias (&alias_addr))
+	return PKT_ALIAS_IGNORED;
+
+    if (pip->ip_src.s_addr != alias_addr.s_addr) {
+
+	    DifferentialChecksum(&pip->ip_sum,
+				 (u_short *) &alias_addr,
+				 (u_short *) &pip->ip_dst,
+				 2);
+	    pip->ip_dst = alias_addr;
+    }
+
+    return PKT_ALIAS_OK;
+}
+
+
+static int
+PptpAliasOut(struct ip *pip)
+{
+/*
+  Handle outgoing PPTP packets. The
+  only thing which is done in this case is to alias
+  the source IP address of the packet.
+*/
+    struct in_addr alias_addr;
+
+    if (!GetPptpAlias (&alias_addr))
+	return PKT_ALIAS_IGNORED;
+
+    if (pip->ip_src.s_addr == alias_addr.s_addr) {
+
+	    alias_addr = FindAliasAddress(pip->ip_src);
+	    DifferentialChecksum(&pip->ip_sum,
+				 (u_short *) &alias_addr,
+				 (u_short *) &pip->ip_src,
+				 2);
+	    pip->ip_src = alias_addr;
+    }
+
+    return PKT_ALIAS_OK;
+}
+
+
+
+static int
+UdpAliasIn(struct ip *pip)
+{
+    struct udphdr *ud;
+    struct alias_link *link;
+
+/* Return if proxy-only mode is enabled */
+    if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+        return PKT_ALIAS_OK;
+
+    ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+    link = FindUdpTcpIn(pip->ip_src, pip->ip_dst,
+                        ud->uh_sport, ud->uh_dport,
+                        IPPROTO_UDP);
+    if (link != NULL)
+    {
+        struct in_addr alias_address;
+        struct in_addr original_address;
+        u_short alias_port;
+        int accumulate;
+        u_short *sptr;
+	int r = 0;
+
+        alias_address = GetAliasAddress(link);
+        original_address = GetOriginalAddress(link);
+        alias_port = ud->uh_dport;
+        ud->uh_dport = GetOriginalPort(link);
+
+/* If NETBIOS Datagram, It should be alias address in UDP Data, too */
+		if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
+         || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER )
+		{
+            r = AliasHandleUdpNbt(pip, link, &original_address, ud->uh_dport);
+		} else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
+         || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER )
+		{
+            r = AliasHandleUdpNbtNS(pip, link, 
+								&alias_address,
+								&alias_port,
+								&original_address, 
+								&ud->uh_dport );
+		}
+
+        if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
+            AliasHandleCUSeeMeIn(pip, original_address);
+
+/* If UDP checksum is not zero, then adjust since destination port */
+/* is being unaliased and destination port is being altered.       */
+        if (ud->uh_sum != 0)
+        {
+            accumulate  = alias_port;
+            accumulate -= ud->uh_dport;
+            sptr = (u_short *) &alias_address;
+            accumulate += *sptr++;
+            accumulate += *sptr;
+            sptr = (u_short *) &original_address;
+            accumulate -= *sptr++;
+            accumulate -= *sptr;
+            ADJUST_CHECKSUM(accumulate, ud->uh_sum)
+        }
+
+/* Restore original IP address */
+        DifferentialChecksum(&pip->ip_sum,
+                             (u_short *) &original_address,
+                             (u_short *) &pip->ip_dst,
+                             2);
+        pip->ip_dst = original_address;
+
+	/*
+	 * If we cannot figure out the packet, ignore it.
+	 */
+	if (r < 0)
+	    return(PKT_ALIAS_IGNORED);
+	else
+	    return(PKT_ALIAS_OK);
+    }
+    return(PKT_ALIAS_IGNORED);
+}
+
+static int
+UdpAliasOut(struct ip *pip)
+{
+    struct udphdr *ud;
+    struct alias_link *link;
+
+/* Return if proxy-only mode is enabled */
+    if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+        return PKT_ALIAS_OK;
+
+    ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+    link = FindUdpTcpOut(pip->ip_src, pip->ip_dst,
+                         ud->uh_sport, ud->uh_dport,
+                         IPPROTO_UDP);
+    if (link != NULL)
+    {
+        u_short alias_port;
+        struct in_addr alias_address;
+
+        alias_address = GetAliasAddress(link);
+        alias_port = GetAliasPort(link);
+
+        if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
+            AliasHandleCUSeeMeOut(pip, link);
+
+/* If NETBIOS Datagram, It should be alias address in UDP Data, too */
+		if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
+         || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER )
+		{
+            AliasHandleUdpNbt(pip, link, &alias_address, alias_port);
+		} else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
+         || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER )
+		{
+            AliasHandleUdpNbtNS(pip, link,
+								&pip->ip_src,
+								&ud->uh_sport,
+							    &alias_address,
+							 	&alias_port); 
+		}
+
+/* If UDP checksum is not zero, adjust since source port is */
+/* being aliased and source address is being altered        */
+        if (ud->uh_sum != 0)
+        {
+            int accumulate;
+            u_short *sptr;
+
+            accumulate  = ud->uh_sport;
+            accumulate -= alias_port;
+            sptr = (u_short *) &(pip->ip_src);
+            accumulate += *sptr++;
+            accumulate += *sptr;
+            sptr = (u_short *) &alias_address;
+            accumulate -= *sptr++;
+            accumulate -= *sptr;
+            ADJUST_CHECKSUM(accumulate, ud->uh_sum)
+        }
+
+/* Put alias port in UDP header */
+        ud->uh_sport = alias_port;
+
+/* Change source address */
+        DifferentialChecksum(&pip->ip_sum,
+                             (u_short *) &alias_address,
+                             (u_short *) &pip->ip_src,
+                             2);
+        pip->ip_src = alias_address;
+
+        return(PKT_ALIAS_OK);
+    }
+    return(PKT_ALIAS_IGNORED);
+}
+
+
+
+static int
+TcpAliasIn(struct ip *pip)
+{
+    struct tcphdr *tc;
+    struct alias_link *link;
+
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+    link = FindUdpTcpIn(pip->ip_src, pip->ip_dst,
+                        tc->th_sport, tc->th_dport,
+                        IPPROTO_TCP);
+    if (link != NULL)
+    {
+        struct in_addr alias_address;
+        struct in_addr original_address;
+        struct in_addr proxy_address;
+        u_short alias_port;
+        u_short proxy_port;
+        int accumulate;
+        u_short *sptr;
+
+        alias_address = GetAliasAddress(link);
+        original_address = GetOriginalAddress(link);
+        proxy_address = GetProxyAddress(link);
+        alias_port = tc->th_dport;
+        tc->th_dport = GetOriginalPort(link);
+        proxy_port = GetProxyPort(link);
+
+/* Adjust TCP checksum since destination port is being unaliased */
+/* and destination port is being altered.                        */
+        accumulate  = alias_port;
+        accumulate -= tc->th_dport;
+        sptr = (u_short *) &alias_address;
+        accumulate += *sptr++;
+        accumulate += *sptr;
+        sptr = (u_short *) &original_address;
+        accumulate -= *sptr++;
+        accumulate -= *sptr;
+
+/* If this is a proxy, then modify the tcp source port  and
+   checksum accumulation */
+        if (proxy_port != 0)
+        {
+            accumulate += tc->th_sport;
+            tc->th_sport = proxy_port;
+            accumulate -= tc->th_sport;
+
+            sptr = (u_short *) &pip->ip_src;
+            accumulate += *sptr++;
+            accumulate += *sptr;
+            sptr = (u_short *) &proxy_address;
+            accumulate -= *sptr++;
+            accumulate -= *sptr;
+        }
+
+/* See if ack number needs to be modified */
+        if (GetAckModified(link) == 1)
+        {
+            int delta;
+
+            delta = GetDeltaAckIn(pip, link);
+            if (delta != 0)
+            {
+                sptr = (u_short *) &tc->th_ack;
+                accumulate += *sptr++;
+                accumulate += *sptr;
+                tc->th_ack = htonl(ntohl(tc->th_ack) - delta);
+                sptr = (u_short *) &tc->th_ack;
+                accumulate -= *sptr++;
+                accumulate -= *sptr;
+            }
+        }
+
+        ADJUST_CHECKSUM(accumulate, tc->th_sum);
+
+/* Restore original IP address */
+        sptr = (u_short *) &pip->ip_dst;
+        accumulate  = *sptr++;
+        accumulate += *sptr;
+        pip->ip_dst = original_address;
+        sptr = (u_short *) &pip->ip_dst;
+        accumulate -= *sptr++;
+        accumulate -= *sptr;
+
+/* If this is a transparent proxy packet, then modify the source
+   address */
+        if (proxy_address.s_addr != 0)
+        {
+            sptr = (u_short *) &pip->ip_src;
+            accumulate += *sptr++;
+            accumulate += *sptr;
+            pip->ip_src = proxy_address;
+            sptr = (u_short *) &pip->ip_src;
+            accumulate -= *sptr++;
+            accumulate -= *sptr;
+        }
+
+        ADJUST_CHECKSUM(accumulate, pip->ip_sum);
+
+/* Monitor TCP connection state */
+        TcpMonitorIn(pip, link);
+
+        return(PKT_ALIAS_OK);
+    }
+    return(PKT_ALIAS_IGNORED);
+}
+
+static int
+TcpAliasOut(struct ip *pip, int maxpacketsize)
+{
+    int proxy_type;
+    u_short dest_port;
+    u_short proxy_server_port;
+    struct in_addr dest_address;
+    struct in_addr proxy_server_address;
+    struct tcphdr *tc;
+    struct alias_link *link;
+
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+    proxy_type = ProxyCheck(pip, &proxy_server_address, &proxy_server_port);
+
+    if (proxy_type == 0 && (packetAliasMode & PKT_ALIAS_PROXY_ONLY))
+        return PKT_ALIAS_OK;
+
+/* If this is a transparent proxy, save original destination,
+   then alter the destination and adust checksums */
+    dest_port = tc->th_dport;
+    dest_address = pip->ip_dst;
+    if (proxy_type != 0)
+    {
+        int accumulate;
+        u_short *sptr;
+
+        accumulate = tc->th_dport;
+        tc->th_dport = proxy_server_port;
+        accumulate -= tc->th_dport;
+
+        sptr = (u_short *) &(pip->ip_dst);
+        accumulate += *sptr++;
+        accumulate += *sptr;
+        sptr = (u_short *) &proxy_server_address;
+        accumulate -= *sptr++;
+        accumulate -= *sptr;
+
+        ADJUST_CHECKSUM(accumulate, tc->th_sum);
+
+        sptr = (u_short *) &(pip->ip_dst);
+        accumulate  = *sptr++;
+        accumulate += *sptr;
+        pip->ip_dst = proxy_server_address;
+        sptr = (u_short *) &(pip->ip_dst);
+        accumulate -= *sptr++;
+        accumulate -= *sptr;
+
+        ADJUST_CHECKSUM(accumulate, pip->ip_sum);
+    }
+
+    link = FindUdpTcpOut(pip->ip_src, pip->ip_dst,
+                         tc->th_sport, tc->th_dport,
+                         IPPROTO_TCP);
+    if (link !=NULL)
+    {
+        u_short alias_port;
+        struct in_addr alias_address;
+        int accumulate;
+        u_short *sptr;
+
+/* Save original destination address, if this is a proxy packet.
+   Also modify packet to include destination encoding. */
+        if (proxy_type != 0)
+        {
+            SetProxyPort(link, dest_port);
+            SetProxyAddress(link, dest_address);
+            ProxyModify(link, pip, maxpacketsize, proxy_type);
+        }
+
+/* Get alias address and port */
+        alias_port = GetAliasPort(link);
+        alias_address = GetAliasAddress(link);
+
+/* Monitor tcp connection state */
+        TcpMonitorOut(pip, link);
+
+/* Special processing for IP encoding protocols */
+        if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER
+         || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER)
+            AliasHandleFtpOut(pip, link, maxpacketsize);
+        if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1
+         || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2)
+            AliasHandleIrcOut(pip, link, maxpacketsize);
+
+/* Adjust TCP checksum since source port is being aliased */
+/* and source address is being altered                    */
+        accumulate  = tc->th_sport;
+        tc->th_sport = alias_port;
+        accumulate -= tc->th_sport;
+
+        sptr = (u_short *) &(pip->ip_src);
+        accumulate += *sptr++;
+        accumulate += *sptr;
+        sptr = (u_short *) &alias_address;
+        accumulate -= *sptr++;
+        accumulate -= *sptr;
+
+/* Modify sequence number if necessary */
+        if (GetAckModified(link) == 1)
+        {
+            int delta;
+
+            delta = GetDeltaSeqOut(pip, link);
+            if (delta != 0)
+            {
+                sptr = (u_short *) &tc->th_seq;
+                accumulate += *sptr++;
+                accumulate += *sptr;
+                tc->th_seq = htonl(ntohl(tc->th_seq) + delta);
+                sptr = (u_short *) &tc->th_seq;
+                accumulate -= *sptr++;
+                accumulate -= *sptr;
+            }
+        }
+
+        ADJUST_CHECKSUM(accumulate, tc->th_sum)
+
+/* Change source address */
+        sptr = (u_short *) &(pip->ip_src);
+        accumulate  = *sptr++;
+        accumulate += *sptr;
+        pip->ip_src = alias_address;
+        sptr = (u_short *) &(pip->ip_src);
+        accumulate -= *sptr++;
+        accumulate -= *sptr;
+
+        ADJUST_CHECKSUM(accumulate, pip->ip_sum)
+
+        return(PKT_ALIAS_OK);
+    }
+    return(PKT_ALIAS_IGNORED);
+}
+
+
+
+
+/* Fragment Handling
+
+    FragmentIn()
+    FragmentOut()
+
+The packet aliasing module has a limited ability for handling IP
+fragments.  If the ICMP, TCP or UDP header is in the first fragment
+received, then the id number of the IP packet is saved, and other
+fragments are identified according to their ID number and IP address
+they were sent from.  Pointers to unresolved fragments can also be
+saved and recalled when a header fragment is seen.
+*/
+
+/* Local prototypes */
+static int FragmentIn(struct ip *);
+static int FragmentOut(struct ip *);
+
+
+static int
+FragmentIn(struct ip *pip)
+{
+    struct alias_link *link;
+
+    link = FindFragmentIn2(pip->ip_src, pip->ip_dst, pip->ip_id);
+    if (link != NULL)
+    {
+        struct in_addr original_address;
+
+        GetFragmentAddr(link, &original_address);
+        DifferentialChecksum(&pip->ip_sum,
+                             (u_short *) &original_address,
+                             (u_short *) &pip->ip_dst,
+                             2);
+        pip->ip_dst = original_address; 
+   
+        return(PKT_ALIAS_OK);
+    }
+    return(PKT_ALIAS_UNRESOLVED_FRAGMENT);
+}
+
+
+static int
+FragmentOut(struct ip *pip)
+{
+    struct in_addr alias_address;
+
+    alias_address = FindAliasAddress(pip->ip_src);
+    DifferentialChecksum(&pip->ip_sum,
+                         (u_short *) &alias_address,
+                         (u_short *) &pip->ip_src,
+                          2);
+    pip->ip_src = alias_address;
+
+    return(PKT_ALIAS_OK);
+}
+
+
+
+
+
+
+/* Outside World Access
+
+        PacketAliasSaveFragment()
+        PacketAliasGetFragment()
+        PacketAliasFragmentIn()
+        PacketAliasIn()
+        PacketAliasOut()
+
+(prototypes in alias.h)
+*/
+
+
+int
+PacketAliasSaveFragment(char *ptr)
+{
+    int iresult;
+    struct alias_link *link;
+    struct ip *pip;
+
+    pip = (struct ip *) ptr;
+    link = AddFragmentPtrLink(pip->ip_src, pip->ip_id);
+    iresult = PKT_ALIAS_ERROR;
+    if (link != NULL)
+    {
+        SetFragmentPtr(link, ptr);
+        iresult = PKT_ALIAS_OK;
+    }
+    return(iresult);
+}
+
+
+char *
+PacketAliasGetFragment(char *ptr)
+{
+    struct alias_link *link;
+    char *fptr;
+    struct ip *pip;
+
+    pip = (struct ip *) ptr;
+    link = FindFragmentPtr(pip->ip_src, pip->ip_id);
+    if (link != NULL)
+    {
+        GetFragmentPtr(link, &fptr);
+        SetFragmentPtr(link, NULL);
+        SetExpire(link, 0); /* Deletes link */
+
+        return(fptr);
+    }
+    else
+    {
+        return(NULL);
+    }
+}
+
+
+void
+PacketAliasFragmentIn(char *ptr,          /* Points to correctly de-aliased
+                                             header fragment */
+                      char *ptr_fragment  /* Points to fragment which must
+                                             be de-aliased   */
+                     )
+{
+    struct ip *pip;
+    struct ip *fpip;
+
+    pip = (struct ip *) ptr;
+    fpip = (struct ip *) ptr_fragment;
+
+    DifferentialChecksum(&fpip->ip_sum,
+                         (u_short *) &pip->ip_dst,
+                         (u_short *) &fpip->ip_dst,
+                         2);
+    fpip->ip_dst = pip->ip_dst;
+}
+
+
+int
+PacketAliasIn(char *ptr, int maxpacketsize)
+{
+    struct in_addr alias_addr;
+    struct ip *pip;
+    int iresult;
+
+    if (packetAliasMode & PKT_ALIAS_REVERSE)
+        return PacketAliasOut(ptr, maxpacketsize);
+
+    HouseKeeping();
+    ClearCheckNewLink();
+    pip = (struct ip *) ptr;
+    alias_addr = pip->ip_dst;
+        
+    /* Defense against mangled packets */
+    if (ntohs(pip->ip_len) > maxpacketsize
+     || (pip->ip_hl<<2) > maxpacketsize)
+        return PKT_ALIAS_IGNORED;
+        
+    iresult = PKT_ALIAS_IGNORED;
+    if ( (ntohs(pip->ip_off) & IP_OFFMASK) == 0 )
+    {
+        switch (pip->ip_p)
+        {
+            case IPPROTO_ICMP:
+                iresult = IcmpAliasIn(pip);
+                break;
+            case IPPROTO_UDP:
+                iresult = UdpAliasIn(pip);
+                break;
+            case IPPROTO_TCP:
+                iresult = TcpAliasIn(pip);
+                break;
+            case IPPROTO_GRE:
+		iresult = PptpAliasIn(pip);
+                break;
+        }
+
+        if (ntohs(pip->ip_off) & IP_MF)
+        {
+            struct alias_link *link;
+
+            link = FindFragmentIn1(pip->ip_src, alias_addr, pip->ip_id);
+            if (link != NULL)
+            {
+                iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT;
+                SetFragmentAddr(link, pip->ip_dst);
+            }
+            else
+            {
+                iresult = PKT_ALIAS_ERROR;
+            }
+        }
+    }
+    else
+    {
+        iresult = FragmentIn(pip);
+    }
+
+    return(iresult);
+}
+
+
+
+/* Unregistered address ranges */
+
+/* 10.0.0.0   ->   10.255.255.255 */
+#define UNREG_ADDR_A_LOWER 0x0a000000
+#define UNREG_ADDR_A_UPPER 0x0affffff
+
+/* 172.16.0.0  ->  172.31.255.255 */
+#define UNREG_ADDR_B_LOWER 0xac100000
+#define UNREG_ADDR_B_UPPER 0xac1fffff
+
+/* 192.168.0.0 -> 192.168.255.255 */
+#define UNREG_ADDR_C_LOWER 0xc0a80000
+#define UNREG_ADDR_C_UPPER 0xc0a8ffff
+
+int
+PacketAliasOut(char *ptr,           /* valid IP packet */
+               int  maxpacketsize   /* How much the packet data may grow
+                                       (FTP and IRC inline changes) */
+              )
+{
+    int iresult;
+    struct in_addr addr_save;
+    struct ip *pip;
+
+    if (packetAliasMode & PKT_ALIAS_REVERSE)
+        return PacketAliasIn(ptr, maxpacketsize);
+
+    HouseKeeping();
+    ClearCheckNewLink();
+    pip = (struct ip *) ptr;
+
+    /* Defense against mangled packets */
+    if (ntohs(pip->ip_len) > maxpacketsize
+     || (pip->ip_hl<<2) > maxpacketsize)
+        return PKT_ALIAS_IGNORED;
+
+    addr_save = GetDefaultAliasAddress();
+    if (packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY)
+    {
+        unsigned int addr;
+        int iclass;
+
+        iclass = 0;
+        addr = ntohl(pip->ip_src.s_addr);
+        if      (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER)
+            iclass = 3;
+        else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER)
+            iclass = 2;
+        else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER)
+            iclass = 1;
+
+        if (iclass == 0)
+        {
+            SetDefaultAliasAddress(pip->ip_src);
+        }
+    }
+
+    iresult = PKT_ALIAS_IGNORED;
+    if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0)
+    {
+        switch (pip->ip_p)
+        {
+            case IPPROTO_ICMP:
+                iresult = IcmpAliasOut(pip);
+                break;
+            case IPPROTO_UDP:
+                iresult = UdpAliasOut(pip);
+                break;
+            case IPPROTO_TCP:
+                iresult = TcpAliasOut(pip, maxpacketsize);
+                break;
+            case IPPROTO_GRE:
+		iresult = PptpAliasOut(pip);
+                break;
+        }
+    }
+    else
+    {
+        iresult = FragmentOut(pip);
+    }
+
+    SetDefaultAliasAddress(addr_save);
+    return(iresult);
+}
diff --git a/alias/alias.h b/alias/alias.h
new file mode 100644
index 0000000..4e0391f
--- /dev/null
+++ b/alias/alias.h
@@ -0,0 +1,166 @@
+/*lint -save -library Flexelint comment for external headers */
+
+/*
+    Alias.h defines the outside world interfaces for the packet
+    aliasing software.
+
+    This software is placed into the public domain with no restrictions
+    on its distribution.
+
+    $Id: alias.h,v 1.1.1.1 2000/01/11 01:48:42 wsanchez Exp $
+*/
+
+
+#ifndef _ALIAS_H_
+#define _ALIAS_H_
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Alias link representative (incomplete struct) */
+struct alias_link;
+
+/* External interfaces (API) to packet aliasing engine */
+
+/* Initialization and Control */
+    extern void
+    PacketAliasInit(void);
+
+    extern void
+    PacketAliasUninit(void);
+
+    extern void
+    PacketAliasSetAddress(struct in_addr);
+
+    extern unsigned int
+    PacketAliasSetMode(unsigned int, unsigned int);
+
+#ifndef NO_FW_PUNCH
+    extern void
+    PacketAliasSetFWBase(unsigned int, unsigned int);
+#endif
+
+/* Packet Handling */
+    extern int
+    PacketAliasIn(char *, int maxpacketsize);
+
+    extern int
+    PacketAliasOut(char *, int maxpacketsize);
+
+/* Port and Address Redirection */
+    extern struct alias_link *
+    PacketAliasRedirectPort(struct in_addr, u_short, 
+                            struct in_addr, u_short,
+                            struct in_addr, u_short,
+                            u_char);
+
+    extern int
+    PacketAliasPptp(struct in_addr);
+
+
+    extern struct alias_link *
+    PacketAliasRedirectAddr(struct in_addr,
+                            struct in_addr);
+
+    extern void
+    PacketAliasRedirectDelete(struct alias_link *);
+
+/* Fragment Handling */
+    extern int
+    PacketAliasSaveFragment(char *);
+
+    extern char *
+    PacketAliasGetFragment(char *);
+
+    extern void 
+    PacketAliasFragmentIn(char *, char *);
+
+/* Miscellaneous Functions */
+    extern void
+    PacketAliasSetTarget(struct in_addr addr);
+
+    extern int
+    PacketAliasCheckNewLink(void);
+
+    extern u_short
+    PacketAliasInternetChecksum(u_short *, int);
+
+/* Transparent Proxying */
+    extern int
+    PacketAliasProxyRule(const char *);
+
+
+/********************** Mode flags ********************/
+/* Set these flags using SetPacketAliasMode() */
+
+/* If PKT_ALIAS_LOG is set, a message will be printed to
+	/var/log/alias.log every time a link is created or deleted.  This
+	is useful for debugging */
+#define PKT_ALIAS_LOG 0x01
+
+/* If PKT_ALIAS_DENY_INCOMING is set, then incoming connections (e.g.
+	to ftp, telnet or web servers will be prevented by the aliasing
+	mechanism.  */
+#define PKT_ALIAS_DENY_INCOMING 0x02
+
+/* If PKT_ALIAS_SAME_PORTS is set, packets will be attempted sent from
+	the same port as they originated on.  This allows eg rsh to work
+	*99% of the time*, but _not_ 100%.  (It will be slightly flakey
+	instead of not working at all.)  This mode bit is set by
+        PacketAliasInit(), so it is a default mode of operation. */
+#define PKT_ALIAS_SAME_PORTS 0x04
+
+/* If PKT_ALIAS_USE_SOCKETS is set, then when partially specified
+	links (e.g. destination port and/or address is zero), the packet
+	aliasing engine will attempt to allocate a socket for the aliasing
+	port it chooses.  This will avoid interference with the host
+	machine.  Fully specified links do not require this.  This bit
+        is set after a call to PacketAliasInit(), so it is a default
+        mode of operation.*/
+#define PKT_ALIAS_USE_SOCKETS 0x08
+
+/* If PKT_ALIAS_UNREGISTERED_ONLY is set, then only packets with with
+	unregistered source addresses will be aliased (along with those
+	of the ppp host maching itself.  Private addresses are those
+        in the following ranges:
+		10.0.0.0     ->   10.255.255.255
+		172.16.0.0   ->   172.31.255.255
+		192.168.0.0  ->   192.168.255.255  */
+#define PKT_ALIAS_UNREGISTERED_ONLY 0x10
+
+/* If PKT_ALIAS_RESET_ON_ADDR_CHANGE is set, then the table of dynamic
+	aliasing links will be reset whenever PacketAliasSetAddress()
+        changes the default aliasing address.  If the default aliasing
+        address is left unchanged by this functions call, then the
+        table of dynamic aliasing links will be left intact.  This
+        bit is set after a call to PacketAliasInit(). */
+#define PKT_ALIAS_RESET_ON_ADDR_CHANGE 0x20
+
+#ifndef NO_FW_PUNCH
+/* If PKT_ALIAS_PUNCH_FW is set, active FTP and IRC DCC connections
+   will create a 'hole' in the firewall to allow the transfers to
+   work.  Where (IPFW "line-numbers") the hole is created is
+   controlled by PacketAliasSetFWBase(base, size). The hole will be
+   attached to that particular alias_link, so when the link goes away
+   so do the hole.  */
+#define PKT_ALIAS_PUNCH_FW 0x40
+#endif
+
+/* If PKT_ALIAS_PROXY_ONLY is set, then NAT will be disabled and only
+      transparent proxying performed */
+#define PKT_ALIAS_PROXY_ONLY 0x40
+
+/* If PKT_ALIAS_REVERSE is set, the actions of PacketAliasIn()
+      and PacketAliasOut() are reversed */
+#define PKT_ALIAS_REVERSE 0x80
+
+/* Return Codes */
+#define PKT_ALIAS_ERROR -1
+#define PKT_ALIAS_OK 1
+#define PKT_ALIAS_IGNORED 2
+#define PKT_ALIAS_UNRESOLVED_FRAGMENT 3
+#define PKT_ALIAS_FOUND_HEADER_FRAGMENT 4
+
+#endif
+/*lint -restore */
diff --git a/alias/alias_cuseeme.c b/alias/alias_cuseeme.c
new file mode 100644
index 0000000..a78f041
--- /dev/null
+++ b/alias/alias_cuseeme.c
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
+ *                    with the aid of code written by
+ *                    Junichi SATOH <junichi@astec.co.jp> 1996, 1997.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$Id: alias_cuseeme.c,v 1.1.1.1 2000/01/11 01:48:42 wsanchez Exp $
+ */
+
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+
+#include "alias_local.h"
+
+/* CU-SeeMe Data Header */
+struct cu_header {
+    u_int16_t dest_family;
+    u_int16_t dest_port;
+    u_int32_t  dest_addr;
+    int16_t family;
+    u_int16_t port;
+    u_int32_t addr;
+    u_int32_t seq;
+    u_int16_t msg;
+    u_int16_t data_type;
+    u_int16_t packet_len;
+};
+
+/* Open Continue Header */
+struct oc_header {
+    u_int16_t client_count;    /* Number of client info structs */
+    u_int32_t seq_no;
+    char user_name[20];
+    char reserved[4];        /* flags, version stuff, etc */
+};
+
+/* client info structures */
+struct client_info {
+    u_int32_t address;          /* Client address */
+    char reserved[8];        /* Flags, pruning bitfield, packet counts etc */
+};
+
+void
+AliasHandleCUSeeMeOut(struct ip *pip, struct alias_link *link)
+{
+  struct udphdr *ud;
+
+  ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
+  if(ud->uh_ulen >= sizeof(struct cu_header)) {
+    struct cu_header *cu;
+    struct alias_link *cu_link;
+
+    cu = (struct cu_header *)(ud + 1);
+    if (cu->addr)
+      cu->addr = (u_int32_t)GetAliasAddress(link).s_addr;
+
+    cu_link = FindUdpTcpOut(pip->ip_src, GetDestAddress(link),
+                            ud->uh_dport, 0, IPPROTO_UDP);
+                         
+#ifndef NO_FW_PUNCH
+    if (cu_link)
+        PunchFWHole(cu_link);
+#endif
+  }
+}
+
+void
+AliasHandleCUSeeMeIn(struct ip *pip, struct in_addr original_addr)
+{
+  struct in_addr alias_addr;
+  struct udphdr *ud;
+  struct cu_header *cu;
+  struct oc_header *oc;
+  struct client_info *ci;
+  char *end;
+  int i;
+
+  alias_addr.s_addr = pip->ip_dst.s_addr;
+  ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
+  cu = (struct cu_header *)(ud + 1);
+  oc = (struct oc_header *)(cu + 1);
+  ci = (struct client_info *)(oc + 1);
+  end = (char *)cu + ud->uh_ulen;
+
+  if ((char *)oc <= end) {
+    if(cu->dest_addr)
+      cu->dest_addr = (u_int32_t)original_addr.s_addr;
+    if(ntohs(cu->data_type) == 101)
+      /* Find and change our address */
+      for(i = 0; (char *)(ci + 1) <= end && i < oc->client_count; i++, ci++)
+        if(ci->address == (u_int32_t)alias_addr.s_addr) {
+          ci->address = (u_int32_t)original_addr.s_addr;
+          break;
+        }
+  }
+}
diff --git a/alias/alias_db.c b/alias/alias_db.c
new file mode 100644
index 0000000..d01188e
--- /dev/null
+++ b/alias/alias_db.c
@@ -0,0 +1,2330 @@
+/*  -*- mode: c; tab-width: 8; c-basic-indent: 4; -*-
+    Alias_db.c encapsulates all data structures used for storing
+    packet aliasing data.  Other parts of the aliasing software
+    access data through functions provided in this file.
+
+    Data storage is based on the notion of a "link", which is
+    established for ICMP echo/reply packets, UDP datagrams and
+    TCP stream connections.  A link stores the original source
+    and destination addresses.  For UDP and TCP, it also stores
+    source and destination port numbers, as well as an alias
+    port number.  Links are also used to store information about
+    fragments.
+
+    There is a facility for sweeping through and deleting old
+    links as new packets are sent through.  A simple timeout is
+    used for ICMP and UDP links.  TCP links are left alone unless
+    there is an incomplete connection, in which case the link
+    can be deleted after a certain amount of time.
+
+
+    This software is placed into the public domain with no restrictions
+    on its distribution.
+
+    Initial version: August, 1996  (cjm)
+
+    Version 1.4: September 16, 1996 (cjm)
+        Facility for handling incoming links added.
+
+    Version 1.6: September 18, 1996 (cjm)
+        ICMP data handling simplified.
+
+    Version 1.7: January 9, 1997 (cjm)
+        Fragment handling simplified.
+        Saves pointers for unresolved fragments.
+        Permits links for unspecied remote ports
+          or unspecified remote addresses.
+        Fixed bug which did not properly zero port
+          table entries after a link was deleted.
+        Cleaned up some obsolete comments.
+
+    Version 1.8: January 14, 1997 (cjm)
+        Fixed data type error in StartPoint().
+        (This error did not exist prior to v1.7
+        and was discovered and fixed by Ari Suutari)
+
+    Version 1.9: February 1, 1997
+        Optionally, connections initiated from packet aliasing host
+        machine will will not have their port number aliased unless it
+        conflicts with an aliasing port already being used. (cjm)
+
+        All options earlier being #ifdef'ed now are available through
+        a new interface, SetPacketAliasMode().  This allow run time
+        control (which is now available in PPP+pktAlias through the
+        'alias' keyword). (ee)
+
+        Added ability to create an alias port without
+        either destination address or port specified.
+        port type = ALIAS_PORT_UNKNOWN_DEST_ALL (ee)
+
+        Removed K&R style function headers
+        and general cleanup. (ee)
+
+        Added packetAliasMode to replace compiler #defines's (ee)
+
+        Allocates sockets for partially specified
+        ports if ALIAS_USE_SOCKETS defined. (cjm)
+
+    Version 2.0: March, 1997
+        SetAliasAddress() will now clean up alias links
+        if the aliasing address is changed. (cjm)
+
+        PacketAliasPermanentLink() function added to support permanent
+        links.  (J. Fortes suggested the need for this.)
+        Examples:
+
+        (192.168.0.1, port 23)  <-> alias port 6002, unknown dest addr/port
+
+        (192.168.0.2, port 21)  <-> alias port 3604, known dest addr
+                                                     unknown dest port
+
+        These permament links allow for incoming connections to
+        machines on the local network.  They can be given with a
+        user-chosen amount of specificity, with increasing specificity
+        meaning more security. (cjm)
+
+        Quite a bit of rework to the basic engine.  The portTable[]
+        array, which kept track of which ports were in use was replaced
+        by a table/linked list structure. (cjm)
+
+        SetExpire() function added. (cjm)
+
+        DeleteLink() no longer frees memory association with a pointer
+        to a fragment (this bug was first recognized by E. Eklund in
+        v1.9).
+
+    Version 2.1: May, 1997 (cjm)
+        Packet aliasing engine reworked so that it can handle
+        multiple external addresses rather than just a single
+        host address.
+
+        PacketAliasRedirectPort() and PacketAliasRedirectAddr()
+        added to the API.  The first function is a more generalized
+        version of PacketAliasPermanentLink().  The second function
+        implements static network address translation.
+
+    See HISTORY file for additional revisions.
+*/
+
+
+/* System include files */
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+/* BSD network include files */
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+#include "alias.h"
+#include "alias_local.h"
+
+
+
+/*
+   Constants (note: constants are also defined
+              near relevant functions or structs)
+*/
+
+/* Sizes of input and output link tables */
+#define LINK_TABLE_OUT_SIZE         101
+#define LINK_TABLE_IN_SIZE         4001
+
+/* Parameters used for cleanup of expired links */
+#define ALIAS_CLEANUP_INTERVAL_SECS  60
+#define ALIAS_CLEANUP_MAX_SPOKES     30
+
+/* Timouts (in seconds) for different link types) */
+#define ICMP_EXPIRE_TIME             60
+#define UDP_EXPIRE_TIME              60
+#define FRAGMENT_ID_EXPIRE_TIME      10
+#define FRAGMENT_PTR_EXPIRE_TIME     30
+
+/* TCP link expire time for different cases */
+/* When the link has been used and closed - minimal grace time to
+   allow ACKs and potential re-connect in FTP (XXX - is this allowed?)  */
+#ifndef TCP_EXPIRE_DEAD
+#   define TCP_EXPIRE_DEAD           10
+#endif
+
+/* When the link has been used and closed on one side - the other side
+   is allowed to still send data */
+#ifndef TCP_EXPIRE_SINGLEDEAD
+#   define TCP_EXPIRE_SINGLEDEAD     90
+#endif
+
+/* When the link isn't yet up */
+#ifndef TCP_EXPIRE_INITIAL
+#   define TCP_EXPIRE_INITIAL       300
+#endif
+
+/* When the link is up */
+#ifndef TCP_EXPIRE_CONNECTED
+#   define TCP_EXPIRE_CONNECTED   86400
+#endif
+
+
+/* Dummy port number codes used for FindLinkIn/Out() and AddLink().
+   These constants can be anything except zero, which indicates an
+   unknown port number. */
+
+#define NO_DEST_PORT     1
+#define NO_SRC_PORT      1
+
+
+
+/* Data Structures
+
+    The fundamental data structure used in this program is
+    "struct alias_link".  Whenever a TCP connection is made,
+    a UDP datagram is sent out, or an ICMP echo request is made,
+    a link record is made (if it has not already been created).
+    The link record is identified by the source address/port
+    and the destination address/port. In the case of an ICMP
+    echo request, the source port is treated as being equivalent
+    with the 16-bit id number of the ICMP packet.
+
+    The link record also can store some auxiliary data.  For
+    TCP connections that have had sequence and acknowledgment
+    modifications, data space is available to track these changes.
+    A state field is used to keep track in changes to the tcp
+    connection state.  Id numbers of fragments can also be
+    stored in the auxiliary space.  Pointers to unresolved
+    framgents can also be stored.
+
+    The link records support two independent chainings.  Lookup
+    tables for input and out tables hold the initial pointers
+    the link chains.  On input, the lookup table indexes on alias
+    port and link type.  On output, the lookup table indexes on
+    source addreess, destination address, source port, destination
+    port and link type.
+*/
+
+struct ack_data_record     /* used to save changes to ack/seq numbers */
+{
+    u_long ack_old;
+    u_long ack_new;
+    int delta;
+    int active;
+};
+
+struct tcp_state           /* Information about tcp connection        */
+{
+    int in;                /* State for outside -> inside             */
+    int out;               /* State for inside  -> outside            */
+    int index;             /* Index to ack data array                 */
+    int ack_modified;      /* Indicates whether ack and seq numbers   */
+                           /* been modified                           */
+};
+
+#define N_LINK_TCP_DATA   3 /* Number of distinct ack number changes
+                               saved for a modified TCP stream */
+struct tcp_dat
+{
+    struct tcp_state state;
+    struct ack_data_record ack[N_LINK_TCP_DATA];
+    int fwhole;             /* Which firewall record is used for this hole? */
+};
+
+struct alias_link                /* Main data structure */
+{
+    struct in_addr src_addr;     /* Address and port information        */
+    struct in_addr dst_addr;
+    struct in_addr alias_addr;
+    struct in_addr proxy_addr;
+    u_short src_port;
+    u_short dst_port;
+    u_short alias_port;
+    u_short proxy_port;
+
+    int link_type;               /* Type of link: tcp, udp, icmp, frag  */
+
+/* values for link_type */
+#define LINK_ICMP                     1
+#define LINK_UDP                      2
+#define LINK_TCP                      3
+#define LINK_FRAGMENT_ID              4
+#define LINK_FRAGMENT_PTR             5
+#define LINK_ADDR                     6
+
+    int flags;                   /* indicates special characteristics   */
+
+/* flag bits */
+#define LINK_UNKNOWN_DEST_PORT     0x01
+#define LINK_UNKNOWN_DEST_ADDR     0x02
+#define LINK_PERMANENT             0x04
+#define LINK_PARTIALLY_SPECIFIED   0x03 /* logical-or of first two bits */
+#define LINK_UNFIREWALLED          0x08
+
+    int timestamp;               /* Time link was last accessed         */
+    int expire_time;             /* Expire time for link                */
+
+    int sockfd;                  /* socket descriptor                   */
+
+    u_int start_point_out;       /* Index number in output lookup table */
+    u_int start_point_in;
+    struct alias_link *next_out; /* Linked list pointers for input and  */
+    struct alias_link *last_out; /* output tables                       */
+    struct alias_link *next_in;  /*  .                                  */
+    struct alias_link *last_in;  /*  .                                  */
+
+    union                        /* Auxiliary data                      */
+    {
+        char *frag_ptr;
+        struct in_addr frag_addr;
+        struct tcp_dat *tcp;
+    } data;
+};
+
+
+
+
+
+/* Global Variables 
+
+    The global variables listed here are only accessed from
+    within alias_db.c and so are prefixed with the static 
+    designation.
+*/
+
+int packetAliasMode;                 /* Mode flags                      */ 
+                                     /*        - documented in alias.h  */
+
+static struct in_addr aliasAddress;  /* Address written onto source     */
+                                     /*   field of IP packet.           */
+
+static struct in_addr targetAddress; /* IP address incoming packets     */
+                                     /*   are sent to if no aliasing    */
+                                     /*   link already exists           */
+
+static struct in_addr nullAddress;   /* Used as a dummy parameter for   */
+                                     /*   some function calls           */
+static struct alias_link *
+linkTableOut[LINK_TABLE_OUT_SIZE];   /* Lookup table of pointers to     */
+                                     /*   chains of link records. Each  */
+static struct alias_link *           /*   link record is doubly indexed */
+linkTableIn[LINK_TABLE_IN_SIZE];     /*   into input and output lookup  */
+                                     /*   tables.                       */
+
+static int icmpLinkCount;            /* Link statistics                 */
+static int udpLinkCount;
+static int tcpLinkCount;
+static int fragmentIdLinkCount;
+static int fragmentPtrLinkCount;
+static int sockCount;
+
+static int cleanupIndex;             /* Index to chain of link table    */
+                                     /* being inspected for old links   */
+
+static int timeStamp;                /* System time in seconds for      */
+                                     /* current packet                  */
+
+static int lastCleanupTime;          /* Last time IncrementalCleanup()  */
+                                     /* was called                      */
+
+static int houseKeepingResidual;     /* used by HouseKeeping()          */
+
+static int deleteAllLinks;           /* If equal to zero, DeleteLink()  */
+                                     /* will not remove permanent links */
+
+static FILE *monitorFile;            /* File descriptor for link        */
+                                     /* statistics monitoring file      */
+
+static int newDefaultLink;           /* Indicates if a new aliasing     */
+                                     /* link has been created after a   */
+                                     /* call to PacketAliasIn/Out().    */
+             
+#ifndef NO_FW_PUNCH
+static int fireWallFD = -1;          /* File descriptor to be able to   */
+                                     /* control firewall.  Opened by    */
+                                     /* PacketAliasSetMode on first     */
+                                     /* setting the PKT_ALIAS_PUNCH_FW  */
+                                     /* flag.                           */
+#endif
+
+static int pptpAliasFlag; 	     /* Indicates if PPTP aliasing is   */
+                                     /* on or off                       */
+static struct in_addr pptpAliasAddr; /* Address of source of PPTP 	*/
+                                     /* packets.           		*/
+
+
+
+
+
+
+
+/* Internal utility routines (used only in alias_db.c)
+
+Lookup table starting points:
+    StartPointIn()           -- link table initial search point for
+                                outgoing packets
+    StartPointOut()          -- port table initial search point for
+                                incoming packets
+    
+Miscellaneous:
+    SeqDiff()                -- difference between two TCP sequences
+    ShowAliasStats()         -- send alias statistics to a monitor file
+*/
+
+
+/* Local prototypes */
+static u_int StartPointIn(struct in_addr, u_short, int);
+
+static u_int StartPointOut(struct in_addr, struct in_addr,
+                           u_short, u_short, int);
+
+static int SeqDiff(u_long, u_long);
+
+static void ShowAliasStats(void);
+
+#ifndef NO_FW_PUNCH
+/* Firewall control */
+static void InitPunchFW(void);
+static void UninitPunchFW(void);
+static void ClearFWHole(struct alias_link *link);
+#endif
+
+/* Log file control */
+static void InitPacketAliasLog(void);
+static void UninitPacketAliasLog(void);
+
+static u_int
+StartPointIn(struct in_addr alias_addr,
+             u_short alias_port,
+             int link_type)
+{
+    u_int n;
+
+    n  = alias_addr.s_addr;
+    n += alias_port;
+    n += link_type;
+    return(n % LINK_TABLE_IN_SIZE);
+}
+
+
+static u_int
+StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
+              u_short src_port, u_short dst_port, int link_type)
+{
+    u_int n;
+
+    n  = src_addr.s_addr;
+    n += dst_addr.s_addr;
+    n += src_port; 
+    n += dst_port;
+    n += link_type;
+
+    return(n % LINK_TABLE_OUT_SIZE);
+}
+
+
+static int
+SeqDiff(u_long x, u_long y)
+{
+/* Return the difference between two TCP sequence numbers */
+
+/*
+    This function is encapsulated in case there are any unusual
+    arithmetic conditions that need to be considered.
+*/
+
+    return (ntohl(y) - ntohl(x));
+}
+
+
+static void
+ShowAliasStats(void)
+{
+/* Used for debugging */
+
+   if (monitorFile)
+   {
+      fprintf(monitorFile, "icmp=%d, udp=%d, tcp=%d, frag_id=%d frag_ptr=%d",
+              icmpLinkCount,
+              udpLinkCount,
+              tcpLinkCount,
+              fragmentIdLinkCount,
+              fragmentPtrLinkCount);
+
+      fprintf(monitorFile, " / tot=%d  (sock=%d)\n",
+              icmpLinkCount + udpLinkCount
+                            + tcpLinkCount
+                            + fragmentIdLinkCount
+                            + fragmentPtrLinkCount,
+              sockCount);
+
+      fflush(monitorFile);
+   }
+}
+
+
+
+
+
+/* Internal routines for finding, deleting and adding links
+
+Port Allocation:
+    GetNewPort()             -- find and reserve new alias port number
+    GetSocket()              -- try to allocate a socket for a given port
+
+Link creation and deletion:
+    CleanupAliasData()      - remove all link chains from lookup table
+    IncrementalCleanup()    - look for stale links in a single chain
+    DeleteLink()            - remove link
+    AddLink()               - add link 
+    ReLink()                - change link 
+
+Link search:
+    FindLinkOut()           - find link for outgoing packets
+    FindLinkIn()            - find link for incoming packets
+*/
+
+/* Local prototypes */
+static int GetNewPort(struct alias_link *, int);
+
+static u_short GetSocket(u_short, int *, int);
+
+static void CleanupAliasData(void);
+
+static void IncrementalCleanup(void);
+
+static void DeleteLink(struct alias_link *);
+
+static struct alias_link *
+AddLink(struct in_addr, struct in_addr, struct in_addr,
+        u_short, u_short, int, int);
+
+static struct alias_link *
+ReLink(struct alias_link *,
+       struct in_addr, struct in_addr, struct in_addr,
+        u_short, u_short, int, int);
+
+static struct alias_link *
+FindLinkOut(struct in_addr, struct in_addr, u_short, u_short, int);
+
+static struct alias_link *
+FindLinkIn(struct in_addr, struct in_addr, u_short, u_short, int, int);
+
+
+#define ALIAS_PORT_BASE            0x08000
+#define ALIAS_PORT_MASK            0x07fff
+#define GET_NEW_PORT_MAX_ATTEMPTS       20
+
+#define GET_ALIAS_PORT                  -1
+#define GET_ALIAS_ID        GET_ALIAS_PORT
+
+/* GetNewPort() allocates port numbers.  Note that if a port number
+   is already in use, that does not mean that it cannot be used by
+   another link concurrently.  This is because GetNewPort() looks for
+   unused triplets: (dest addr, dest port, alias port). */
+
+static int
+GetNewPort(struct alias_link *link, int alias_port_param)
+{
+    int i;
+    int max_trials;
+    u_short port_sys;
+    u_short port_net;
+
+/*
+   Description of alias_port_param for GetNewPort().  When
+   this parameter is zero or positive, it precisely specifies
+   the port number.  GetNewPort() will return this number
+   without check that it is in use.
+
+   Whis this parameter is -1, it indicates to get a randomly
+   selected port number.
+*/
+ 
+    if (alias_port_param == GET_ALIAS_PORT)
+    {
+        /*
+         * The aliasing port is automatically selected
+         * by one of two methods below:
+         */
+        max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
+
+        if (packetAliasMode & PKT_ALIAS_SAME_PORTS)
+        {
+            /*
+             * When the ALIAS_SAME_PORTS option is
+             * chosen, the first try will be the
+             * actual source port. If this is already
+             * in use, the remainder of the trials
+             * will be random.
+             */
+            port_net = link->src_port;
+            port_sys = ntohs(port_net);
+        }
+        else
+        {
+            /* First trial and all subsequent are random. */
+            port_sys = random() & ALIAS_PORT_MASK;
+            port_sys += ALIAS_PORT_BASE;
+            port_net = htons(port_sys);
+        }
+    }
+    else if (alias_port_param >= 0 && alias_port_param < 0x10000)
+    {
+        link->alias_port = (u_short) alias_port_param;
+        return(0);
+    }
+    else
+    {
+#ifdef DEBUG
+        fprintf(stderr, "PacketAlias/GetNewPort(): ");
+        fprintf(stderr, "input parameter error\n");
+#endif
+        return(-1);
+    }
+
+
+/* Port number search */
+    for (i=0; i<max_trials; i++)
+    {
+        int go_ahead;
+        struct alias_link *search_result;
+
+        search_result = FindLinkIn(link->dst_addr, link->alias_addr,
+                                   link->dst_port, port_net,
+                                   link->link_type, 0);
+
+        if (search_result == NULL)
+            go_ahead = 1;
+        else if (!(link->flags          & LINK_PARTIALLY_SPECIFIED)
+               && (search_result->flags & LINK_PARTIALLY_SPECIFIED))
+            go_ahead = 1;
+        else
+            go_ahead = 0;
+
+        if (go_ahead)
+        {
+            if ((packetAliasMode && PKT_ALIAS_USE_SOCKETS)
+             && (link->flags & LINK_PARTIALLY_SPECIFIED))
+            {
+                if (GetSocket(port_net, &link->sockfd, link->link_type))
+                {
+                    link->alias_port = port_net;
+                    return(0);
+                }
+            }
+            else
+            {
+                link->alias_port = port_net;
+                return(0);
+            }
+        }
+
+        port_sys = random() & ALIAS_PORT_MASK;
+        port_sys += ALIAS_PORT_BASE;
+        port_net = htons(port_sys);
+    }
+
+#ifdef DEBUG
+    fprintf(stderr, "PacketAlias/GetnewPort(): ");
+    fprintf(stderr, "could not find free port\n");
+#endif
+
+    return(-1);
+}
+
+
+static u_short 
+GetSocket(u_short port_net, int *sockfd, int link_type)
+{
+    int err;
+    int sock;
+    struct sockaddr_in sock_addr;
+
+    if (link_type == LINK_TCP)
+        sock = socket(AF_INET, SOCK_STREAM, 0);
+    else if (link_type == LINK_UDP)
+        sock = socket(AF_INET, SOCK_DGRAM, 0);
+    else
+    {
+#ifdef DEBUG
+        fprintf(stderr, "PacketAlias/GetSocket(): ");
+        fprintf(stderr, "incorrect link type\n");
+#endif
+        return(0);
+    }
+
+    if (sock < 0)
+    {
+#ifdef DEBUG
+        fprintf(stderr, "PacketAlias/GetSocket(): ");
+        fprintf(stderr, "socket() error %d\n", *sockfd);
+#endif
+        return(0);
+    }
+
+    sock_addr.sin_family = AF_INET;
+    sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+    sock_addr.sin_port = port_net;
+
+    err = bind(sock,
+               (struct sockaddr *) &sock_addr,
+               sizeof(sock_addr));
+    if (err == 0)
+    {
+        sockCount++;
+        *sockfd = sock;
+        return(1);
+    }
+    else
+    {
+        close(sock);
+        return(0);
+    }
+}
+
+
+static void
+CleanupAliasData(void)
+{
+    struct alias_link *link;
+    int i, icount;
+
+    icount = 0;
+    for (i=0; i<LINK_TABLE_OUT_SIZE; i++)
+    {
+        link = linkTableOut[i];
+        while (link != NULL)
+        {
+            struct alias_link *link_next;
+            link_next = link->next_out;
+            icount++;
+            DeleteLink(link);
+            link = link_next;
+        }
+    }
+
+    cleanupIndex =0;
+}
+
+
+static void
+IncrementalCleanup(void)
+{
+    int icount;
+    struct alias_link *link;
+
+    icount = 0;
+    link = linkTableOut[cleanupIndex++];
+    while (link != NULL)
+    {
+        int idelta;
+        struct alias_link *link_next;
+
+        link_next = link->next_out; 
+        idelta = timeStamp - link->timestamp;
+        switch (link->link_type)
+        {
+            case LINK_ICMP:
+            case LINK_UDP:
+            case LINK_FRAGMENT_ID:
+            case LINK_FRAGMENT_PTR:
+                if (idelta > link->expire_time)
+                {
+                    DeleteLink(link);
+                    icount++;
+                }
+                break;
+            case LINK_TCP:
+                if (idelta > link->expire_time)
+                {
+                    struct tcp_dat *tcp_aux;
+
+                    tcp_aux = link->data.tcp; 
+                    if (tcp_aux->state.in  != ALIAS_TCP_STATE_CONNECTED
+                     || tcp_aux->state.out != ALIAS_TCP_STATE_CONNECTED)
+                    {
+                        DeleteLink(link);
+                        icount++;
+                    }
+                }
+                break;
+        }
+        link = link_next;
+    }
+
+    if (cleanupIndex == LINK_TABLE_OUT_SIZE)
+        cleanupIndex = 0;
+}
+
+void
+DeleteLink(struct alias_link *link)
+{
+    struct alias_link *link_last;
+    struct alias_link *link_next;
+
+/* Don't do anything if the link is marked permanent */
+    if (deleteAllLinks == 0 && link->flags & LINK_PERMANENT)
+        return;
+
+#ifndef NO_FW_PUNCH
+/* Delete associatied firewall hole, if any */
+    ClearFWHole(link);
+#endif
+
+/* Adjust output table pointers */
+    link_last = link->last_out;
+    link_next = link->next_out;
+
+    if (link_last != NULL)
+        link_last->next_out = link_next;
+    else
+        linkTableOut[link->start_point_out] = link_next;
+
+    if (link_next != NULL)
+        link_next->last_out = link_last;
+
+/* Adjust input table pointers */
+    link_last = link->last_in;
+    link_next = link->next_in;
+
+    if (link_last != NULL)
+        link_last->next_in = link_next;
+    else
+        linkTableIn[link->start_point_in] = link_next;
+
+    if (link_next != NULL)
+        link_next->last_in = link_last;
+
+/* Close socket, if one has been allocated */
+    if (link->sockfd != -1)
+    {
+        sockCount--;
+        close(link->sockfd);
+    }
+
+/* Link-type dependent cleanup */
+    switch(link->link_type)
+    {
+        case LINK_ICMP:
+            icmpLinkCount--;
+            break;
+        case LINK_UDP:
+            udpLinkCount--;
+            break;
+        case LINK_TCP:
+            tcpLinkCount--;
+            if (link->data.tcp != NULL)
+                free(link->data.tcp);
+            break;
+        case LINK_FRAGMENT_ID:
+            fragmentIdLinkCount--;
+            break;
+        case LINK_FRAGMENT_PTR:
+            fragmentPtrLinkCount--;
+            if (link->data.frag_ptr != NULL)
+                free(link->data.frag_ptr);
+            break;
+    }
+
+/* Free memory */
+    free(link);
+
+/* Write statistics, if logging enabled */
+    if (packetAliasMode & PKT_ALIAS_LOG)
+    {
+        ShowAliasStats();
+    }
+}
+
+
+static struct alias_link *
+AddLink(struct in_addr  src_addr,
+        struct in_addr  dst_addr,
+        struct in_addr  alias_addr,
+        u_short         src_port,
+        u_short         dst_port,
+        int             alias_port_param,  /* if less than zero, alias   */
+        int             link_type)         /* port will be automatically */
+{                                          /* chosen. If greater than    */
+    u_int start_point;                     /* zero, equal to alias port  */
+    struct alias_link *link;
+    struct alias_link *first_link;
+
+    link = malloc(sizeof(struct alias_link));
+    if (link != NULL)
+    {
+    /* If either the aliasing address or source address are
+       equal to the default device address (equal to the
+       global variable aliasAddress), then set the alias
+       address field of the link record to zero */
+
+        if (src_addr.s_addr == aliasAddress.s_addr)
+            src_addr.s_addr = 0;
+
+        if (alias_addr.s_addr == aliasAddress.s_addr)
+            alias_addr.s_addr = 0;
+
+    /* Basic initialization */
+        link->src_addr          = src_addr;
+        link->dst_addr          = dst_addr;
+        link->alias_addr        = alias_addr;
+        link->proxy_addr.s_addr = 0;
+        link->src_port          = src_port;
+        link->dst_port          = dst_port;
+        link->proxy_port        = 0;
+        link->link_type         = link_type;
+        link->sockfd            = -1;
+        link->flags             = 0;
+        link->timestamp         = timeStamp;
+
+    /* Expiration time */
+        switch (link_type)
+        {
+        case LINK_ICMP:
+            link->expire_time = ICMP_EXPIRE_TIME;
+            break;
+        case LINK_UDP:
+            link->expire_time = UDP_EXPIRE_TIME;
+            break;
+        case LINK_TCP:
+            link->expire_time = TCP_EXPIRE_INITIAL;
+            break;
+        case LINK_FRAGMENT_ID:
+            link->expire_time = FRAGMENT_ID_EXPIRE_TIME;
+            break;
+        case LINK_FRAGMENT_PTR:
+            link->expire_time = FRAGMENT_PTR_EXPIRE_TIME;
+            break;
+        }
+
+    /* Determine alias flags */
+        if (dst_addr.s_addr == 0)
+            link->flags |= LINK_UNKNOWN_DEST_ADDR;
+        if (dst_port == 0)
+            link->flags |= LINK_UNKNOWN_DEST_PORT;
+
+    /* Determine alias port */
+        if (GetNewPort(link, alias_port_param) != 0)
+        {
+            free(link);
+            return(NULL);
+        }
+
+    /* Set up pointers for output lookup table */
+        start_point = StartPointOut(src_addr, dst_addr, 
+                                    src_port, dst_port, link_type);
+        first_link = linkTableOut[start_point];
+
+        link->last_out        = NULL;
+        link->next_out        = first_link;
+        link->start_point_out = start_point;
+
+        if (first_link != NULL)
+            first_link->last_out = link;
+
+        linkTableOut[start_point] = link;
+
+    /* Set up pointers for input lookup table */
+        start_point = StartPointIn(alias_addr, link->alias_port, link_type); 
+        first_link = linkTableIn[start_point];
+
+        link->last_in        = NULL;
+        link->next_in        = first_link;
+        link->start_point_in = start_point;
+
+        if (first_link != NULL)
+            first_link->last_in = link;
+
+        linkTableIn[start_point] = link;
+
+    /* Link-type dependent initialization */
+        switch(link_type)
+        {
+            struct tcp_dat  *aux_tcp;
+
+            case LINK_ICMP:
+                icmpLinkCount++;
+                break;
+            case LINK_UDP:
+                udpLinkCount++;
+                break;
+            case LINK_TCP:
+                aux_tcp = malloc(sizeof(struct tcp_dat));
+                link->data.tcp = aux_tcp;
+                if (aux_tcp != NULL)
+                {
+                    int i;
+
+                    tcpLinkCount++;
+                    aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED;
+                    aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED;
+                    aux_tcp->state.index = 0;
+                    aux_tcp->state.ack_modified = 0;
+                    for (i=0; i<N_LINK_TCP_DATA; i++)
+                        aux_tcp->ack[i].active = 0;
+                    aux_tcp->fwhole = -1;
+                }
+                else
+                {
+#ifdef DEBUG
+                    fprintf(stderr, "PacketAlias/AddLink: ");
+                    fprintf(stderr, " cannot allocate auxiliary TCP data\n");
+#endif
+                }
+                break;
+            case LINK_FRAGMENT_ID:
+                fragmentIdLinkCount++;
+                break;
+            case LINK_FRAGMENT_PTR:
+                fragmentPtrLinkCount++;
+                break;
+        }
+    }
+    else
+    {
+#ifdef DEBUG
+        fprintf(stderr, "PacketAlias/AddLink(): ");
+        fprintf(stderr, "malloc() call failed.\n");
+#endif
+    }
+
+    if (packetAliasMode & PKT_ALIAS_LOG)
+    {
+        ShowAliasStats();
+    }
+
+    return(link);
+}
+
+static struct alias_link *
+ReLink(struct alias_link *old_link,
+       struct in_addr  src_addr,
+       struct in_addr  dst_addr,
+       struct in_addr  alias_addr,
+       u_short         src_port,
+       u_short         dst_port,
+       int             alias_port_param,   /* if less than zero, alias   */
+       int             link_type)          /* port will be automatically */
+{                                          /* chosen. If greater than    */
+    struct alias_link *new_link;           /* zero, equal to alias port  */
+
+    new_link = AddLink(src_addr, dst_addr, alias_addr,
+                       src_port, dst_port, alias_port_param,
+                       link_type);
+#ifndef NO_FW_PUNCH
+    if (new_link != NULL &&
+        old_link->link_type == LINK_TCP &&
+        old_link->data.tcp &&
+        old_link->data.tcp->fwhole > 0) {
+      PunchFWHole(new_link);
+    }
+#endif
+    DeleteLink(old_link);
+    return new_link;
+}
+
+static struct alias_link *
+FindLinkOut(struct in_addr src_addr,
+            struct in_addr dst_addr,
+            u_short src_port,
+            u_short dst_port,
+            int link_type)
+{
+    u_int i;
+    struct alias_link *link;
+
+    if (src_addr.s_addr == aliasAddress.s_addr)
+        src_addr.s_addr = 0;
+
+    i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
+    link = linkTableOut[i];
+    while (link != NULL)
+    {
+        if (link->src_addr.s_addr == src_addr.s_addr
+         && link->dst_addr.s_addr == dst_addr.s_addr
+         && link->dst_port        == dst_port
+         && link->src_port        == src_port
+         && link->link_type       == link_type)
+        {
+            link->timestamp = timeStamp;
+            break;
+        }
+        link = link->next_out;
+    }
+
+    return(link);
+}
+
+
+struct alias_link *
+FindLinkIn(struct in_addr  dst_addr,
+           struct in_addr  alias_addr,
+           u_short         dst_port,
+           u_short         alias_port,
+           int             link_type,
+           int             replace_partial_links)
+{
+    int flags_in;
+    u_int start_point;
+    struct alias_link *link;
+    struct alias_link *link_fully_specified;
+    struct alias_link *link_unknown_all;
+    struct alias_link *link_unknown_dst_addr;
+    struct alias_link *link_unknown_dst_port;
+
+/* Initialize pointers */
+    link_fully_specified  = NULL;
+    link_unknown_all      = NULL;
+    link_unknown_dst_addr = NULL;
+    link_unknown_dst_port = NULL;
+
+/* If either the dest addr or port is unknown, the search
+   loop will have to know about this. */
+
+    flags_in = 0;
+    if (dst_addr.s_addr == 0)
+        flags_in |= LINK_UNKNOWN_DEST_ADDR;
+    if (dst_port == 0)
+        flags_in |= LINK_UNKNOWN_DEST_PORT;
+
+/* The following allows permanent links to be
+   be specified as using the default aliasing address
+   (i.e. device interface address) without knowing
+   in advance what that address is. */
+
+    if (alias_addr.s_addr == aliasAddress.s_addr)
+        alias_addr.s_addr = 0;
+
+/* Search loop */
+    start_point = StartPointIn(alias_addr, alias_port, link_type);
+    link = linkTableIn[start_point];
+    while (link != NULL)
+    {
+        int flags;
+
+        flags = flags_in | link->flags;
+        if (!(flags & LINK_PARTIALLY_SPECIFIED))
+        {
+            if (link->alias_addr.s_addr == alias_addr.s_addr
+             && link->alias_port        == alias_port 
+             && link->dst_addr.s_addr   == dst_addr.s_addr
+             && link->dst_port          == dst_port
+             && link->link_type         == link_type)
+            {
+                link_fully_specified = link;
+                break;
+            }
+        }
+        else if ((flags & LINK_UNKNOWN_DEST_ADDR)
+              && (flags & LINK_UNKNOWN_DEST_PORT))
+        {
+            if (link->alias_addr.s_addr == alias_addr.s_addr
+             && link->alias_port        == alias_port
+             && link->link_type         == link_type)
+            {
+                if (link_unknown_all == NULL)
+                    link_unknown_all = link;
+            }
+        }
+        else if (flags & LINK_UNKNOWN_DEST_ADDR)
+        {
+            if (link->alias_addr.s_addr == alias_addr.s_addr
+             && link->alias_port        == alias_port
+             && link->link_type         == link_type
+             && link->dst_port          == dst_port)
+            {
+                if (link_unknown_dst_addr == NULL)
+                    link_unknown_dst_addr = link;
+            }
+        }
+        else if (flags & LINK_UNKNOWN_DEST_PORT)
+        {
+            if (link->alias_addr.s_addr == alias_addr.s_addr
+             && link->alias_port        == alias_port
+             && link->link_type         == link_type
+             && link->dst_addr.s_addr   == dst_addr.s_addr)
+            {
+                if (link_unknown_dst_port == NULL)
+                    link_unknown_dst_port = link;
+            }
+        }
+        link = link->next_in;
+    }
+
+
+
+    if (link_fully_specified != NULL)
+    {
+        return link_fully_specified;
+    }
+    else if (link_unknown_dst_port != NULL)
+    {
+        return replace_partial_links
+          ? ReLink(link_unknown_dst_port,
+                   link_unknown_dst_port->src_addr, dst_addr, alias_addr,
+                   link_unknown_dst_port->src_port, dst_port, alias_port,
+                   link_type)
+          : link_unknown_dst_port;
+    }
+    else if (link_unknown_dst_addr != NULL)
+    {
+        return replace_partial_links
+          ? ReLink(link_unknown_dst_addr,
+                   link_unknown_dst_addr->src_addr, dst_addr, alias_addr,
+                   link_unknown_dst_addr->src_port, dst_port, alias_port,
+                   link_type)
+          : link_unknown_dst_addr;
+    }
+    else if (link_unknown_all != NULL)
+    {
+        return replace_partial_links
+          ? ReLink(link_unknown_all,
+                   link_unknown_all->src_addr, dst_addr, alias_addr,
+                   link_unknown_all->src_port, dst_port, alias_port,
+                   link_type)
+          : link_unknown_all;
+    }
+    else
+    {
+        return(NULL);
+    }
+}
+
+
+
+
+/* External routines for finding/adding links
+
+-- "external" means outside alias_db.c, but within alias*.c --
+
+    FindIcmpIn(), FindIcmpOut()
+    FindFragmentIn1(), FindFragmentIn2()
+    AddFragmentPtrLink(), FindFragmentPtr()
+    FindUdpTcpIn(), FindUdpTcpOut()
+    FindOriginalAddress(), FindAliasAddress()
+
+(prototypes in alias_local.h)
+*/
+
+
+struct alias_link *
+FindIcmpIn(struct in_addr dst_addr,
+           struct in_addr alias_addr,
+           u_short id_alias)
+{
+    return FindLinkIn(dst_addr, alias_addr,
+                      NO_DEST_PORT, id_alias,
+                      LINK_ICMP, 0);
+}
+
+
+struct alias_link *
+FindIcmpOut(struct in_addr src_addr,
+            struct in_addr dst_addr,
+            u_short id)
+{
+    struct alias_link * link;
+
+    link = FindLinkOut(src_addr, dst_addr,
+                       id, NO_DEST_PORT,
+                       LINK_ICMP);
+    if (link == NULL)
+    {
+        struct in_addr alias_addr;
+
+        alias_addr = FindAliasAddress(src_addr);
+        link = AddLink(src_addr, dst_addr, alias_addr,
+                       id, NO_DEST_PORT, GET_ALIAS_ID,
+                       LINK_ICMP);
+    }
+
+    return(link);
+}
+
+
+struct alias_link *
+FindFragmentIn1(struct in_addr dst_addr,
+                struct in_addr alias_addr,
+                u_short ip_id)
+{
+    struct alias_link *link;
+
+    link = FindLinkIn(dst_addr, alias_addr,
+                      NO_DEST_PORT, ip_id,
+                      LINK_FRAGMENT_ID, 0);
+
+    if (link == NULL)
+    {
+        link = AddLink(nullAddress, dst_addr, alias_addr,
+                       NO_SRC_PORT, NO_DEST_PORT, ip_id,
+                       LINK_FRAGMENT_ID);
+    }
+
+    return(link);
+}
+
+
+struct alias_link *
+FindFragmentIn2(struct in_addr dst_addr,   /* Doesn't add a link if one */
+                struct in_addr alias_addr, /*   is not found.           */
+                u_short ip_id)
+{
+    return FindLinkIn(dst_addr, alias_addr,
+                      NO_DEST_PORT, ip_id,
+                      LINK_FRAGMENT_ID, 0);
+}
+
+
+struct alias_link *
+AddFragmentPtrLink(struct in_addr dst_addr,
+                   u_short ip_id)
+{
+    return AddLink(nullAddress, dst_addr, nullAddress,
+                   NO_SRC_PORT, NO_DEST_PORT, ip_id,
+                   LINK_FRAGMENT_PTR);
+}
+
+
+struct alias_link *
+FindFragmentPtr(struct in_addr dst_addr,
+                u_short ip_id)
+{
+    return FindLinkIn(dst_addr, nullAddress,
+                      NO_DEST_PORT, ip_id,
+                      LINK_FRAGMENT_PTR, 0);
+}
+
+
+struct alias_link *
+FindUdpTcpIn(struct in_addr dst_addr,
+             struct in_addr alias_addr,
+             u_short        dst_port,
+             u_short        alias_port,
+             u_char         proto)
+{
+    int link_type;
+    struct alias_link *link;
+
+    switch (proto)
+    {
+    case IPPROTO_UDP:
+        link_type = LINK_UDP;
+        break;
+    case IPPROTO_TCP:
+        link_type = LINK_TCP;
+        break;
+    default:
+        return NULL;
+        break;
+    }
+
+    link = FindLinkIn(dst_addr, alias_addr,
+                      dst_port, alias_port,
+                      link_type, 1);
+
+    if (!(packetAliasMode & PKT_ALIAS_DENY_INCOMING)
+     && !(packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+     && link == NULL)
+    {
+        struct in_addr target_addr;
+
+        target_addr = FindOriginalAddress(alias_addr);
+        link = AddLink(target_addr, dst_addr, alias_addr,
+                       alias_port, dst_port, alias_port,
+                       link_type);
+    }
+
+    return(link);
+}
+
+
+struct alias_link * 
+FindUdpTcpOut(struct in_addr  src_addr,
+              struct in_addr  dst_addr,
+              u_short         src_port,
+              u_short         dst_port,
+              u_char          proto)
+{
+    int link_type;
+    struct alias_link *link;
+
+    switch (proto)
+    {
+    case IPPROTO_UDP:
+        link_type = LINK_UDP;
+        break;
+    case IPPROTO_TCP:
+        link_type = LINK_TCP;
+        break;
+    default:
+        return NULL;
+        break;
+    }
+
+    link = FindLinkOut(src_addr, dst_addr, src_port, dst_port, link_type);
+
+    if (link == NULL)
+    {
+        struct in_addr alias_addr;
+
+        alias_addr = FindAliasAddress(src_addr);
+        link = AddLink(src_addr, dst_addr, alias_addr,
+                       src_port, dst_port, GET_ALIAS_PORT,
+                       link_type);
+    }
+
+    return(link);
+}
+
+
+struct in_addr
+FindOriginalAddress(struct in_addr alias_addr)
+{
+    struct alias_link *link;
+    
+    link = FindLinkIn(nullAddress, alias_addr,
+                      0, 0, LINK_ADDR, 0);
+    if (link == NULL)
+    {
+        newDefaultLink = 1;
+        if (targetAddress.s_addr != 0)
+            return targetAddress;
+        else
+            return alias_addr;
+    }
+    else
+    {
+        if (link->src_addr.s_addr == 0)
+            return aliasAddress;
+        else
+            return link->src_addr;
+    }
+}
+
+
+struct in_addr
+FindAliasAddress(struct in_addr original_addr)
+{
+    struct alias_link *link;
+    
+    link = FindLinkOut(original_addr, nullAddress,
+                       0, 0, LINK_ADDR);
+    if (link == NULL)
+    {
+        return aliasAddress;
+    }
+    else
+    {
+        if (link->alias_addr.s_addr == 0)
+            return aliasAddress;
+        else
+            return link->alias_addr;
+    }
+}
+
+
+/* External routines for getting or changing link data
+   (external to alias_db.c, but internal to alias*.c)
+
+    SetFragmentData(), GetFragmentData()
+    SetFragmentPtr(), GetFragmentPtr()
+    SetStateIn(), SetStateOut(), GetStateIn(), GetStateOut()
+    GetOriginalAddress(), GetDestAddress(), GetAliasAddress()
+    GetOriginalPort(), GetAliasPort()
+    SetAckModified(), GetAckModified()
+    GetDeltaAckIn(), GetDeltaSeqOut(), AddSeq()
+*/
+
+
+void
+SetFragmentAddr(struct alias_link *link, struct in_addr src_addr)
+{
+    link->data.frag_addr = src_addr;
+}
+
+
+void
+GetFragmentAddr(struct alias_link *link, struct in_addr *src_addr)
+{
+    *src_addr = link->data.frag_addr;
+}
+
+
+void
+SetFragmentPtr(struct alias_link *link, char *fptr)
+{
+    link->data.frag_ptr = fptr;
+}
+
+
+void
+GetFragmentPtr(struct alias_link *link, char **fptr)
+{
+   *fptr = link->data.frag_ptr;
+}
+
+
+void
+SetStateIn(struct alias_link *link, int state)
+{
+    /* TCP input state */
+    switch (state) {
+    case ALIAS_TCP_STATE_DISCONNECTED:
+        if (link->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED) {
+            link->expire_time = TCP_EXPIRE_DEAD;
+        } else {
+            link->expire_time = TCP_EXPIRE_SINGLEDEAD;
+        }
+        link->data.tcp->state.in = state;
+        break;
+    case ALIAS_TCP_STATE_CONNECTED:
+        link->expire_time = TCP_EXPIRE_CONNECTED;
+        /*FALLTHROUGH*/
+    case ALIAS_TCP_STATE_NOT_CONNECTED:
+        link->data.tcp->state.in = state;
+        break;
+    default:
+        abort();
+    }
+}
+
+
+void
+SetStateOut(struct alias_link *link, int state)
+{
+    /* TCP output state */
+    switch (state) {
+    case ALIAS_TCP_STATE_DISCONNECTED:
+        if (link->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED) {
+            link->expire_time = TCP_EXPIRE_DEAD;
+        } else {
+            link->expire_time = TCP_EXPIRE_SINGLEDEAD;
+        }
+        link->data.tcp->state.out = state;
+        break;
+    case ALIAS_TCP_STATE_CONNECTED:
+        link->expire_time = TCP_EXPIRE_CONNECTED;
+        /*FALLTHROUGH*/
+    case ALIAS_TCP_STATE_NOT_CONNECTED:
+        link->data.tcp->state.out = state;
+        break;
+    default:
+        abort();
+    }
+}
+
+
+int
+GetStateIn(struct alias_link *link)
+{
+    /* TCP input state */
+    return link->data.tcp->state.in;
+}
+
+
+int
+GetStateOut(struct alias_link *link)
+{
+    /* TCP output state */
+    return link->data.tcp->state.out;
+}
+
+
+struct in_addr
+GetOriginalAddress(struct alias_link *link)
+{
+    if (link->src_addr.s_addr == 0)
+        return aliasAddress;
+    else
+        return(link->src_addr);
+}
+
+
+struct in_addr
+GetDestAddress(struct alias_link *link)
+{
+    return(link->dst_addr);
+}
+
+
+struct in_addr
+GetAliasAddress(struct alias_link *link)
+{
+    if (link->alias_addr.s_addr == 0)
+        return aliasAddress;
+    else
+        return link->alias_addr;
+}
+
+
+struct in_addr
+GetDefaultAliasAddress()
+{
+    return aliasAddress;
+}
+
+
+void
+SetDefaultAliasAddress(struct in_addr alias_addr)
+{
+    aliasAddress = alias_addr;
+}
+
+
+u_short
+GetOriginalPort(struct alias_link *link)
+{
+    return(link->src_port);
+}
+
+
+u_short
+GetAliasPort(struct alias_link *link)
+{
+    return(link->alias_port);
+}
+
+u_short
+GetDestPort(struct alias_link *link)
+{
+    return(link->dst_port);
+}
+
+void
+SetAckModified(struct alias_link *link)
+{
+/* Indicate that ack numbers have been modified in a TCP connection */
+    link->data.tcp->state.ack_modified = 1;
+}
+
+
+struct in_addr
+GetProxyAddress(struct alias_link *link)
+{
+    return link->proxy_addr;
+}
+
+
+void
+SetProxyAddress(struct alias_link *link, struct in_addr addr)
+{
+    link->proxy_addr = addr;
+}
+
+
+u_short
+GetProxyPort(struct alias_link *link)
+{
+    return link->proxy_port;
+}
+
+
+void
+SetProxyPort(struct alias_link *link, u_short port)
+{
+    link->proxy_port = port;
+}
+
+
+int
+GetAckModified(struct alias_link *link)
+{
+/* See if ack numbers have been modified */
+    return link->data.tcp->state.ack_modified;
+}
+
+
+int
+GetDeltaAckIn(struct ip *pip, struct alias_link *link)
+{
+/*
+Find out how much the ack number has been altered for an incoming
+TCP packet.  To do this, a circular list is ack numbers where the TCP
+packet size was altered is searched. 
+*/
+
+    int i;
+    struct tcphdr *tc;
+    int delta, ack_diff_min;
+    u_long ack;
+
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+    ack      = tc->th_ack;
+
+    delta = 0;
+    ack_diff_min = -1;
+    for (i=0; i<N_LINK_TCP_DATA; i++)
+    {
+        struct ack_data_record x;
+
+        x = link->data.tcp->ack[i];
+        if (x.active == 1)
+        {
+            int ack_diff;
+
+            ack_diff = SeqDiff(x.ack_new, ack);
+            if (ack_diff >= 0)
+            {
+                if (ack_diff_min >= 0)
+                {
+                    if (ack_diff < ack_diff_min)
+                    {
+                        delta = x.delta;
+                        ack_diff_min = ack_diff;
+                    }
+                }
+                else
+                {
+                    delta = x.delta;
+                    ack_diff_min = ack_diff;
+                }
+            }
+        }
+    }
+    return (delta);
+}
+
+
+int
+GetDeltaSeqOut(struct ip *pip, struct alias_link *link)
+{
+/*
+Find out how much the seq number has been altered for an outgoing
+TCP packet.  To do this, a circular list is ack numbers where the TCP
+packet size was altered is searched. 
+*/
+
+    int i;
+    struct tcphdr *tc;
+    int delta, seq_diff_min;
+    u_long seq;
+
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+    seq = tc->th_seq;
+
+    delta = 0;
+    seq_diff_min = -1;
+    for (i=0; i<N_LINK_TCP_DATA; i++)
+    {
+        struct ack_data_record x;
+
+        x = link->data.tcp->ack[i];
+        if (x.active == 1)
+        {
+            int seq_diff;
+
+            seq_diff = SeqDiff(x.ack_old, seq);
+            if (seq_diff >= 0)
+            {
+                if (seq_diff_min >= 0)
+                {
+                    if (seq_diff < seq_diff_min)
+                    {
+                        delta = x.delta;
+                        seq_diff_min = seq_diff;
+                    }
+                }
+                else
+                {
+                    delta = x.delta;
+                    seq_diff_min = seq_diff;
+                }
+            }
+        }
+    }
+    return (delta);
+}
+
+
+void
+AddSeq(struct ip *pip, struct alias_link *link, int delta)
+{
+/*
+When a TCP packet has been altered in length, save this
+information in a circular list.  If enough packets have
+been altered, then this list will begin to overwrite itself.
+*/
+
+    struct tcphdr *tc;
+    struct ack_data_record x;
+    int hlen, tlen, dlen;
+    int i;
+
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+    hlen = (pip->ip_hl + tc->th_off) << 2;
+    tlen = ntohs(pip->ip_len);
+    dlen = tlen - hlen;
+
+    x.ack_old = htonl(ntohl(tc->th_seq) + dlen);
+    x.ack_new = htonl(ntohl(tc->th_seq) + dlen + delta);
+    x.delta = delta;
+    x.active = 1;
+
+    i = link->data.tcp->state.index;
+    link->data.tcp->ack[i] = x;
+
+    i++;
+    if (i == N_LINK_TCP_DATA)
+        link->data.tcp->state.index = 0;
+    else
+        link->data.tcp->state.index = i;
+}
+
+void
+SetExpire(struct alias_link *link, int expire)
+{
+    if (expire == 0)
+    {
+        link->flags &= ~LINK_PERMANENT;
+        DeleteLink(link);
+    }
+    else if (expire == -1)
+    {
+        link->flags |= LINK_PERMANENT;
+    }
+    else if (expire > 0)
+    {
+        link->expire_time = expire;
+    }
+    else
+    {
+#ifdef DEBUG
+        fprintf(stderr, "PacketAlias/SetExpire(): ");
+        fprintf(stderr, "error in expire parameter\n");
+#endif
+    }
+}
+
+void
+ClearCheckNewLink(void)
+{
+    newDefaultLink = 0;
+}
+
+
+/* Miscellaneous Functions
+
+    HouseKeeping()
+    InitPacketAliasLog()
+    UninitPacketAliasLog()
+*/
+
+/*
+    Whenever an outgoing or incoming packet is handled, HouseKeeping()
+    is called to find and remove timed-out aliasing links.  Logic exists
+    to sweep through the entire table and linked list structure
+    every 60 seconds.
+
+    (prototype in alias_local.h)
+*/
+
+void
+HouseKeeping(void)
+{
+    int i, n, n100;
+    struct timeval tv;
+    struct timezone tz;
+
+    /*
+     * Save system time (seconds) in global variable timeStamp for
+     * use by other functions. This is done so as not to unnecessarily
+     * waste timeline by making system calls.
+     */
+    gettimeofday(&tv, &tz);
+    timeStamp = tv.tv_sec;
+
+    /* Compute number of spokes (output table link chains) to cover */
+    n100  = LINK_TABLE_OUT_SIZE * 100 + houseKeepingResidual;
+    n100 *= timeStamp - lastCleanupTime;
+    n100 /= ALIAS_CLEANUP_INTERVAL_SECS;
+
+    n = n100/100;
+
+    /* Handle different cases */
+    if (n > ALIAS_CLEANUP_MAX_SPOKES)
+    {
+        n = ALIAS_CLEANUP_MAX_SPOKES;
+        lastCleanupTime = timeStamp;
+        houseKeepingResidual = 0;
+
+        for (i=0; i<n; i++)
+            IncrementalCleanup();
+    }
+    else if (n > 0)
+    {
+        lastCleanupTime = timeStamp;
+        houseKeepingResidual = n100 - 100*n;
+
+        for (i=0; i<n; i++)
+            IncrementalCleanup();
+    }
+    else if (n < 0)
+    {
+#ifdef DEBUG
+        fprintf(stderr, "PacketAlias/HouseKeeping(): ");
+        fprintf(stderr, "something unexpected in time values\n");
+#endif
+        lastCleanupTime = timeStamp;
+        houseKeepingResidual = 0;
+    }
+}
+
+
+/* Init the log file and enable logging */
+static void
+InitPacketAliasLog(void)
+{
+   if ((~packetAliasMode & PKT_ALIAS_LOG)
+    && (monitorFile = fopen("/var/log/alias.log", "w")))
+   {
+      packetAliasMode |= PKT_ALIAS_LOG;
+      fprintf(monitorFile,
+      "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n");
+   }
+}
+
+
+/* Close the log-file and disable logging. */
+static void
+UninitPacketAliasLog(void)
+{
+    if (monitorFile) {
+        fclose(monitorFile);
+        monitorFile = NULL;
+    }
+    packetAliasMode &= ~PKT_ALIAS_LOG;
+}
+
+
+
+
+
+
+/* Outside world interfaces
+
+-- "outside world" means other than alias*.c routines --
+
+    PacketAliasRedirectPort()
+    PacketAliasRedirectAddr()
+    PacketAliasRedirectDelete()
+    PacketAliasSetAddress()
+    PacketAliasInit()
+    PacketAliasUninit()
+    PacketAliasSetMode()
+
+(prototypes in alias.h)
+*/
+
+/* Redirection from a specific public addr:port to a
+   a private addr:port */
+struct alias_link *
+PacketAliasRedirectPort(struct in_addr src_addr,   u_short src_port,
+                        struct in_addr dst_addr,   u_short dst_port,
+                        struct in_addr alias_addr, u_short alias_port,
+                        u_char proto)
+{
+    int link_type;
+    struct alias_link *link;
+
+    switch(proto)
+    {
+    case IPPROTO_UDP:
+        link_type = LINK_UDP;
+        break;
+    case IPPROTO_TCP:
+        link_type = LINK_TCP;
+        break;
+    default:
+#ifdef DEBUG
+        fprintf(stderr, "PacketAliasRedirectPort(): ");
+        fprintf(stderr, "only TCP and UDP protocols allowed\n");
+#endif
+        return NULL;
+    }
+
+    link = AddLink(src_addr, dst_addr, alias_addr,
+                   src_port, dst_port, alias_port,
+                   link_type);
+
+    if (link != NULL)
+    {
+        link->flags |= LINK_PERMANENT;
+    }
+#ifdef DEBUG
+    else
+    {
+        fprintf(stderr, "PacketAliasRedirectPort(): " 
+                        "call to AddLink() failed\n");
+    }
+#endif
+
+    return link;
+}
+
+/* Translate PPTP packets to a machine on the inside
+ */
+int
+PacketAliasPptp(struct in_addr src_addr)
+{
+
+    pptpAliasAddr = src_addr; 		/* Address of the inside PPTP machine */
+    pptpAliasFlag = src_addr.s_addr != INADDR_NONE;
+
+    return 1;
+}
+
+int GetPptpAlias (struct in_addr* alias_addr)
+{
+    if (pptpAliasFlag)
+	*alias_addr = pptpAliasAddr;
+
+    return pptpAliasFlag;
+}
+
+/* Static address translation */
+struct alias_link *
+PacketAliasRedirectAddr(struct in_addr src_addr,
+                        struct in_addr alias_addr)
+{
+    struct alias_link *link;
+
+    link = AddLink(src_addr, nullAddress, alias_addr,
+                   0, 0, 0,
+                   LINK_ADDR);
+
+    if (link != NULL)
+    {
+        link->flags |= LINK_PERMANENT;
+    }
+#ifdef DEBUG
+    else
+    {
+        fprintf(stderr, "PacketAliasRedirectAddr(): " 
+                        "call to AddLink() failed\n");
+    }
+#endif
+
+    return link;
+}
+
+
+void
+PacketAliasRedirectDelete(struct alias_link *link)
+{
+/* This is a dangerous function to put in the API,
+   because an invalid pointer can crash the program. */
+
+    deleteAllLinks = 1;
+    DeleteLink(link);
+    deleteAllLinks = 0;
+}
+
+
+void
+PacketAliasSetAddress(struct in_addr addr)
+{
+    if (packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE
+     && aliasAddress.s_addr != addr.s_addr)
+        CleanupAliasData();
+
+    aliasAddress = addr;
+}
+
+
+void
+PacketAliasSetTarget(struct in_addr target_addr)
+{
+    targetAddress = target_addr;
+}
+
+
+void
+PacketAliasInit(void)
+{
+    int i;
+    struct timeval tv;
+    struct timezone tz;
+    static int firstCall = 1;
+
+    if (firstCall == 1)
+    {
+        gettimeofday(&tv, &tz);
+        timeStamp = tv.tv_sec;
+        lastCleanupTime = tv.tv_sec;
+        houseKeepingResidual = 0;
+
+        for (i=0; i<LINK_TABLE_OUT_SIZE; i++)
+            linkTableOut[i] = NULL;
+        for (i=0; i<LINK_TABLE_IN_SIZE; i++)
+            linkTableIn[i] = NULL;
+
+        atexit(PacketAliasUninit);
+        firstCall = 0;
+    }
+    else
+    {
+        deleteAllLinks = 1;
+        CleanupAliasData();
+        deleteAllLinks = 0;
+    }
+
+    aliasAddress.s_addr = 0;
+    targetAddress.s_addr = 0;
+
+    icmpLinkCount = 0;
+    udpLinkCount = 0;
+    tcpLinkCount = 0;
+    fragmentIdLinkCount = 0;
+    fragmentPtrLinkCount = 0;
+    sockCount = 0;
+
+    cleanupIndex =0;
+
+    packetAliasMode = PKT_ALIAS_SAME_PORTS
+                    | PKT_ALIAS_USE_SOCKETS
+                    | PKT_ALIAS_RESET_ON_ADDR_CHANGE;
+
+    pptpAliasFlag = 0;
+}
+
+void
+PacketAliasUninit(void) {
+    deleteAllLinks = 1;
+    CleanupAliasData();
+    deleteAllLinks = 0;
+    UninitPacketAliasLog();
+#ifndef NO_FW_PUNCH
+    UninitPunchFW();
+#endif
+}
+
+
+/* Change mode for some operations */
+unsigned int
+PacketAliasSetMode(
+    unsigned int flags, /* Which state to bring flags to */
+    unsigned int mask   /* Mask of which flags to affect (use 0 to do a
+                           probe for flag values) */
+)
+{
+/* Enable logging? */
+    if (flags & mask & PKT_ALIAS_LOG)
+    {
+        InitPacketAliasLog();     /* Do the enable */
+    } else
+/* _Disable_ logging? */
+    if (~flags & mask & PKT_ALIAS_LOG) {
+        UninitPacketAliasLog();
+    }
+
+#ifndef NO_FW_PUNCH
+/* Start punching holes in the firewall? */
+    if (flags & mask & PKT_ALIAS_PUNCH_FW) {
+        InitPunchFW();
+    } else
+/* Stop punching holes in the firewall? */
+    if (~flags & mask & PKT_ALIAS_PUNCH_FW) {
+        UninitPunchFW();
+    }
+#endif
+
+/* Other flags can be set/cleared without special action */
+    packetAliasMode = (flags & mask) | (packetAliasMode & ~mask);
+    return packetAliasMode;
+}
+
+
+int
+PacketAliasCheckNewLink(void)
+{
+    return newDefaultLink;
+}
+
+
+#ifndef NO_FW_PUNCH
+
+/*****************
+  Code to support firewall punching.  This shouldn't really be in this
+  file, but making variables global is evil too.
+  ****************/
+
+/* Firewall include files */
+#include <sys/queue.h>
+#include <net/if.h>
+#include <netinet/ip_fw.h>
+#include <string.h>
+#include <err.h>
+
+static void ClearAllFWHoles(void);
+
+static int fireWallBaseNum;     /* The first firewall entry free for our use */
+static int fireWallNumNums;     /* How many entries can we use? */
+static int fireWallActiveNum;   /* Which entry did we last use? */
+static char *fireWallField;     /* bool array for entries */
+
+#define fw_setfield(field, num)                         \
+do {                                                    \
+    (field)[num] = 1;                                   \
+} /*lint -save -e717 */ while(0) /*lint -restore */
+#define fw_clrfield(field, num)                         \
+do {                                                    \
+    (field)[num] = 0;                                   \
+} /*lint -save -e717 */ while(0) /*lint -restore */
+#define fw_tstfield(field, num) ((field)[num])
+
+void
+PacketAliasSetFWBase(unsigned int base, unsigned int num) {
+    fireWallBaseNum = base;
+    fireWallNumNums = num;
+}
+
+static void
+InitPunchFW(void) {
+    fireWallField = malloc(fireWallNumNums);
+    if (fireWallField) {
+        memset(fireWallField, 0, fireWallNumNums);
+        if (fireWallFD < 0) {
+            fireWallFD = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+        }
+        ClearAllFWHoles();
+        fireWallActiveNum = fireWallBaseNum;
+    }
+}
+
+static void
+UninitPunchFW(void) {
+    ClearAllFWHoles();
+    if (fireWallFD >= 0)
+        close(fireWallFD);
+    fireWallFD = -1;
+    if (fireWallField)
+        free(fireWallField);
+    fireWallField = NULL;
+    packetAliasMode &= ~PKT_ALIAS_PUNCH_FW;
+}
+
+/* Make a certain link go through the firewall */
+void
+PunchFWHole(struct alias_link *link) {
+    int r;                      /* Result code */
+    struct ip_fw rule;          /* On-the-fly built rule */
+    int fwhole;                 /* Where to punch hole */
+
+/* Don't do anything unless we are asked to */
+    if ( !(packetAliasMode & PKT_ALIAS_PUNCH_FW) ||
+         fireWallFD < 0 ||
+         link->link_type != LINK_TCP ||
+         !link->data.tcp)
+        return;
+
+    memset(&rule, 0, sizeof rule);
+
+/** Build rule **/
+
+    /* Find empty slot */
+    for (fwhole = fireWallActiveNum;
+         fwhole < fireWallBaseNum + fireWallNumNums &&
+             fw_tstfield(fireWallField, fwhole);
+         fwhole++)
+        ;
+    if (fwhole >= fireWallBaseNum + fireWallNumNums ||
+        fw_tstfield(fireWallField, fwhole)) {
+        for (fwhole = fireWallBaseNum;
+             fwhole < fireWallActiveNum &&
+                 fw_tstfield(fireWallField, fwhole);
+             fwhole++)
+            ;
+        if (fwhole == fireWallActiveNum) {
+            /* No rule point empty - we can't punch more holes. */
+            fireWallActiveNum = fireWallBaseNum;
+#ifdef DEBUG
+            fprintf(stderr, "libalias: Unable to create firewall hole!\n");
+#endif
+            return;
+        }
+    }
+    /* Start next search at next position */
+    fireWallActiveNum = fwhole+1;
+
+    /* Build generic part of the two rules */
+    rule.fw_number = fwhole;
+    rule.fw_nports = 1;         /* Number of source ports; dest ports follow */
+    rule.fw_flg = IP_FW_F_ACCEPT;
+    rule.fw_prot = IPPROTO_TCP;
+    rule.fw_smsk.s_addr = INADDR_BROADCAST;
+    rule.fw_dmsk.s_addr = INADDR_BROADCAST;
+
+    /* Build and apply specific part of the rules */
+    rule.fw_src = GetOriginalAddress(link);
+    rule.fw_dst = GetDestAddress(link);
+    rule.fw_uar.fw_pts[0] = ntohs(GetOriginalPort(link));
+    rule.fw_uar.fw_pts[1] = ntohs(GetDestPort(link));
+
+    /* Skip non-bound links - XXX should not be strictly necessary,
+       but seems to leave hole if not done.  Leak of non-bound links?
+       (Code should be left even if the problem is fixed - it is a
+       clear optimization) */
+    if (rule.fw_uar.fw_pts[0] != 0 && rule.fw_uar.fw_pts[1] != 0) {
+        r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
+#ifdef DEBUG
+        if (r)
+            err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
+#endif
+        rule.fw_src = GetDestAddress(link);
+        rule.fw_dst = GetOriginalAddress(link);
+        rule.fw_uar.fw_pts[0] = ntohs(GetDestPort(link));
+        rule.fw_uar.fw_pts[1] = ntohs(GetOriginalPort(link));
+        r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
+#ifdef DEBUG
+        if (r)
+            err(1, "alias punch inbound(2) setsockopt(IP_FW_ADD)");
+#endif
+    }
+/* Indicate hole applied */
+    link->data.tcp->fwhole = fwhole;
+    fw_setfield(fireWallField, fwhole);
+}
+
+/* Remove a hole in a firewall associated with a particular alias
+   link.  Calling this too often is harmless. */
+static void
+ClearFWHole(struct alias_link *link) {
+    if (link->link_type == LINK_TCP && link->data.tcp) {
+        int fwhole =  link->data.tcp->fwhole; /* Where is the firewall hole? */
+        struct ip_fw rule;
+
+        if (fwhole < 0)
+            return;
+
+        memset(&rule, 0, sizeof rule);
+        rule.fw_number = fwhole;
+        while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule))
+            ;
+        fw_clrfield(fireWallField, fwhole);
+        link->data.tcp->fwhole = -1;
+    }
+}
+
+/* Clear out the entire range dedicated to firewall holes. */
+static void
+ClearAllFWHoles(void) {
+    struct ip_fw rule;          /* On-the-fly built rule */
+    int i;
+    
+    if (fireWallFD < 0)
+        return;
+
+    memset(&rule, 0, sizeof rule);
+    for (i = fireWallBaseNum; i < fireWallBaseNum + fireWallNumNums; i++) {
+        rule.fw_number = i;
+        while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule))
+            ;
+    }
+    memset(fireWallField, 0, fireWallNumNums);
+}
+#endif
diff --git a/alias/alias_ftp.c b/alias/alias_ftp.c
new file mode 100644
index 0000000..73769fd
--- /dev/null
+++ b/alias/alias_ftp.c
@@ -0,0 +1,229 @@
+/*
+    Alias_ftp.c performs special processing for FTP sessions under
+    TCP.  Specifically, when a PORT command from the client side
+    is sent, it is intercepted and modified.  The address is changed
+    to the gateway machine and an aliasing port is used.
+
+    For this routine to work, the PORT command must fit entirely
+    into a single TCP packet.  This is typically the case, but exceptions
+    can easily be envisioned under the actual specifications.
+
+    Probably the most troubling aspect of the approach taken here is
+    that the new PORT command will typically be a different length, and
+    this causes a certain amount of bookkeeping to keep track of the
+    changes of sequence and acknowledgment numbers, since the client
+    machine is totally unaware of the modification to the TCP stream.
+
+
+    This software is placed into the public domain with no restrictions
+    on its distribution.
+
+    Initial version:  August, 1996  (cjm)
+
+    Version 1.6
+         Brian Somers and Martin Renters identified an IP checksum
+         error for modified IP packets.
+
+    Version 1.7:  January 9, 1996 (cjm)
+         Differental checksum computation for change
+         in IP packet length.
+   
+    Version 2.1:  May, 1997 (cjm)
+         Very minor changes to conform with
+         local/global/function naming conventions
+         withing the packet alising module.
+
+    See HISTORY file for record of revisions.
+*/
+
+/* Includes */
+#include <ctype.h>
+#include <stdio.h> 
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include "alias_local.h"
+
+static void NewFtpPortCommand(struct ip *, struct alias_link *, struct in_addr, u_short, int);
+
+
+
+void
+AliasHandleFtpOut(
+struct ip *pip,	  /* IP packet to examine/patch */
+struct alias_link *link, /* The link to go through (aliased port) */
+int maxpacketsize  /* The maximum size this packet can grow to (including headers) */)
+{
+    int hlen, tlen, dlen;
+    struct in_addr true_addr;
+    u_short true_port;
+    char *sptr;
+    struct tcphdr *tc;
+        
+/* Calculate data length of TCP packet */
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+    hlen = (pip->ip_hl + tc->th_off) << 2;
+    tlen = ntohs(pip->ip_len);
+    dlen = tlen - hlen;
+
+/* Return is data length is too long or too short */
+    if (dlen<10 || dlen>80)
+        return;
+
+/* Place string pointer and beginning of data */
+    sptr = (char *) pip;  
+    sptr += hlen;
+
+/* Parse through string using state diagram method */
+    {
+        char ch, zero;
+        int i, state;
+        u_long a1, a2, a3, a4;
+        u_short p1, p2; 
+
+        a1=0; a2=0; a3=0; a4=0; p1=0; p2=0;
+        zero = '0';
+        state=-4;
+        for (i=0; i<dlen; i++)
+        {
+            ch = sptr[i];
+            switch (state)
+            {
+                case -4: if (ch == 'P') state=-3; else return; break;
+                case -3: if (ch == 'O') state=-2; else return; break;
+                case -2: if (ch == 'R') state=-1; else return; break;
+                case -1: if (ch == 'T') state= 0; else return; break;
+
+                case 0 :
+                    if (isdigit(ch)) {a1=ch-zero; state=1 ;} break;
+                case 1 :
+                    if (isdigit(ch)) a1=10*a1+ch-zero; else state=2 ; break;
+                case 2 :
+                    if (isdigit(ch)) {a2=ch-zero; state=3 ;} break;
+                case 3 :
+                    if (isdigit(ch)) a2=10*a2+ch-zero; else state=4 ; break;
+                case 4 :
+                    if (isdigit(ch)) {a3=ch-zero; state=5 ;} break;
+                case 5 :
+                    if (isdigit(ch)) a3=10*a3+ch-zero; else state=6 ; break;
+                case 6 :
+                    if (isdigit(ch)) {a4=ch-zero; state=7 ;} break;
+                case 7 :
+                    if (isdigit(ch)) a4=10*a4+ch-zero; else state=8 ; break;
+                case 8 :
+                    if (isdigit(ch)) {p1=ch-zero; state=9 ;} break;
+                case 9 :
+                    if (isdigit(ch)) p1=10*p1+ch-zero; else state=10; break;
+                case 10:
+                    if (isdigit(ch)) {p2=ch-zero; state=11;} break;
+                case 11:
+                    if (isdigit(ch)) p2=10*p2+ch-zero; break;
+            }
+        }
+
+        if (state == 11)
+        {
+            true_port = htons((p1<<8) + p2);
+            true_addr.s_addr = htonl((a1<<24) + (a2<<16) +(a3<<8) + a4);
+            NewFtpPortCommand(pip, link, true_addr, true_port, maxpacketsize);
+        }
+    }
+}
+
+static void
+NewFtpPortCommand(struct ip *pip,
+                  struct alias_link *link,
+                  struct in_addr true_addr,
+                  u_short true_port,
+                  int maxpacketsize)
+{ 
+    struct alias_link *ftp_link;
+
+/* Establish link to address and port found in PORT command */
+    ftp_link = FindUdpTcpOut(true_addr, GetDestAddress(link),
+                             true_port, 0, IPPROTO_TCP);
+
+    if (ftp_link != NULL)
+    {
+        int slen, hlen, tlen, dlen;
+        struct tcphdr *tc;
+
+#ifndef NO_FW_PUNCH
+/* Punch hole in firewall */
+        PunchFWHole(ftp_link);
+#endif
+
+/* Calculate data length of TCP packet */
+        tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+        hlen = (pip->ip_hl + tc->th_off) << 2;
+        tlen = ntohs(pip->ip_len);
+        dlen = tlen - hlen;
+
+/* Create new PORT command */
+        {
+            char stemp[80];
+            char *sptr;
+            u_short alias_port;
+            u_char *ptr;
+            int a1, a2, a3, a4, p1, p2; 
+            struct in_addr alias_address;
+        
+/* Decompose alias address into quad format */
+            alias_address = GetAliasAddress(link);
+            ptr = (u_char *) &alias_address.s_addr;
+            a1 = *ptr++; a2=*ptr++; a3=*ptr++; a4=*ptr;
+
+/* Decompose alias port into pair format */
+            alias_port = GetAliasPort(ftp_link);
+            ptr = (char *) &alias_port;
+            p1 = *ptr++; p2=*ptr;
+
+/* Generate command string */
+            sprintf(stemp, "PORT %d,%d,%d,%d,%d,%d\r\n",
+                     a1,a2,a3,a4,p1,p2);
+
+/* Save string length for IP header modification */
+            slen = strlen(stemp);
+
+/* Copy into IP packet */
+            sptr = (char *) pip; sptr += hlen;
+            strncpy(sptr, stemp, maxpacketsize-hlen);
+        }
+
+/* Save information regarding modified seq and ack numbers */
+        {
+            int delta;
+
+            SetAckModified(link);
+            delta = GetDeltaSeqOut(pip, link);
+            AddSeq(pip, link, delta+slen-dlen);
+        }
+
+/* Revise IP header */
+        {
+            u_short new_len;
+
+            new_len = htons(hlen + slen);
+            DifferentialChecksum(&pip->ip_sum,
+                                 &new_len,
+                                 &pip->ip_len,
+                                 1);
+            pip->ip_len = new_len;
+        }
+
+/* Compute TCP checksum for revised packet */
+        tc->th_sum = 0;
+        tc->th_sum = TcpChecksum(pip);
+    }
+    else
+    {
+#ifdef DEBUG
+        fprintf(stderr,
+        "PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n");
+#endif
+    }
+}
diff --git a/alias/alias_irc.c b/alias/alias_irc.c
new file mode 100644
index 0000000..910e934
--- /dev/null
+++ b/alias/alias_irc.c
@@ -0,0 +1,316 @@
+/* Alias_irc.c intercepts packages contain IRC CTCP commands, and
+	changes DCC commands to export a port on the aliasing host instead
+	of an aliased host.
+
+    For this routine to work, the DCC command must fit entirely into a
+    single TCP packet.  This will usually happen, but is not
+    guaranteed.
+
+	 The interception is likely to change the length of the packet.
+	 The handling of this is copied more-or-less verbatim from
+	 ftp_alias.c
+
+    This software is placed into the public domain with no restrictions
+    on its distribution.
+
+	 Initial version: Eivind Eklund <perhaps@yes.no> (ee) 97-01-29
+
+         Version 2.1:  May, 1997 (cjm)
+             Very minor changes to conform with
+             local/global/function naming conventions
+             withing the packet alising module.
+*/
+
+/* Includes */
+#include <ctype.h>
+#include <stdio.h> 
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <limits.h>
+
+#include "alias_local.h"
+
+/* Local defines */
+#define DBprintf(a)
+
+
+void
+AliasHandleIrcOut(struct ip *pip, /* IP packet to examine */
+				 struct alias_link *link,		  /* Which link are we on? */
+				 int maxsize		  /* Maximum size of IP packet including headers */
+				 )
+{       
+    int hlen, tlen, dlen;
+    struct in_addr true_addr;
+    u_short true_port;
+    char *sptr;
+    struct tcphdr *tc;
+	 int i;							  /* Iterator through the source */
+        
+/* Calculate data length of TCP packet */
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+    hlen = (pip->ip_hl + tc->th_off) << 2;
+    tlen = ntohs(pip->ip_len);
+    dlen = tlen - hlen;
+
+	 /* Return if data length is too short - assume an entire PRIVMSG in each packet. */
+    if (dlen<sizeof(":A!a@n.n PRIVMSG A :aDCC 1 1a")-1)
+        return;
+
+/* Place string pointer at beginning of data */
+    sptr = (char *) pip;  
+    sptr += hlen;
+	 maxsize -= hlen;				  /* We're interested in maximum size of data, not packet */
+
+	 /* Search for a CTCP command [Note 1] */
+	 for(	i=0; i<dlen; i++ ) {
+		 if(sptr[i]=='\001')
+			 goto lFOUND_CTCP;
+	 }
+	 return;					  /* No CTCP commands in  */
+	 /* Handle CTCP commands - the buffer may have to be copied */
+lFOUND_CTCP:
+	 {
+		 char newpacket[65536];	  /* Estimate of maximum packet size :) */
+		 int  copyat = i;			  /* Same */
+		 int  iCopy = 0;			  /* How much data have we written to copy-back string? */
+		 unsigned long org_addr;  /* Original IP address */
+		 unsigned short org_port; /* Original source port address */
+	 lCTCP_START:
+		 if( i >= dlen || iCopy >= sizeof(newpacket) )
+			 goto lPACKET_DONE;
+		 newpacket[iCopy++] = sptr[i++];	/* Copy the CTCP start character */
+		 /* Start of a CTCP */
+		 if( i+4 >= dlen )		  /* Too short for DCC */
+			 goto lBAD_CTCP;
+		 if( sptr[i+0] != 'D' )
+			 goto lBAD_CTCP;
+		 if( sptr[i+1] != 'C' )
+			 goto lBAD_CTCP;
+		 if( sptr[i+2] != 'C' )
+			 goto lBAD_CTCP;
+		 if( sptr[i+3] != ' ' )
+			 goto lBAD_CTCP;
+		 /* We have a DCC command - handle it! */
+		 i+= 4;						  /* Skip "DCC " */
+		 if( iCopy+4 > sizeof(newpacket) )
+			 goto lPACKET_DONE;
+		 newpacket[iCopy++] = 'D';
+		 newpacket[iCopy++] = 'C';
+		 newpacket[iCopy++] = 'C';
+		 newpacket[iCopy++] = ' ';
+
+		 DBprintf(("Found DCC\n"));
+		 /* Skip any extra spaces (should not occur according to
+          protocol, but DCC breaks CTCP protocol anyway */
+		 while(sptr[i] == ' ') {
+			 if( ++i >= dlen) {
+				 DBprintf(("DCC packet terminated in just spaces\n"));
+				 goto lPACKET_DONE;
+			 }
+		 }
+
+		 DBprintf(("Transferring command...\n"));
+		 while(sptr[i] != ' ') {
+			 newpacket[iCopy++] = sptr[i];
+			 if( ++i >= dlen || iCopy >= sizeof(newpacket) ) {
+				 DBprintf(("DCC packet terminated during command\n"));
+				 goto lPACKET_DONE;
+			 }
+		 }
+		 /* Copy _one_ space */
+		 if( i+1 < dlen && iCopy < sizeof(newpacket) )
+			 newpacket[iCopy++] = sptr[i++];
+
+		 DBprintf(("Done command - removing spaces\n"));
+		 /* Skip any extra spaces (should not occur according to
+          protocol, but DCC breaks CTCP protocol anyway */
+		 while(sptr[i] == ' ') {
+			 if( ++i >= dlen ) {
+				 DBprintf(("DCC packet terminated in just spaces (post-command)\n"));
+				 goto lPACKET_DONE;
+			 }
+		 }
+
+		 DBprintf(("Transferring filename...\n"));
+		 while(sptr[i] != ' ') {
+			 newpacket[iCopy++] = sptr[i];
+			 if( ++i >= dlen || iCopy >= sizeof(newpacket) ) {
+				 DBprintf(("DCC packet terminated during filename\n"));
+				 goto lPACKET_DONE;
+			 }
+		 }
+		 /* Copy _one_ space */
+		 if( i+1 < dlen && iCopy < sizeof(newpacket) )
+			 newpacket[iCopy++] = sptr[i++];
+
+		 DBprintf(("Done filename - removing spaces\n"));
+		 /* Skip any extra spaces (should not occur according to
+          protocol, but DCC breaks CTCP protocol anyway */
+		 while(sptr[i] == ' ') {
+			 if( ++i >= dlen ) {
+				 DBprintf(("DCC packet terminated in just spaces (post-filename)\n"));
+				 goto lPACKET_DONE;
+			 }
+		 }
+
+		 DBprintf(("Fetching IP address\n"));
+		 /* Fetch IP address */
+		 org_addr = 0;
+		 while(i<dlen && isdigit(sptr[i])) {
+			 if( org_addr > ULONG_MAX/10UL )	{ /* Terminate on overflow */
+				 DBprintf(("DCC Address overflow (org_addr == 0x%08lx, next char %c\n", org_addr, sptr[i]));
+				 goto lBAD_CTCP;
+			 }
+			 org_addr *= 10;
+			 org_addr += sptr[i++]-'0';
+		 }
+		 DBprintf(("Skipping space\n"));
+		 if( i+1 >= dlen || sptr[i] != ' ' ) {
+			 DBprintf(("Overflow (%d >= %d) or bad character (%02x) terminating IP address\n", i+1, dlen, sptr[i]));
+			 goto lBAD_CTCP;
+		 }
+		 /* Skip any extra spaces (should not occur according to
+          protocol, but DCC breaks CTCP protocol anyway, so we might
+          as well play it safe */
+		 while(sptr[i] == ' ') {
+			 if( ++i >= dlen ) {
+				 DBprintf(("Packet failure - space overflow.\n"));
+				 goto lPACKET_DONE;
+			 }
+		 }
+		 DBprintf(("Fetching port number\n"));
+		 /* Fetch source port */
+		 org_port = 0;
+		 while(i<dlen && isdigit(sptr[i])) {
+			 if( org_port > 6554 )	{ /* Terminate on overflow (65536/10 rounded up*/
+				 DBprintf(("DCC: port number overflow\n"));
+				 goto lBAD_CTCP;
+			 }
+			 org_port *= 10;
+			 org_port += sptr[i++]-'0';
+		 }
+		 /* Skip illegal addresses (or early termination) */
+		 if( i >= dlen || (sptr[i] != '\001' && sptr[i] != ' ') ) {
+			 DBprintf(("Bad port termination\n"));
+			 goto lBAD_CTCP;
+		 }
+		 DBprintf(("Got IP %lu and port %u\n", org_addr, (unsigned)org_port));
+
+		 /* We've got the address and port - now alias it */
+		 {
+			 struct alias_link *dcc_link;
+			 struct in_addr destaddr;
+			 
+
+			 true_port = htons(org_port);
+			 true_addr.s_addr = htonl(org_addr);
+			 destaddr.s_addr = 0;
+
+			 /* Steal the FTP_DATA_PORT - it doesn't really matter, and this
+				 would probably allow it through at least _some_
+				 firewalls. */
+			 dcc_link = FindUdpTcpOut (true_addr,
+											destaddr,
+										   true_port,
+											0, IPPROTO_TCP);
+			 DBprintf(("Got a DCC link\n"));
+			 if ( dcc_link ) {
+				 struct in_addr alias_address;	/* Address from aliasing */
+				 u_short alias_port;	/* Port given by aliasing */
+
+#ifndef NO_FW_PUNCH
+				 /* Generate firewall hole as appropriate */
+				 PunchFWHole(dcc_link);
+#endif
+
+				 alias_address = GetAliasAddress(link);
+				 iCopy += snprintf(&newpacket[iCopy],
+										 sizeof(newpacket)-iCopy, 
+										 "%lu ", (u_long)htonl(alias_address.s_addr));
+				 if( iCopy >= sizeof(newpacket) ) { /* Truncated/fit exactly - bad news */
+					 DBprintf(("DCC constructed packet overflow.\n"));
+					 goto lBAD_CTCP;
+				 }
+				 alias_port = GetAliasPort(dcc_link);
+				 iCopy += snprintf(&newpacket[iCopy],
+										 sizeof(newpacket)-iCopy, 
+										 "%u", htons(alias_port) );
+				 /* Done - truncated cases will be taken care of by lBAD_CTCP */
+				 DBprintf(("Aliased IP %lu and port %u\n", alias_address.s_addr, (unsigned)alias_port));
+			 }
+		 }
+		 /* An uninteresting CTCP - state entered right after '\001' has
+          been pushed.  Also used to copy the rest of a DCC, after IP
+          address and port has been handled */
+	 lBAD_CTCP:
+		 for(; i<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
+			 newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
+			 if(sptr[i] == '\001') {
+				 goto lNORMAL_TEXT;
+			 }
+		 }
+		 goto lPACKET_DONE;
+		 /* Normal text */
+	 lNORMAL_TEXT:
+		 for(; i<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
+			 newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
+			 if(sptr[i] == '\001') {
+				 goto lCTCP_START;
+			 }
+		 }
+		 /* Handle the end of a packet */
+	 lPACKET_DONE:
+		 iCopy = iCopy > maxsize-copyat ? maxsize-copyat : iCopy;
+		 memcpy(sptr+copyat, newpacket, iCopy);
+
+/* Save information regarding modified seq and ack numbers */
+        {
+            int delta;
+
+            SetAckModified(link);
+            delta = GetDeltaSeqOut(pip, link);
+            AddSeq(pip, link, delta+copyat+iCopy-dlen);
+        }
+
+		  /* Revise IP header */
+        {
+			  u_short new_len;
+			  
+			  new_len = htons(hlen + iCopy + copyat);
+			  DifferentialChecksum(&pip->ip_sum,
+										  &new_len,
+										  &pip->ip_len,
+										  1);
+			  pip->ip_len = new_len;
+        }
+
+		  /* Compute TCP checksum for revised packet */
+        tc->th_sum = 0;
+        tc->th_sum = TcpChecksum(pip);
+		  return;
+	 }
+}
+
+/* Notes:
+	[Note 1]
+	The initial search will most often fail; it could be replaced with a 32-bit specific search.
+	Such a search would be done for 32-bit unsigned value V:
+	V ^= 0x01010101;				  (Search is for null bytes)
+	if( ((V-0x01010101)^V) & 0x80808080 ) {
+     (found a null bytes which was a 01 byte)
+	}
+   To assert that the processor is 32-bits, do
+   extern int ircdccar[32];        (32 bits)
+   extern int ircdccar[CHAR_BIT*sizeof(unsigned int)];
+   which will generate a type-error on all but 32-bit machines.
+
+	[Note 2] This routine really ought to be replaced with one that
+	creates a transparent proxy on the aliasing host, to allow arbitary
+	changes in the TCP stream.  This should not be too difficult given
+	this base;  I (ee) will try to do this some time later.
+	*/
diff --git a/alias/alias_local.h b/alias/alias_local.h
new file mode 100644
index 0000000..23b04a8
--- /dev/null
+++ b/alias/alias_local.h
@@ -0,0 +1,170 @@
+/* -*- mode: c; tab-width: 3; c-basic-offset: 3; -*-
+    Alias_local.h contains the function prototypes for alias.c,
+    alias_db.c, alias_util.c and alias_ftp.c, alias_irc.c (as well
+    as any future add-ons).  It also includes macros, globals and
+    struct definitions shared by more than one alias*.c file.
+
+    This include file is intended to be used only within the aliasing
+    software.  Outside world interfaces are defined in alias.h
+
+    This software is placed into the public domain with no restrictions
+    on its distribution.
+
+    Initial version:  August, 1996  (cjm)    
+    
+     <updated several times by original author and Eivind Eiklund>
+*/
+#ifndef ALIAS_LOCAL_H
+#define ALIAS_LOCAL_H
+
+
+/*
+    Macros
+ */
+
+/*
+   The following macro is used to update an
+   internet checksum.  "delta" is a 32-bit
+   accumulation of all the changes to the
+   checksum (adding in new 16-bit words and
+   subtracting out old words), and "cksum"
+   is the checksum value to be updated.
+*/
+#define ADJUST_CHECKSUM(acc, cksum) { \
+    acc += cksum; \
+    if (acc < 0) \
+    { \
+        acc = -acc; \
+        acc = (acc >> 16) + (acc & 0xffff); \
+        acc += acc >> 16; \
+        cksum = (u_short) ~acc; \
+    } \
+    else \
+    { \
+        acc = (acc >> 16) + (acc & 0xffff); \
+        acc += acc >> 16; \
+        cksum = (u_short) acc; \
+    } \
+}
+
+
+/*
+    Globals
+*/
+
+extern int packetAliasMode;
+
+
+/*
+    Structs
+*/
+
+struct alias_link;    /* Incomplete structure */
+
+
+/*
+    Prototypes
+*/
+
+/* General utilities */
+u_short IpChecksum(struct ip *);
+u_short TcpChecksum(struct ip *);
+void DifferentialChecksum(u_short *, u_short *, u_short *, int);
+
+/* Internal data access */
+struct alias_link *
+FindIcmpIn(struct in_addr, struct in_addr, u_short);
+
+struct alias_link *
+FindIcmpOut(struct in_addr, struct in_addr, u_short);
+
+struct alias_link *
+FindFragmentIn1(struct in_addr, struct in_addr, u_short);
+
+struct alias_link *
+FindFragmentIn2(struct in_addr, struct in_addr, u_short);
+
+struct alias_link *
+AddFragmentPtrLink(struct in_addr, u_short);
+
+struct alias_link *
+FindFragmentPtr(struct in_addr, u_short);
+
+struct alias_link *
+FindUdpTcpIn (struct in_addr, struct in_addr, u_short, u_short, u_char);
+
+struct alias_link *
+FindUdpTcpOut(struct in_addr, struct in_addr, u_short, u_short, u_char);
+
+struct in_addr
+FindOriginalAddress(struct in_addr);
+
+struct in_addr
+FindAliasAddress(struct in_addr);
+
+/* External data access/modification */
+void GetFragmentAddr(struct alias_link *, struct in_addr *);
+void SetFragmentAddr(struct alias_link *, struct in_addr);
+void GetFragmentPtr(struct alias_link *, char **);
+void SetFragmentPtr(struct alias_link *, char *);
+void SetStateIn(struct alias_link *, int);
+void SetStateOut(struct alias_link *, int);
+int GetStateIn(struct alias_link *);
+int GetStateOut(struct alias_link *);
+struct in_addr GetOriginalAddress(struct alias_link *);
+struct in_addr GetDestAddress(struct alias_link *);
+struct in_addr GetAliasAddress(struct alias_link *);
+struct in_addr GetDefaultAliasAddress(void);
+void SetDefaultAliasAddress(struct in_addr);
+u_short GetOriginalPort(struct alias_link *);
+u_short GetAliasPort(struct alias_link *);
+struct in_addr GetProxyAddress(struct alias_link *);
+void SetProxyAddress(struct alias_link *, struct in_addr);
+u_short GetProxyPort(struct alias_link *);
+void SetProxyPort(struct alias_link *, u_short);
+void SetAckModified(struct alias_link *);
+int GetAckModified(struct alias_link *);
+int GetDeltaAckIn(struct ip *, struct alias_link *);
+int GetDeltaSeqOut(struct ip *, struct alias_link *);
+void AddSeq(struct ip *, struct alias_link *, int);
+void SetExpire(struct alias_link *, int);
+void ClearCheckNewLink(void);
+#ifndef NO_FW_PUNCH
+void PunchFWHole(struct alias_link *);
+#endif
+
+
+/* Housekeeping function */
+void HouseKeeping(void);
+
+/* Tcp specfic routines */
+/*lint -save -library Suppress flexelint warnings */
+
+/* FTP routines */
+void AliasHandleFtpOut(struct ip *, struct alias_link *, int);
+
+/* IRC routines */
+void AliasHandleIrcOut(struct ip *, struct alias_link *, int);
+
+/* NetBIOS routines */
+int AliasHandleUdpNbt(struct ip *, struct alias_link *, struct in_addr *, u_short);
+int AliasHandleUdpNbtNS(struct ip *, struct alias_link *, struct in_addr *, u_short *, struct in_addr *, u_short *);
+
+/* CUSeeMe routines */
+void AliasHandleCUSeeMeOut(struct ip *, struct alias_link *);
+void AliasHandleCUSeeMeIn(struct ip *, struct in_addr);
+
+/* Transparent proxy routines */
+int ProxyCheck(struct ip *, struct in_addr *, u_short *);
+void ProxyModify(struct alias_link *, struct ip *, int, int);
+
+
+enum alias_tcp_state {
+    ALIAS_TCP_STATE_NOT_CONNECTED,
+    ALIAS_TCP_STATE_CONNECTED,
+    ALIAS_TCP_STATE_DISCONNECTED
+};
+
+int GetPptpAlias (struct in_addr*);
+/*lint -restore */
+#endif /* defined(ALIAS_LOCAL_H) */
diff --git a/alias/alias_nbt.c b/alias/alias_nbt.c
new file mode 100644
index 0000000..b629b8e
--- /dev/null
+++ b/alias/alias_nbt.c
@@ -0,0 +1,711 @@
+/*
+ * Written by Atsushi Murai <amurai@spec.co.jp>
+ *
+ * Copyright (C) 1998, System Planning and Engineering Co. All rights reserverd.
+ *
+ * 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 System Planning and Engineering Co.  The name of the
+ * SPEC 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.
+ *
+ * $Id: alias_nbt.c,v 1.1.1.1 2000/01/11 01:48:42 wsanchez Exp $
+ *
+ *  TODO:
+ *       oClean up. 
+ *       oConsidering for word alignment for other platform.
+ */
+/*
+    alias_nbt.c performs special processing for NetBios over TCP/IP
+    sessions by UDP.
+
+    Initial version:  May, 1998  (Atsushi Murai <amurai@spec.co.jp>)
+
+    See HISTORY file for record of revisions.
+*/
+
+/* Includes */
+#include <ctype.h>
+#include <stdio.h> 
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <netinet/tcp.h>
+
+#include "alias_local.h"
+
+#define ADJUST_CHECKSUM(acc, cksum) { \
+    acc += cksum; \
+    if (acc < 0) \
+    { \
+        acc = -acc; \
+        acc = (acc >> 16) + (acc & 0xffff); \
+        acc += acc >> 16; \
+        cksum = (u_short) ~acc; \
+    } \
+    else \
+    { \
+        acc = (acc >> 16) + (acc & 0xffff); \
+        acc += acc >> 16; \
+        cksum = (u_short) acc; \
+    } \
+}
+
+typedef struct {
+	struct in_addr		oldaddr;
+	u_short 			oldport;
+	struct in_addr		newaddr;
+	u_short 			newport;
+	u_short 			*uh_sum;
+} NBTArguments;
+
+typedef struct {
+	unsigned char   type;
+	unsigned char   flags;
+	u_short  		id;
+	struct in_addr  source_ip;
+	u_short			source_port;
+	u_short			len;
+	u_short			offset;
+} NbtDataHeader;
+
+#define OpQuery		0
+#define OpUnknown	4
+#define OpRegist	5
+#define OpRelease	6
+#define OpWACK		7
+#define OpRefresh	8
+typedef struct {
+	u_short			nametrid;
+	u_short 		dir:1, opcode:4, nmflags:7, rcode:4;
+	u_short			qdcount;
+	u_short			ancount;
+	u_short			nscount;
+	u_short			arcount;
+} NbtNSHeader;
+
+#define FMT_ERR		0x1
+#define SRV_ERR		0x2
+#define IMP_ERR		0x4
+#define RFS_ERR		0x5
+#define ACT_ERR		0x6
+#define CFT_ERR		0x7
+
+
+#ifdef DEBUG
+static void PrintRcode( u_char rcode )  {
+
+	switch (rcode) {
+		case FMT_ERR:
+			printf("\nFormat Error.");
+		case SRV_ERR:
+			printf("\nSever failure.");
+		case IMP_ERR:
+			printf("\nUnsupported request error.\n");
+		case RFS_ERR:
+			printf("\nRefused error.\n");
+		case ACT_ERR:
+			printf("\nActive error.\n");
+		case CFT_ERR:
+			printf("\nName in conflict error.\n");
+		default:
+			printf("\n???=%0x\n", rcode );
+
+	}	
+}
+#endif
+
+
+/* Handling Name field */
+static u_char *AliasHandleName ( u_char *p, char *pmax ) {
+
+	u_char *s;
+	u_char c;
+	int		compress;
+
+	/* Following length field */
+
+	if (p == NULL || (char *)p >= pmax)
+		return(NULL);
+
+	if (*p & 0xc0 ) {
+		p = p + 2;
+		if ((char *)p > pmax)
+			return(NULL);
+		return ((u_char *)p);
+	}
+	while ( ( *p & 0x3f) != 0x00 ) {
+		s = p + 1;
+		if ( *p == 0x20 )
+			compress = 1;
+		else
+			compress = 0;
+		
+	 	/* Get next length field */
+		p = (u_char *)(p + (*p & 0x3f) + 1);
+		if ((char *)p > pmax) {
+			p = NULL;
+			break;
+		}
+#ifdef DEBUG
+		printf(":");
+#endif
+		while (s < p) {
+			if ( compress == 1 ) {
+				c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11));
+#ifdef DEBUG
+				if (isprint( c ) )
+					printf("%c", c );
+				else
+					printf("<0x%02x>", c );
+#endif
+				s +=2;
+			} else {
+#ifdef DEBUG
+				printf("%c", *s);
+#endif
+				s++;
+			}
+		}
+#ifdef DEBUG
+		printf(":");
+#endif
+		fflush(stdout);
+    }
+
+	/* Set up to out of Name field */
+	if (p == NULL || (char *)p >= pmax)
+	    p = NULL;
+	else
+	    p++;
+	return ((u_char *)p);
+}
+
+/* 
+ * NetBios Datagram Handler (IP/UDP)
+ */
+#define DGM_DIRECT_UNIQ		0x10
+#define DGM_DIRECT_GROUP	0x11
+#define DGM_BROADCAST		0x12
+#define DGM_ERROR			0x13
+#define DGM_QUERY			0x14
+#define DGM_POSITIVE_RES	0x15
+#define DGM_NEGATIVE_RES	0x16
+
+int AliasHandleUdpNbt(
+	struct ip 		  	*pip,	 /* IP packet to examine/patch */
+	struct alias_link 	*link,
+	struct in_addr		*alias_address,
+    u_short 		alias_port
+) {
+    struct udphdr *	uh;
+    NbtDataHeader 	*ndh;
+    u_char		*p = NULL;
+    char		*pmax;
+        
+    /* Calculate data length of UDP packet */
+    uh =  (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
+    pmax = (char *)uh + ntohs( uh->uh_ulen );
+
+	ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr)));
+    if ((char *)(ndh + 1) > pmax)
+	    return(-1);
+#ifdef DEBUG
+	printf("\nType=%02x,", ndh->type );
+#endif
+	switch ( ndh->type ) {
+		case DGM_DIRECT_UNIQ:
+		case DGM_DIRECT_GROUP:
+		case DGM_BROADCAST:
+			p = (u_char *)ndh + 14;
+		    p = AliasHandleName ( p, pmax ); /* Source Name */
+		    p = AliasHandleName ( p, pmax ); /* Destination Name */
+			break;
+		case DGM_ERROR:
+			p = (u_char *)ndh + 11;
+			break;
+		case DGM_QUERY:
+		case DGM_POSITIVE_RES:
+		case DGM_NEGATIVE_RES:
+			p = (u_char *)ndh + 10;
+		    p = AliasHandleName ( p, pmax ); /* Destination Name */
+			break;
+	}
+    if (p == NULL || (char *)p > pmax)
+	    p = NULL;
+#ifdef DEBUG
+	printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
+#endif
+	/* Doing a IP address and Port number Translation */
+	if ( uh->uh_sum != 0 ) {
+		int				acc;
+		u_short			*sptr;
+		acc  = ndh->source_port;
+		acc -= alias_port;
+		sptr = (u_short *) &(ndh->source_ip);
+		acc += *sptr++;
+		acc += *sptr;
+		sptr = (u_short *) alias_address;
+		acc -= *sptr++;
+		acc -= *sptr;
+		ADJUST_CHECKSUM(acc, uh->uh_sum)
+	}
+    ndh->source_ip = *alias_address;
+    ndh->source_port = alias_port;
+#ifdef DEBUG
+	printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
+	fflush(stdout);
+#endif
+    return((p == NULL) ? -1 : 0);
+}
+/* Question Section */
+#define QS_TYPE_NB		0x0020
+#define QS_TYPE_NBSTAT	0x0021
+#define QS_CLAS_IN		0x0001
+typedef struct {
+	u_short	type;	/* The type of Request */
+	u_short	class;	/* The class of Request */
+} NBTNsQuestion;
+
+static u_char *
+AliasHandleQuestion(
+    u_short count,
+							NBTNsQuestion *q,
+    char *pmax,
+							NBTArguments  *nbtarg)
+{
+
+	while ( count != 0 ) {
+		/* Name Filed */
+		q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax);
+
+		if (q == NULL || (char *)(q + 1) > pmax) {
+			q = NULL;
+			break;
+		}
+
+		/* Type and Class filed */
+		switch ( ntohs(q->type) ) {
+			case QS_TYPE_NB:
+			case QS_TYPE_NBSTAT:
+				q= q+1;
+			break;
+			default:
+#ifdef DEBUG
+				printf("\nUnknown Type on Question %0x\n", ntohs(q->type) );
+#endif
+			break;
+		}
+		count--;
+	}
+
+	/* Set up to out of Question Section */
+	return ((u_char *)q);
+}
+
+/* Resource Record */
+#define RR_TYPE_A		0x0001
+#define RR_TYPE_NS		0x0002
+#define RR_TYPE_NULL	0x000a
+#define RR_TYPE_NB		0x0020
+#define RR_TYPE_NBSTAT	0x0021
+#define RR_CLAS_IN		0x0001
+#define SizeOfNsResource	8
+typedef struct {
+ 	u_short type;
+ 	u_short class;
+ 	unsigned int ttl;
+ 	u_short rdlen;
+} NBTNsResource;
+
+#define SizeOfNsRNB			6
+typedef struct {
+	u_short g:1, ont:2, resv:13;
+	struct	in_addr	addr;
+} NBTNsRNB;
+
+static u_char *
+AliasHandleResourceNB( 
+    NBTNsResource *q,
+    char *pmax, 
+							   NBTArguments  *nbtarg)
+{
+	NBTNsRNB	*nb;
+	u_short bcount;
+
+	if (q == NULL || (char *)(q + 1) > pmax)
+		return(NULL);
+	/* Check out a length */
+	bcount = ntohs(q->rdlen);
+
+	/* Forward to Resource NB position */
+	nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource);
+
+	/* Processing all in_addr array */
+#ifdef DEBUG
+	printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
+            printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount);
+#endif
+	while ( nb != NULL && bcount != 0 )  {
+		if ((char *)(nb + 1) > pmax) {
+			nb = NULL;
+			break;
+		}
+#ifdef DEBUG
+		printf("<%s>", inet_ntoa(nb->addr) );
+#endif
+		if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) {
+			if ( *nbtarg->uh_sum != 0 ) {
+            	int acc;
+            	u_short *sptr;
+
+            	sptr = (u_short *) &(nb->addr);
+            	acc = *sptr++;
+            	acc += *sptr;
+            	sptr = (u_short *) &(nbtarg->newaddr);
+            	acc -= *sptr++;
+            	acc -= *sptr;
+            	ADJUST_CHECKSUM(acc, *nbtarg->uh_sum)
+			}
+
+			nb->addr = nbtarg->newaddr;
+#ifdef DEBUG
+			printf("O");
+#endif
+		}
+#ifdef DEBUG
+		 else {
+			printf(".");
+		}
+#endif
+		nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB);
+	 	bcount -= SizeOfNsRNB;
+	}
+	if (nb == NULL || (char *)(nb + 1) > pmax) {
+		nb = NULL;
+	}
+
+	return ((u_char *)nb);
+}
+
+#define SizeOfResourceA		6
+typedef struct {
+	struct	in_addr	addr;
+} NBTNsResourceA;
+
+static u_char *
+AliasHandleResourceA( 
+    NBTNsResource *q,
+    char *pmax,
+						 	  NBTArguments  *nbtarg)
+{
+	NBTNsResourceA	*a;
+	u_short bcount;
+
+	if (q == NULL || (char *)(q + 1) > pmax)
+		return(NULL);
+
+	/* Forward to Resource A position */
+	a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) );
+
+	/* Check out of length */
+	bcount = ntohs(q->rdlen);
+
+	/* Processing all in_addr array */
+#ifdef DEBUG
+	printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
+        printf("->%s]",inet_ntoa(nbtarg->newaddr ));
+#endif
+	while ( bcount != 0 )  {
+		if (a == NULL || (char *)(a + 1) > pmax)
+			return(NULL);
+#ifdef DEBUG
+		printf("..%s", inet_ntoa(a->addr) );
+#endif
+		if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) {
+			if ( *nbtarg->uh_sum != 0 ) {
+            	int acc;
+            	u_short *sptr;
+
+            	sptr = (u_short *) &(a->addr);		 /* Old */
+            	acc = *sptr++;
+            	acc += *sptr;
+            	sptr = (u_short *) &nbtarg->newaddr; /* New */
+            	acc -= *sptr++;
+            	acc -= *sptr;
+            	ADJUST_CHECKSUM(acc, *nbtarg->uh_sum)
+			}
+
+			a->addr = nbtarg->newaddr;
+		}
+		a++;	/*XXXX*/
+		bcount -= SizeOfResourceA;
+	}
+	if (a == NULL || (char *)(a + 1) > pmax)
+		a =  NULL;
+	return ((u_char *)a);
+}
+
+typedef struct {
+	u_short opcode:4, flags:8, resv:4;
+} NBTNsResourceNULL;
+
+static u_char *
+AliasHandleResourceNULL( 
+    NBTNsResource *q, 
+    char *pmax,
+						 	     NBTArguments  *nbtarg)
+{
+	NBTNsResourceNULL	*n;
+	u_short bcount;
+
+	if (q == NULL || (char *)(q + 1) > pmax)
+		return(NULL);
+
+	/* Forward to Resource NULL position */
+	n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
+
+	/* Check out of length */
+	bcount = ntohs(q->rdlen);
+
+	/* Processing all in_addr array */
+	while ( bcount != 0 )  {
+		if ((char *)(n + 1) > pmax) {
+			n = NULL;
+			break;
+		}
+		n++;
+		bcount -= sizeof(NBTNsResourceNULL);
+	}
+	if ((char *)(n + 1) > pmax)
+		n = NULL;
+
+	return ((u_char *)n);
+}
+
+static u_char *
+AliasHandleResourceNS( 
+    NBTNsResource *q,
+    char *pmax,
+						 	     NBTArguments  *nbtarg)
+{
+	NBTNsResourceNULL	*n;
+	u_short bcount;
+
+	if (q == NULL || (char *)(q + 1) > pmax)
+		return(NULL);
+
+	/* Forward to Resource NULL position */
+	n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
+
+	/* Check out of length */
+	bcount = ntohs(q->rdlen);
+
+	/* Resource Record Name Filed */
+	q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */
+
+	if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
+		return(NULL);
+	else
+	return ((u_char *)n + bcount);
+}
+
+typedef struct {
+	u_short	numnames;
+} NBTNsResourceNBSTAT;
+
+static u_char *
+AliasHandleResourceNBSTAT(
+    NBTNsResource *q,
+    char *pmax,
+						 	       NBTArguments  *nbtarg)
+{
+	NBTNsResourceNBSTAT	*n;
+	u_short bcount;
+
+	if (q == NULL || (char *)(q + 1) > pmax)
+		return(NULL);
+
+	/* Forward to Resource NBSTAT position */
+	n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) );
+
+	/* Check out of length */
+	bcount = ntohs(q->rdlen);
+
+	if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
+		return(NULL);
+	else
+	return ((u_char *)n + bcount);
+}
+
+static u_char *
+AliasHandleResource(
+    u_short count, 
+							NBTNsResource *q,
+    char *pmax,
+    NBTArguments  
+    *nbtarg)
+{
+	while ( count != 0 ) {
+		/* Resource Record Name Filed */
+		q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax );
+
+		if (q == NULL || (char *)(q + 1) > pmax)
+			break;
+#ifdef DEBUG
+		printf("type=%02x, count=%d\n", ntohs(q->type), count );
+#endif
+
+		/* Type and Class filed */
+		switch ( ntohs(q->type) ) {
+			case RR_TYPE_NB:
+				q = (NBTNsResource *)AliasHandleResourceNB( 
+				    q,
+				    pmax,
+				    nbtarg 
+				);
+				break;
+			case RR_TYPE_A: 
+				q = (NBTNsResource *)AliasHandleResourceA( 
+				    q, 
+				    pmax, 
+				    nbtarg
+				);
+				break;
+			case RR_TYPE_NS:
+				q = (NBTNsResource *)AliasHandleResourceNS( 
+				    q,
+				    pmax, 
+				    nbtarg 
+				);
+				break;
+			case RR_TYPE_NULL:
+				q = (NBTNsResource *)AliasHandleResourceNULL( 
+				    q, 
+				    pmax, 
+				    nbtarg 
+				);
+				break;
+			case RR_TYPE_NBSTAT:
+				q = (NBTNsResource *)AliasHandleResourceNBSTAT(
+				    q,
+				    pmax, 
+				    nbtarg
+				);
+				break;
+			default: 
+#ifdef DEBUG
+				printf(
+				    "\nUnknown Type of Resource %0x\n", 
+				    ntohs(q->type) 
+				);
+#endif
+				break;
+		}
+		count--;
+	}
+	fflush(stdout);
+	return ((u_char *)q);
+}
+
+int AliasHandleUdpNbtNS(
+	struct ip 		  	*pip,	 /* IP packet to examine/patch */
+	struct alias_link 	*link,
+	struct in_addr		*alias_address,
+	u_short 			*alias_port,
+	struct in_addr		*original_address,
+	u_short 			*original_port )
+{
+    struct udphdr *	uh;
+	NbtNSHeader	  * nsh;
+	u_char		  * p;
+	char		*pmax;
+	NBTArguments    nbtarg;
+
+	/* Set up Common Parameter */	
+	nbtarg.oldaddr	=	*alias_address;
+	nbtarg.oldport	=	*alias_port;
+	nbtarg.newaddr	=	*original_address;
+	nbtarg.newport	=	*original_port;
+
+    /* Calculate data length of UDP packet */
+    uh =  (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
+	nbtarg.uh_sum	=	&(uh->uh_sum);
+	nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr)));
+	p = (u_char *)(nsh + 1);
+    pmax = (char *)uh + ntohs( uh->uh_ulen );
+
+    if ((char *)(nsh + 1) > pmax)
+	return(-1);
+
+#ifdef DEBUG
+    printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
+	   ", an=%04x, ns=%04x, ar=%04x, [%d]-->", 
+		nsh->dir ? "Response": "Request",
+		nsh->nametrid,
+		nsh->opcode,
+		nsh->nmflags,
+		nsh->rcode,
+		ntohs(nsh->qdcount),
+		ntohs(nsh->ancount),
+		ntohs(nsh->nscount),
+		ntohs(nsh->arcount),
+	(u_char *)p -(u_char *)nsh
+    );
+#endif
+
+	/* Question Entries */
+	if (ntohs(nsh->qdcount) !=0 ) {
+	p = AliasHandleQuestion(
+	    ntohs(nsh->qdcount),
+	    (NBTNsQuestion *)p,
+	    pmax, 
+	    &nbtarg 
+	);
+	}
+
+	/* Answer Resource Records */
+	if (ntohs(nsh->ancount) !=0 ) {
+	p = AliasHandleResource(
+	    ntohs(nsh->ancount),
+	    (NBTNsResource *)p,
+	    pmax, 
+	    &nbtarg 
+	);
+	}
+
+	/* Authority Resource Recodrs */
+	if (ntohs(nsh->nscount) !=0 ) {
+	p = AliasHandleResource(
+	    ntohs(nsh->nscount), 
+	    (NBTNsResource *)p,
+	    pmax, 
+	    &nbtarg 
+	);
+	}
+
+	/* Additional Resource Recodrs */
+	if (ntohs(nsh->arcount) !=0 ) {
+	p = AliasHandleResource(
+	    ntohs(nsh->arcount),
+	    (NBTNsResource *)p,
+	    pmax, 
+	    &nbtarg 
+	);
+	}
+
+#ifdef DEBUG
+	 	PrintRcode(nsh->rcode);
+#endif
+    return ((p == NULL) ? -1 : 0);
+}
diff --git a/alias/alias_proxy.c b/alias/alias_proxy.c
new file mode 100644
index 0000000..60437bf
--- /dev/null
+++ b/alias/alias_proxy.c
@@ -0,0 +1,805 @@
+/* file: alias_proxy.c
+
+    This file encapsulates special operations related to transparent
+    proxy redirection.  This is where packets with a particular destination,
+    usually tcp port 80, are redirected to a proxy server.
+
+    When packets are proxied, the destination address and port are
+    modified.  In certain cases, it is necessary to somehow encode
+    the original address/port info into the packet.  Two methods are
+    presently supported: addition of a [DEST addr port] string at the
+    beginning a of tcp stream, or inclusion of an optional field
+    in the IP header.
+    
+    There is one public API function:
+
+        PacketAliasProxyRule()    -- Adds and deletes proxy
+                                     rules.
+
+    Rules are stored in a linear linked list, so lookup efficiency
+    won't be too good for large lists.
+
+
+    Initial development: April, 1998 (cjm)
+*/
+
+
+/* System includes */
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/* BSD IPV4 includes */
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <arpa/inet.h>
+
+#include "alias_local.h"  /* Functions used by alias*.c */
+#include "alias.h"        /* Public API functions for libalias */
+
+
+
+/*
+    Data structures
+ */
+
+/*
+ * A linked list of arbitrary length, based on struct proxy_entry is
+ * used to store proxy rules.
+ */
+struct proxy_entry
+{
+#define PROXY_TYPE_ENCODE_NONE      1
+#define PROXY_TYPE_ENCODE_TCPSTREAM 2
+#define PROXY_TYPE_ENCODE_IPHDR     3
+    int rule_index;
+    int proxy_type;
+    u_char proto;
+    u_short proxy_port;
+    u_short server_port;
+
+    struct in_addr server_addr;
+
+    struct in_addr src_addr;
+    struct in_addr src_mask;
+
+    struct in_addr dst_addr;
+    struct in_addr dst_mask;
+
+    struct proxy_entry *next;
+    struct proxy_entry *last;
+};
+
+
+
+/*
+    File scope variables
+*/
+
+static struct proxy_entry *proxyList;
+
+
+
+/* Local (static) functions:
+
+    IpMask()                 -- Utility function for creating IP
+                                masks from integer (1-32) specification.
+    IpAddr()                 -- Utility function for converting string
+                                to IP address
+    IpPort()                 -- Utility function for converting string
+                                to port number
+    RuleAdd()                -- Adds an element to the rule list.
+    RuleDelete()             -- Removes an element from the rule list.
+    RuleNumberDelete()       -- Removes all elements from the rule list
+                                having a certain rule number.
+    ProxyEncodeTcpStream()   -- Adds [DEST x.x.x.x xxxx] to the beginning
+                                of a TCP stream.
+    ProxyEncodeIpHeader()    -- Adds an IP option indicating the true
+                                destination of a proxied IP packet
+*/
+
+static int IpMask(int, struct in_addr *);
+static int IpAddr(char *, struct in_addr *);
+static int IpPort(char *, int, int *);
+static void RuleAdd(struct proxy_entry *);
+static void RuleDelete(struct proxy_entry *);
+static int RuleNumberDelete(int);
+static void ProxyEncodeTcpStream(struct alias_link *, struct ip *, int);
+static void ProxyEncodeIpHeader(struct ip *, int);
+
+static int
+IpMask(int nbits, struct in_addr *mask)
+{
+    int i;
+    u_int imask;
+
+    if (nbits < 0 || nbits > 32)
+        return -1;
+
+    imask = 0;
+    for (i=0; i<nbits; i++)
+        imask = (imask >> 1) + 0x80000000;
+    mask->s_addr = htonl(imask);
+
+    return 0;
+}
+
+static int
+IpAddr(char *s, struct in_addr *addr)
+{
+    if (inet_aton(s, addr) == 0)
+        return -1;
+    else
+        return 0;
+}
+
+static int
+IpPort(char *s, int proto, int *port)
+{
+    int n;
+
+    n = sscanf(s, "%d", port);
+    if (n != 1)
+    {
+        struct servent *se;
+
+        if (proto == IPPROTO_TCP)
+            se = getservbyname(s, "tcp");
+        else if (proto == IPPROTO_UDP)
+            se = getservbyname(s, "udp");
+        else
+            return -1;
+
+        if (se == NULL)
+                return -1;
+
+        *port = (u_int) ntohs(se->s_port);
+    }
+
+    return 0;
+}
+
+void
+RuleAdd(struct proxy_entry *entry)
+{
+    int rule_index;
+    struct proxy_entry *ptr;
+    struct proxy_entry *ptr_last;
+
+    if (proxyList == NULL)
+    {
+        proxyList = entry;
+        entry->last = NULL;
+        entry->next = NULL;
+        return;
+    }
+
+    rule_index = entry->rule_index;
+    ptr = proxyList;
+    ptr_last = NULL;
+    while (ptr != NULL)
+    {
+        if (ptr->rule_index >= rule_index)
+        {
+            if (ptr_last == NULL)
+            {
+                entry->next = proxyList;
+                entry->last = NULL;
+                proxyList->last = entry;
+                proxyList = entry;
+                return;
+            }
+
+            ptr_last->next = entry;
+            ptr->last = entry;
+            entry->last = ptr->last;
+            entry->next = ptr;
+            return;
+        }
+        ptr_last = ptr;
+        ptr = ptr->next;
+    }
+
+    ptr_last->next = entry;
+    entry->last = ptr_last;
+    entry->next = NULL;
+}
+
+static void
+RuleDelete(struct proxy_entry *entry)
+{
+    if (entry->last != NULL)
+        entry->last->next = entry->next;
+    else
+        proxyList = entry->next;
+
+    if (entry->next != NULL)
+        entry->next->last = entry->last;
+
+    free(entry);
+}
+
+static int
+RuleNumberDelete(int rule_index)
+{
+    int err;
+    struct proxy_entry *ptr;
+
+    err = -1;
+    ptr = proxyList;
+    while (ptr != NULL)
+    {
+        struct proxy_entry *ptr_next;
+
+        ptr_next = ptr->next;
+        if (ptr->rule_index == rule_index)
+        {
+            err = 0;
+            RuleDelete(ptr);
+        }
+
+        ptr = ptr_next;
+    }
+
+    return err;
+}
+
+static void
+ProxyEncodeTcpStream(struct alias_link *link,
+                     struct ip *pip,
+                     int maxpacketsize)
+{
+    int slen;
+    char buffer[40];
+    struct tcphdr *tc;
+
+/* Compute pointer to tcp header */
+    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+/* Don't modify if once already modified */
+
+    if (GetAckModified (link))
+	return;
+
+/* Translate destination address and port to string form */
+    snprintf(buffer, sizeof(buffer) - 2, "[DEST %s %d]",
+        inet_ntoa(GetProxyAddress (link)), (u_int) ntohs(GetProxyPort (link)));
+    
+/* Pad string out to a multiple of two in length */
+    slen = strlen(buffer);
+    switch (slen % 2)
+    {
+    case 0:
+        strcat(buffer, " \n");
+	slen += 2;
+        break;
+    case 1:
+        strcat(buffer, "\n");
+	slen += 1;
+    }
+
+/* Check for packet overflow */
+    if ((ntohs(pip->ip_len) + strlen(buffer)) > maxpacketsize)
+        return;
+
+/* Shift existing TCP data and insert destination string */
+    {
+        int dlen;
+        int hlen;
+        u_char *p;
+
+        hlen = (pip->ip_hl + tc->th_off) << 2;
+        dlen = ntohs (pip->ip_len) - hlen;
+
+/* Modify first packet that has data in it */
+
+	if (dlen == 0)
+		return;
+
+        p = (char *) pip;
+        p += hlen;
+
+        memmove(p + slen, p, dlen);
+        memcpy(p, buffer, slen);
+    }
+
+/* Save information about modfied sequence number */
+    {
+        int delta;
+
+        SetAckModified(link);
+        delta = GetDeltaSeqOut(pip, link);
+        AddSeq(pip, link, delta+slen);
+    }
+
+/* Update IP header packet length and checksum */
+    {
+        int accumulate;
+
+        accumulate  = pip->ip_len;
+        pip->ip_len = htons(ntohs(pip->ip_len) + slen);
+        accumulate -= pip->ip_len;
+
+        ADJUST_CHECKSUM(accumulate, pip->ip_sum);
+    }
+
+/* Update TCP checksum, Use TcpChecksum since so many things have
+   already changed. */
+
+    tc->th_sum = 0;
+    tc->th_sum = TcpChecksum (pip);
+}
+
+static void
+ProxyEncodeIpHeader(struct ip *pip,
+                    int maxpacketsize)
+{
+#define OPTION_LEN_BYTES  8
+#define OPTION_LEN_INT16  4
+#define OPTION_LEN_INT32  2
+    u_char option[OPTION_LEN_BYTES];
+
+#ifdef DEBUG
+    fprintf(stdout, " ip cksum 1 = %x\n", (u_int) IpChecksum(pip));
+    fprintf(stdout, "tcp cksum 1 = %x\n", (u_int) TcpChecksum(pip));
+#endif
+
+/* Check to see that there is room to add an IP option */
+    if (pip->ip_hl > (0x0f - OPTION_LEN_INT32))
+        return;
+
+/* Build option and copy into packet */
+    {
+        u_char *ptr;
+        struct tcphdr *tc;
+
+        ptr = (u_char *) pip;
+        ptr += 20;
+        memcpy(ptr + OPTION_LEN_BYTES, ptr, ntohs(pip->ip_len) - 20);
+
+        option[0] = 0x64; /* class: 3 (reserved), option 4 */
+        option[1] = OPTION_LEN_BYTES;
+
+        memcpy(&option[2], (u_char *) &pip->ip_dst, 4);
+
+        tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+        memcpy(&option[6], (u_char *) &tc->th_sport, 2);
+
+        memcpy(ptr, option, 8);
+    }
+
+/* Update checksum, header length and packet length */
+    {
+        int i;
+        int accumulate;
+        u_short *sptr;
+
+        sptr = (u_short *) option;
+        accumulate = 0;
+        for (i=0; i<OPTION_LEN_INT16; i++)
+            accumulate -= *(sptr++);
+
+        sptr = (u_short *) pip;
+        accumulate += *sptr;
+        pip->ip_hl += OPTION_LEN_INT32;
+        accumulate -= *sptr;
+
+        accumulate += pip->ip_len;
+        pip->ip_len = htons(ntohs(pip->ip_len) + OPTION_LEN_BYTES);
+        accumulate -= pip->ip_len;
+
+        ADJUST_CHECKSUM(accumulate, pip->ip_sum);
+    }
+#undef OPTION_LEN_BYTES
+#undef OPTION_LEN_INT16
+#undef OPTION_LEN_INT32
+#ifdef DEBUG
+    fprintf(stdout, " ip cksum 2 = %x\n", (u_int) IpChecksum(pip));
+    fprintf(stdout, "tcp cksum 2 = %x\n", (u_int) TcpChecksum(pip));
+#endif
+}
+
+
+/* Functions by other packet alias source files
+
+    ProxyCheck()         -- Checks whether an outgoing packet should
+                            be proxied.
+    ProxyModify()        -- Encodes the original destination address/port
+                            for a packet which is to be redirected to
+                            a proxy server.
+*/
+
+int
+ProxyCheck(struct ip *pip,
+           struct in_addr *proxy_server_addr,
+           u_short *proxy_server_port)
+{
+    u_short dst_port;
+    struct in_addr src_addr;
+    struct in_addr dst_addr;
+    struct proxy_entry *ptr;
+
+    src_addr = pip->ip_src;
+    dst_addr = pip->ip_dst;
+    dst_port = ((struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)))
+        ->th_dport;
+
+    ptr = proxyList;
+    while (ptr != NULL)
+    {
+        u_short proxy_port;
+
+        proxy_port = ptr->proxy_port;
+        if ((dst_port == proxy_port || proxy_port == 0)
+         && pip->ip_p == ptr->proto
+         && src_addr.s_addr != ptr->server_addr.s_addr)
+        {
+            struct in_addr src_addr_masked;
+            struct in_addr dst_addr_masked;
+
+            src_addr_masked.s_addr = src_addr.s_addr & ptr->src_mask.s_addr;
+            dst_addr_masked.s_addr = dst_addr.s_addr & ptr->dst_mask.s_addr;
+
+            if ((src_addr_masked.s_addr == ptr->src_addr.s_addr)
+             && (dst_addr_masked.s_addr == ptr->dst_addr.s_addr))
+            {
+                if ((*proxy_server_port = ptr->server_port) == 0)
+                    *proxy_server_port = dst_port;
+                *proxy_server_addr = ptr->server_addr;
+                return ptr->proxy_type;
+            }
+        }
+        ptr = ptr->next;
+    }
+
+    return 0;
+}
+
+void
+ProxyModify(struct alias_link *link,
+            struct ip *pip,
+            int maxpacketsize,
+            int proxy_type)
+{
+    switch (proxy_type)
+    {
+    case PROXY_TYPE_ENCODE_IPHDR:
+        ProxyEncodeIpHeader(pip, maxpacketsize);
+        break;
+
+    case PROXY_TYPE_ENCODE_TCPSTREAM:
+        ProxyEncodeTcpStream(link, pip, maxpacketsize);
+        break;
+    }
+}
+
+
+/*
+    Public API functions
+*/
+
+int
+PacketAliasProxyRule(const char *cmd)
+{
+/*
+ * This function takes command strings of the form:
+ *
+ *   server <addr>[:<port>]
+ *   [port <port>]
+ *   [rule n]
+ *   [proto tcp|udp]
+ *   [src <addr>[/n]]
+ *   [dst <addr>[/n]]
+ *   [type encode_tcp_stream|encode_ip_hdr|no_encode]
+ *
+ *   delete <rule number>
+ *
+ * Subfields can be in arbitrary order.  Port numbers and addresses
+ * must be in either numeric or symbolic form. An optional rule number
+ * is used to control the order in which rules are searched.  If two
+ * rules have the same number, then search order cannot be guaranteed,
+ * and the rules should be disjoint.  If no rule number is specified,
+ * then 0 is used, and group 0 rules are always checked before any
+ * others.
+ */
+    int i, n, len;
+    int cmd_len;
+    int token_count;
+    int state;
+    char *token;
+    char buffer[256];
+    char str_port[sizeof(buffer)];
+    char str_server_port[sizeof(buffer)];
+
+    int rule_index;
+    int proto;
+    int proxy_type;
+    int proxy_port;
+    int server_port;
+    struct in_addr server_addr;
+    struct in_addr src_addr, src_mask;
+    struct in_addr dst_addr, dst_mask;
+    struct proxy_entry *proxy_entry;
+
+/* Copy command line into a buffer */
+    cmd_len = strlen(cmd);
+    if (cmd_len > (sizeof(buffer) - 1))
+        return -1;
+    strcpy(buffer, cmd);
+
+/* Convert to lower case */
+    len = strlen(buffer);
+    for (i=0; i<len; i++)
+        buffer[i] = tolower(buffer[i]);
+
+/* Set default proxy type */
+
+/* Set up default values */
+    rule_index = 0;
+    proxy_type = PROXY_TYPE_ENCODE_NONE;
+    proto = IPPROTO_TCP;
+    proxy_port = 0;
+    server_addr.s_addr = 0;
+    server_port = 0;
+    src_addr.s_addr = 0;
+    IpMask(0, &src_mask);
+    dst_addr.s_addr = 0;
+    IpMask(0, &dst_mask);
+
+    str_port[0] = 0;
+    str_server_port[0] = 0;
+
+/* Parse command string with state machine */
+#define STATE_READ_KEYWORD    0
+#define STATE_READ_TYPE       1
+#define STATE_READ_PORT       2
+#define STATE_READ_SERVER     3
+#define STATE_READ_RULE       4
+#define STATE_READ_DELETE     5
+#define STATE_READ_PROTO      6
+#define STATE_READ_SRC        7
+#define STATE_READ_DST        8
+    state = STATE_READ_KEYWORD;
+    token = strtok(buffer, " \t");
+    token_count = 0;
+    while (token != NULL)
+    {
+        token_count++;
+        switch (state)
+        {
+        case STATE_READ_KEYWORD:
+            if (strcmp(token, "type") == 0)
+                state = STATE_READ_TYPE;
+            else if (strcmp(token, "port") == 0)
+                state = STATE_READ_PORT;
+            else if (strcmp(token, "server") == 0)
+                state = STATE_READ_SERVER;
+            else if (strcmp(token, "rule") == 0)
+                state = STATE_READ_RULE;
+            else if (strcmp(token, "delete") == 0)
+                state = STATE_READ_DELETE;
+            else if (strcmp(token, "proto") == 0)
+                state = STATE_READ_PROTO;
+            else if (strcmp(token, "src") == 0)
+                state = STATE_READ_SRC;
+            else if (strcmp(token, "dst") == 0)
+                state = STATE_READ_DST;
+            else
+                return -1;
+            break;
+
+        case STATE_READ_TYPE:
+            if (strcmp(token, "encode_ip_hdr") == 0)
+                proxy_type = PROXY_TYPE_ENCODE_IPHDR;
+            else if (strcmp(token, "encode_tcp_stream") == 0)
+                proxy_type = PROXY_TYPE_ENCODE_TCPSTREAM;
+            else if (strcmp(token, "no_encode") == 0)
+                proxy_type = PROXY_TYPE_ENCODE_NONE;
+            else
+                return -1;
+            state = STATE_READ_KEYWORD;
+            break;
+
+        case STATE_READ_PORT:
+            strcpy(str_port, token);
+            state = STATE_READ_KEYWORD;
+            break;
+
+        case STATE_READ_SERVER:
+            {
+                int err;
+                char *p;
+                char s[sizeof(buffer)];
+
+                p = token;
+                while (*p != ':' && *p != 0)
+                    p++;
+
+                if (*p != ':')
+                {
+                    err = IpAddr(token, &server_addr);
+                    if (err)
+                        return -1;
+                }
+                else
+                {
+                    *p = ' ';
+                
+                    n = sscanf(token, "%s %s", s, str_server_port);
+                    if (n != 2)
+                        return -1;
+
+                    err = IpAddr(s, &server_addr);
+                    if (err)
+                        return -1;
+                }
+            }
+            state = STATE_READ_KEYWORD;
+            break;
+
+        case STATE_READ_RULE:
+            n = sscanf(token, "%d", &rule_index);
+            if (n != 1 || rule_index < 0)
+                return -1;
+            state = STATE_READ_KEYWORD;
+            break;
+
+        case STATE_READ_DELETE:
+            {
+                int err;
+                int rule_to_delete;
+
+                if (token_count != 2)
+                    return -1;
+
+                n = sscanf(token, "%d", &rule_to_delete);
+                if (n != 1)
+                    return -1;
+                err = RuleNumberDelete(rule_to_delete);
+                if (err)
+                    return -1;
+                return 0;
+            }
+
+        case STATE_READ_PROTO:
+            if (strcmp(token, "tcp") == 0)
+                proto = IPPROTO_TCP;
+            else if (strcmp(token, "udp") == 0)
+                proto = IPPROTO_UDP;
+            else
+                return -1;
+            state = STATE_READ_KEYWORD;
+            break;
+
+        case STATE_READ_SRC:
+        case STATE_READ_DST:
+            {
+                int err;
+                char *p;
+                struct in_addr mask;
+                struct in_addr addr;
+
+                p = token;
+                while (*p != '/' && *p != 0)
+                    p++;
+
+                if (*p != '/')
+                {
+                     IpMask(32, &mask);
+                     err = IpAddr(token, &addr);
+                     if (err)
+                         return -1;
+                }
+                else
+                {
+                    int n;
+                    int nbits;
+                    char s[sizeof(buffer)];
+
+                    *p = ' ';
+                    n = sscanf(token, "%s %d", s, &nbits);
+                    if (n != 2)
+                        return -1;
+
+                    err = IpAddr(s, &addr);
+                    if (err)
+                        return -1;
+
+                    err = IpMask(nbits, &mask);
+                    if (err)
+                        return -1;
+                }
+
+                if (state == STATE_READ_SRC)
+                {
+                    src_addr = addr;
+                    src_mask = mask;
+                }
+                else 
+                {
+                    dst_addr = addr;
+                    dst_mask = mask;
+                }
+            }
+            state = STATE_READ_KEYWORD;
+            break;
+
+        default:
+            return -1;
+            break;
+        }
+
+        token = strtok(NULL, " \t");
+    }
+#undef STATE_READ_KEYWORD
+#undef STATE_READ_TYPE
+#undef STATE_READ_PORT
+#undef STATE_READ_SERVER
+#undef STATE_READ_RULE
+#undef STATE_READ_DELETE
+#undef STATE_READ_PROTO
+#undef STATE_READ_SRC
+#undef STATE_READ_DST
+
+/* Convert port strings to numbers.  This needs to be done after
+   the string is parsed, because the prototype might not be designated
+   before the ports (which might be symbolic entries in /etc/services) */
+
+    if (strlen(str_port) != 0)
+    {
+        int err;
+
+        err = IpPort(str_port, proto, &proxy_port);
+        if (err)
+            return -1;
+    }
+    else
+    {
+        proxy_port = 0;
+    }
+
+    if (strlen(str_server_port) != 0)
+    { 
+        int err;
+
+        err = IpPort(str_server_port, proto, &server_port);
+        if (err)
+            return -1;
+    }
+    else
+    {
+        server_port = 0;
+    }
+
+/* Check that at least the server address has been defined */
+    if (server_addr.s_addr == 0)
+        return -1;
+
+/* Add to linked list */
+    proxy_entry = malloc(sizeof(struct proxy_entry));
+    if (proxy_entry == NULL)
+        return -1;
+
+    proxy_entry->proxy_type = proxy_type;
+    proxy_entry->rule_index = rule_index;
+    proxy_entry->proto = proto;
+    proxy_entry->proxy_port = htons(proxy_port);
+    proxy_entry->server_port = htons(server_port);
+    proxy_entry->server_addr = server_addr;
+    proxy_entry->src_addr.s_addr = src_addr.s_addr & src_mask.s_addr;
+    proxy_entry->dst_addr.s_addr = dst_addr.s_addr & dst_mask.s_addr;
+    proxy_entry->src_mask = src_mask;
+    proxy_entry->dst_mask = dst_mask;
+
+    RuleAdd(proxy_entry);
+
+    return 0;
+}
diff --git a/alias/alias_util.c b/alias/alias_util.c
new file mode 100644
index 0000000..fe07653
--- /dev/null
+++ b/alias/alias_util.c
@@ -0,0 +1,137 @@
+/*
+    Alias_util.h contains general utilities used by other functions
+    in the packet aliasing module.  At the moment, there are functions
+    for computing IP header and TCP packet checksums.
+
+    The checksum routines are based upon example code in a Unix networking
+    text written by Stevens (sorry, I can't remember the title -- but
+    at least this is a good author).
+
+    Initial Version:  August, 1996  (cjm)
+
+    Version 1.7:  January 9, 1997
+         Added differential checksum update function.
+*/
+
+/*
+Note: the checksum routines assume that the actual checksum word has
+been zeroed out.  If the checksum workd is filled with the proper value,
+then these routines will give a result of zero (useful for testing
+purposes);
+*/
+    
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include "alias.h"
+#include "alias_local.h"
+
+u_short
+PacketAliasInternetChecksum(u_short *ptr, int nbytes)
+{
+    int sum, oddbyte;
+
+    sum = 0;
+    while (nbytes > 1)
+    {
+        sum += *ptr++;
+        nbytes -= 2;
+    }
+    if (nbytes == 1)
+    {
+        oddbyte = 0;
+        *((u_char *) &oddbyte) = *(u_char *) ptr;
+        sum += oddbyte;
+    }
+    sum = (sum >> 16) + (sum & 0xffff);
+    sum += (sum >> 16);
+    return(~sum);
+}
+
+u_short
+IpChecksum(struct ip *pip)
+{
+    return( PacketAliasInternetChecksum((u_short *) pip,
+            (pip->ip_hl << 2)) );
+
+}
+
+u_short 
+TcpChecksum(struct ip *pip)
+{
+    u_short *ptr;
+    struct tcphdr *tc;
+    int nhdr, ntcp, nbytes;
+    int sum, oddbyte;
+
+    nhdr = pip->ip_hl << 2;
+    ntcp = ntohs(pip->ip_len) - nhdr;
+
+    tc = (struct tcphdr *) ((char *) pip + nhdr);
+    ptr = (u_short *) tc;
+    
+/* Add up TCP header and data */
+    nbytes = ntcp;
+    sum = 0;
+    while (nbytes > 1)
+    {
+        sum += *ptr++;
+        nbytes -= 2;
+    }
+    if (nbytes == 1)
+    {
+        oddbyte = 0;
+        *((u_char *) &oddbyte) = *(u_char *) ptr;
+        sum += oddbyte;
+    }
+
+/* "Pseudo-header" data */
+    ptr = (u_short *) &(pip->ip_dst);
+    sum += *ptr++;
+    sum += *ptr;
+    ptr = (u_short *) &(pip->ip_src);
+    sum += *ptr++;
+    sum += *ptr;
+    sum += htons((u_short) ntcp);
+    sum += htons((u_short) pip->ip_p);
+
+/* Roll over carry bits */
+    sum = (sum >> 16) + (sum & 0xffff);
+    sum += (sum >> 16);
+
+/* Return checksum */
+    return((u_short) ~sum);
+}
+
+
+void
+DifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n)
+{
+    int i;
+    int accumulate;
+
+    accumulate = *cksum;
+    for (i=0; i<n; i++)
+    {
+        accumulate -= *new++;
+        accumulate += *old++;
+    }
+
+    if (accumulate < 0)
+    {
+        accumulate = -accumulate;
+        accumulate = (accumulate >> 16) + (accumulate & 0xffff);
+        accumulate += accumulate >> 16;
+        *cksum = (u_short) ~accumulate;
+    }
+    else
+    {
+        accumulate = (accumulate >> 16) + (accumulate & 0xffff);
+        accumulate += accumulate >> 16;
+        *cksum = (u_short) accumulate;
+    }
+}
+
diff --git a/arp.tproj/Makefile b/arp.tproj/Makefile
new file mode 100644
index 0000000..50e5151
--- /dev/null
+++ b/arp.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = arp
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = arp.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble arp4.4 arp.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/arp.tproj/Makefile.postamble b/arp.tproj/Makefile.postamble
new file mode 100644
index 0000000..3b11434
--- /dev/null
+++ b/arp.tproj/Makefile.postamble
@@ -0,0 +1,115 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app)
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+
+
+# Change defaults assumed by the standard app makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if
+# you would like changes to them to invalidate previous builds.  The project
+# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build.
+#MAKEFILES = Makefile 
+
+# Optimization flag passed to compiler:
+#OPTIMIZATION_CFLAG = -O
+
+# Flags always passed to compiler:
+#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall  
+
+# Flags passed to compiler in normal 'app' compiles:
+#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG)
+
+# Flags passed to compiler in 'debug' compiles:
+#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG
+
+# Flags passed to compiler in 'profile' compiles
+#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User to chown app to
+#INSTALL_AS_GROUP = wheel      # Group to chgrp app to 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for bundles, apps with bundles, and apps without bundles, 
+# respectively.
+#RELOCATABLE_STRIP_OPTS = -x -u
+#DYLD_APP_STRIP_OPTS = -A -n
+#APP_STRIP_OPTS = 
+#TOOL_STRIP_OPTS = 
+#LIBRARY_STRIP_OPTS = -x -S   # Note: -S strips debugging symbols
+# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but
+#  developers doing their own dynamic loading should set this to 
+#  $(DYLD_APP_STRIP_OPTS)).
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Typical 
+# user-defined rules are before_install and after_install (please don't 
+# redefine things like install or app, as they are owned by the top-level 
+# Makefile API), which are rules that get invoked before and after the install 
+# target runs.  Such rules should be specified with the '::' syntax rather than 
+# a single colon.
+
+beforeinstall:
+	install -c -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} arp4.0 \
+	    ${DESTDIR}${MANDIR}4/arp.0
+
diff --git a/arp.tproj/Makefile.preamble b/arp.tproj/Makefile.preamble
new file mode 100644
index 0000000..c7802b8
--- /dev/null
+++ b/arp.tproj/Makefile.preamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags here.  To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+#OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+
+BUNDLELDFLAGS =            # use iff project is a bundle
+PALETTELDFLAGS =           # use iff project is a palette
+
+## Specify which headers in this project should be published to the outside 
+## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be 
+## prepended by DSTROOT, below.  Any subset of these public headers can be
+## precompiled automatically after installation, with extra user-defined flags.
+PUBLIC_HEADER_DIR = 
+PUBLIC_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+## Configure what is linked in at each level here.  Libraries are only used in
+## the final 'app' linking step.  Final 'app' linking is only done via the
+## 'app', 'debug', and 'profile' targets when they are invoked for
+## the top-level app.
+
+# Additional relocatables to be linked in at this level
+OTHER_OFILES = 
+# Additional libs to link apps against ('app' target)
+#OTHER_LIBS = 
+# Additional libs to link apps against ('debug' target)
+OTHER_DEBUG_LIBS = 
+# Additional libs to link apps against ('profile' target)
+OTHER_PROF_LIBS = 
+
+# More 'app' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# More 'debug' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_DEBUG_LIBS = 
+# More 'profile' libs when $(JAPANESE) = "YES"
+OTHER_JAPANESE_PROF_LIBS = 
+
+# If this is a bundle, and you *know* the enclosing application will not
+# be linking with a library which you require in your bundle code, then
+# mention it here so that it gets linked into the bundle.  Note that this
+# is wasteful but sometimes necessary.
+BUNDLE_LIBS = 
+
+## Configure how things get built here.  Additional dependencies, sourcefiles, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = arp4.0
+# Precompiled headers to be built before any compilation occurs (e.g., draw.p)
+PRECOMPS = 
+
+# Targets to be built before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# Set the following to "YES" if you want the old behavior of recursively
+# cleaning all nested subprojects during 'make clean'.
+CLEAN_ALL_SUBPROJECTS =
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+# To include a version string, project source must exist in a directory named
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/arp.tproj/PB.project b/arp.tproj/PB.project
new file mode 100644
index 0000000..237a43f
--- /dev/null
+++ b/arp.tproj/PB.project
@@ -0,0 +1,41 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (arp.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, arp4.4, arp.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = arp; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/arp.tproj/arp.8 b/arp.tproj/arp.8
new file mode 100644
index 0000000..313aba2
--- /dev/null
+++ b/arp.tproj/arp.8
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)arp.8	8.2 (Berkeley) 4/27/95
+.\"
+.Dd April 27, 1995
+.Dt ARP 8
+.Os BSD 4.3
+.Sh NAME
+.Nm arp
+.Nd address resolution display and control
+.Sh SYNOPSIS
+.Nm arp
+.Ar hostname
+.Nm arp
+.Fl a
+.Nm arp
+.Fl d Ar hostname
+.Nm arp
+.Fl s Ar hostname ether_addr
+.Op Ar temp
+.Op Ar pub
+.Nm arp
+.Fl f Ar filename
+.Sh DESCRIPTION
+The
+.Nm arp
+program displays and modifies the Internet-to-Ethernet address translation
+tables used by the address resolution protocol
+.Pq Xr arp 4 .
+With no flags, the program displays the current
+.Tn ARP
+entry for
+.Ar hostname .
+The host may be specified by name or by number,
+using Internet dot notation.
+.Pp
+Available options:
+.Bl -tag -width Ds
+.It Fl a
+The program displays all of the current
+.Tn ARP
+entries.
+.It Fl d
+A super-user may delete an entry for the host called
+.Ar hostname
+with the
+.Fl d
+flag.
+.It Fl s Ar hostname ether_addr
+Create an
+.Tn ARP
+entry for the host called
+.Ar hostname
+with the Ethernet address 
+.Ar ether_addr .
+The Ethernet address is given as six hex bytes separated by colons.
+The entry will be permanent unless the word
+.Ar temp
+is given in the command. 
+If the word
+.Ar pub
+is given, the entry will be "published"; i.e., this system will
+act as an
+.Tn ARP
+server,
+responding to requests for 
+.Ar hostname
+even though the host address is not its own.
+.It Fl f
+Causes the file
+.Ar filename
+to be read and multiple entries to be set in the
+.Tn ARP
+tables.  Entries
+in the file should be of the form
+.Pp
+.Bd -filled -offset indent -compact
+.Ar hostname ether_addr
+.Op Ar temp
+.Op Ar pub
+.Ed
+.Pp
+with argument meanings as given above.
+.El
+.Sh SEE ALSO
+.Xr inet 3 ,
+.Xr arp 4 ,
+.Xr ifconfig 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 .
diff --git a/arp.tproj/arp.c b/arp.tproj/arp.c
new file mode 100644
index 0000000..4e932b4
--- /dev/null
+++ b/arp.tproj/arp.c
@@ -0,0 +1,554 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1984, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Sun Microsystems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1984, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)arp.c	8.3 (Berkeley) 4/28/95";
+#endif /* not lint */
+
+/*
+ * arp - display, set, and delete arp table entries
+ */
+
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <arpa/inet.h>
+
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <nlist.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int pid;
+static int nflag;
+static int s = -1;
+
+int	delete __P((char *, char *));
+void	dump __P((u_long));
+int	ether_aton __P((char *, u_char *));
+void	ether_print __P((u_char *));
+int	file __P((char *));
+void	get __P((char *));
+void	getsocket __P((void));
+int	rtmsg __P((int));
+int	set __P((int, char **));
+void	usage __P((void));
+
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	int ch;
+
+	pid = getpid();
+	while ((ch = getopt(argc, argv, "ands")) != EOF)
+		switch((char)ch) {
+		case 'a':
+			dump(0);
+			exit(0);
+		case 'd':
+			if (argc < 3 || argc > 4)
+				usage();
+			delete(argv[2], argv[3]);
+			exit(0);
+		case 'n':
+			nflag = 1;
+			continue;
+		case 's':
+			if (argc < 4 || argc > 7)
+				usage();
+			exit(set(argc-2, &argv[2]) ? 1 : 0);
+		case '?':
+		default:
+			usage();
+		}
+	if (argc != 2)
+		usage();
+	get(argv[1]);
+	return (0);
+}
+
+/*
+ * Process a file to set standard arp entries
+ */
+int
+file(name)
+	char *name;
+{
+	FILE *fp;
+	int i, retval;
+	char line[100], arg[5][50], *args[5];
+
+	if ((fp = fopen(name, "r")) == NULL) {
+		fprintf(stderr, "arp: cannot open %s\n", name);
+		exit(1);
+	}
+	args[0] = &arg[0][0];
+	args[1] = &arg[1][0];
+	args[2] = &arg[2][0];
+	args[3] = &arg[3][0];
+	args[4] = &arg[4][0];
+	retval = 0;
+	while(fgets(line, 100, fp) != NULL) {
+		i = sscanf(line, "%s %s %s %s %s", arg[0], arg[1], arg[2],
+		    arg[3], arg[4]);
+		if (i < 2) {
+			fprintf(stderr, "arp: bad line: %s\n", line);
+			retval = 1;
+			continue;
+		}
+		if (set(i, args))
+			retval = 1;
+	}
+	fclose(fp);
+	return (retval);
+}
+
+void
+getsocket() {
+	if (s < 0) {
+		s = socket(PF_ROUTE, SOCK_RAW, 0);
+		if (s < 0) {
+			perror("arp: socket");
+			exit(1);
+		}
+	}
+}
+
+struct	sockaddr_in so_mask = {8, 0, 0, { 0xffffffff}};
+struct	sockaddr_inarp blank_sin = {sizeof(blank_sin), AF_INET }, sin_m;
+struct	sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m;
+int	expire_time, flags, export_only, doing_proxy, found_entry;
+struct	{
+	struct	rt_msghdr m_rtm;
+	char	m_space[512];
+}	m_rtmsg;
+
+/*
+ * Set an individual arp entry 
+ */
+int
+set(argc, argv)
+	int argc;
+	char **argv;
+{
+	struct hostent *hp;
+	register struct sockaddr_inarp *sin = &sin_m;
+	register struct sockaddr_dl *sdl;
+	register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm);
+	u_char *ea;
+	char *host = argv[0], *eaddr = argv[1];
+
+	getsocket();
+	argc -= 2;
+	argv += 2;
+	sdl_m = blank_sdl;
+	sin_m = blank_sin;
+	sin->sin_addr.s_addr = inet_addr(host);
+	if (sin->sin_addr.s_addr == -1) {
+		if (!(hp = gethostbyname(host))) {
+			fprintf(stderr, "arp: %s: ", host);
+			herror((char *)NULL);
+			return (1);
+		}
+		bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
+		    sizeof sin->sin_addr);
+	}
+	ea = (u_char *)LLADDR(&sdl_m);
+	if (ether_aton(eaddr, ea) == 0)
+		sdl_m.sdl_alen = 6;
+	doing_proxy = flags = export_only = expire_time = 0;
+	while (argc-- > 0) {
+		if (strncmp(argv[0], "temp", 4) == 0) {
+			struct timeval time;
+			gettimeofday(&time, 0);
+			expire_time = time.tv_sec + 20 * 60;
+		}
+		else if (strncmp(argv[0], "pub", 3) == 0) {
+			flags |= RTF_ANNOUNCE;
+			doing_proxy = SIN_PROXY;
+		} else if (strncmp(argv[0], "trail", 5) == 0) {
+			printf("%s: Sending trailers is no longer supported\n",
+				host);
+		}
+		argv++;
+	}
+tryagain:
+	if (rtmsg(RTM_GET) < 0) {
+		perror(host);
+		return (1);
+	}
+	sin = (struct sockaddr_inarp *)(rtm + 1);
+	sdl = (struct sockaddr_dl *)(sin->sin_len + (char *)sin);
+	if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) {
+		if (sdl->sdl_family == AF_LINK &&
+		    (rtm->rtm_flags & RTF_LLINFO) &&
+		    !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) {
+		case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
+		case IFT_ISO88024: case IFT_ISO88025:
+			goto overwrite;
+		}
+		if (doing_proxy == 0) {
+			printf("set: can only proxy for %s\n", host);
+			return (1);
+		}
+		if (sin_m.sin_other & SIN_PROXY) {
+			printf("set: proxy entry exists for non 802 device\n");
+			return(1);
+		}
+		sin_m.sin_other = SIN_PROXY;
+		export_only = 1;
+		goto tryagain;
+	}
+overwrite:
+	if (sdl->sdl_family != AF_LINK) {
+		printf("cannot intuit interface index and type for %s\n", host);
+		return (1);
+	}
+	sdl_m.sdl_type = sdl->sdl_type;
+	sdl_m.sdl_index = sdl->sdl_index;
+	return (rtmsg(RTM_ADD));
+}
+
+/*
+ * Display an individual arp entry
+ */
+void
+get(host)
+	char *host;
+{
+	struct hostent *hp;
+	struct sockaddr_inarp *sin = &sin_m;
+
+	sin_m = blank_sin;
+	sin->sin_addr.s_addr = inet_addr(host);
+	if (sin->sin_addr.s_addr == -1) {
+		if (!(hp = gethostbyname(host))) {
+			fprintf(stderr, "arp: %s: ", host);
+			herror((char *)NULL);
+			exit(1);
+		}
+		bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
+		    sizeof sin->sin_addr);
+	}
+	dump(sin->sin_addr.s_addr);
+	if (found_entry == 0) {
+		printf("%s (%s) -- no entry\n",
+		    host, inet_ntoa(sin->sin_addr));
+		exit(1);
+	}
+}
+
+/*
+ * Delete an arp entry 
+ */
+int
+delete(host, info)
+	char *host;
+	char *info;
+{
+	struct hostent *hp;
+	register struct sockaddr_inarp *sin = &sin_m;
+	register struct rt_msghdr *rtm = &m_rtmsg.m_rtm;
+	struct sockaddr_dl *sdl;
+
+	if (info && strncmp(info, "pro", 3) )
+		export_only = 1;
+	getsocket();
+	sin_m = blank_sin;
+	sin->sin_addr.s_addr = inet_addr(host);
+	if (sin->sin_addr.s_addr == -1) {
+		if (!(hp = gethostbyname(host))) {
+			fprintf(stderr, "arp: %s: ", host);
+			herror((char *)NULL);
+			return (1);
+		}
+		bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
+		    sizeof sin->sin_addr);
+	}
+tryagain:
+	if (rtmsg(RTM_GET) < 0) {
+		perror(host);
+		return (1);
+	}
+	sin = (struct sockaddr_inarp *)(rtm + 1);
+	sdl = (struct sockaddr_dl *)(sin->sin_len + (char *)sin);
+	if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) {
+		if (sdl->sdl_family == AF_LINK &&
+		    (rtm->rtm_flags & RTF_LLINFO) &&
+		    !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) {
+		case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
+		case IFT_ISO88024: case IFT_ISO88025:
+			goto delete;
+		}
+	}
+	if (sin_m.sin_other & SIN_PROXY) {
+		fprintf(stderr, "delete: can't locate %s\n",host);
+		return (1);
+	} else {
+		sin_m.sin_other = SIN_PROXY;
+		goto tryagain;
+	}
+delete:
+	if (sdl->sdl_family != AF_LINK) {
+		printf("cannot locate %s\n", host);
+		return (1);
+	}
+	if (rtmsg(RTM_DELETE))
+		return (1);
+	printf("%s (%s) deleted\n", host, inet_ntoa(sin->sin_addr));
+	return (0);
+}
+
+/*
+ * Dump the entire arp table
+ */
+void
+dump(addr)
+	u_long addr;
+{
+	int mib[6];
+	size_t needed;
+	char *host, *lim, *buf, *next;
+	struct rt_msghdr *rtm;
+	struct sockaddr_inarp *sin;
+	struct sockaddr_dl *sdl;
+	extern int h_errno;
+	struct hostent *hp;
+
+	mib[0] = CTL_NET;
+	mib[1] = PF_ROUTE;
+	mib[2] = 0;
+	mib[3] = AF_INET;
+	mib[4] = NET_RT_FLAGS;
+	mib[5] = RTF_LLINFO;
+	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+		err(1, "route-sysctl-estimate");
+	if ((buf = malloc(needed)) == NULL)
+		err(1, "malloc");
+	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+		err(1, "actual retrieval of routing table");
+	lim = buf + needed;
+	for (next = buf; next < lim; next += rtm->rtm_msglen) {
+		rtm = (struct rt_msghdr *)next;
+		sin = (struct sockaddr_inarp *)(rtm + 1);
+		sdl = (struct sockaddr_dl *)(sin + 1);
+		if (addr) {
+			if (addr != sin->sin_addr.s_addr)
+				continue;
+			found_entry = 1;
+		}
+		if (nflag == 0)
+			hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
+			    sizeof sin->sin_addr, AF_INET);
+		else
+			hp = 0;
+		if (hp)
+			host = hp->h_name;
+		else {
+			host = "?";
+			if (h_errno == TRY_AGAIN)
+				nflag = 1;
+		}
+		printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));
+		if (sdl->sdl_alen)
+			ether_print((u_char *)LLADDR(sdl));
+		else
+			printf("(incomplete)");
+		if (rtm->rtm_rmx.rmx_expire == 0)
+			printf(" permanent");
+		if (sin->sin_other & SIN_PROXY)
+			printf(" published (proxy only)");
+		if (rtm->rtm_addrs & RTA_NETMASK) {
+			sin = (struct sockaddr_inarp *)
+				(sdl->sdl_len + (char *)sdl);
+			if (sin->sin_addr.s_addr == 0xffffffff)
+				printf(" published");
+			if (sin->sin_len != 8)
+				printf("(wierd)");
+		}
+		printf("\n");
+	}
+}
+
+void
+ether_print(cp)
+	u_char *cp;
+{
+	printf("%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
+}
+
+int
+ether_aton(a, n)
+	char *a;
+	u_char *n;
+{
+	int i, o[6];
+
+	i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2],
+					   &o[3], &o[4], &o[5]);
+	if (i != 6) {
+		fprintf(stderr, "arp: invalid Ethernet address '%s'\n", a);
+		return (1);
+	}
+	for (i=0; i<6; i++)
+		n[i] = o[i];
+	return (0);
+}
+
+void
+usage()
+{
+	printf("usage: arp hostname\n");
+	printf("       arp -a [kernel] [kernel_memory]\n");
+	printf("       arp -d hostname\n");
+	printf("       arp -s hostname ether_addr [temp] [pub]\n");
+	printf("       arp -f filename\n");
+	exit(1);
+}
+
+int
+rtmsg(cmd)
+	int cmd;
+{
+	static int seq;
+	int rlen;
+	register struct rt_msghdr *rtm = &m_rtmsg.m_rtm;
+	register char *cp = m_rtmsg.m_space;
+	register int l;
+
+	errno = 0;
+	if (cmd == RTM_DELETE)
+		goto doit;
+	bzero((char *)&m_rtmsg, sizeof(m_rtmsg));
+	rtm->rtm_flags = flags;
+	rtm->rtm_version = RTM_VERSION;
+
+	switch (cmd) {
+	default:
+		fprintf(stderr, "arp: internal wrong cmd\n");
+		exit(1);
+	case RTM_ADD:
+		rtm->rtm_addrs |= RTA_GATEWAY;
+		rtm->rtm_rmx.rmx_expire = expire_time;
+		rtm->rtm_inits = RTV_EXPIRE;
+		rtm->rtm_flags |= (RTF_HOST | RTF_STATIC);
+		sin_m.sin_other = 0;
+		if (doing_proxy) {
+			if (export_only)
+				sin_m.sin_other = SIN_PROXY;
+			else {
+				rtm->rtm_addrs |= RTA_NETMASK;
+				rtm->rtm_flags &= ~RTF_HOST;
+			}
+		}
+		/* FALLTHROUGH */
+	case RTM_GET:
+		rtm->rtm_addrs |= RTA_DST;
+	}
+#define NEXTADDR(w, s) \
+	if (rtm->rtm_addrs & (w)) { \
+		bcopy((char *)&s, cp, sizeof(s)); cp += sizeof(s);}
+
+	NEXTADDR(RTA_DST, sin_m);
+	NEXTADDR(RTA_GATEWAY, sdl_m);
+	NEXTADDR(RTA_NETMASK, so_mask);
+
+	rtm->rtm_msglen = cp - (char *)&m_rtmsg;
+doit:
+	l = rtm->rtm_msglen;
+	rtm->rtm_seq = ++seq;
+	rtm->rtm_type = cmd;
+	if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {
+		if (errno != ESRCH || cmd != RTM_DELETE) {
+			perror("writing to routing socket");
+			return (-1);
+		}
+	}
+	do {
+		l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
+	} while (l > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid));
+	if (l < 0)
+		(void) fprintf(stderr, "arp: read from routing socket: %s\n",
+		    strerror(errno));
+	return (0);
+}
diff --git a/arp.tproj/arp4.4 b/arp.tproj/arp4.4
new file mode 100644
index 0000000..0cd7161
--- /dev/null
+++ b/arp.tproj/arp4.4
@@ -0,0 +1,124 @@
+.\" Copyright (c) 1985, 1986, 1988, 1994
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)arp4.4	6.5 (Berkeley) 4/18/94
+.\"
+.Dd April 18, 1994
+.Dt ARP 4
+.Os BSD 4
+.Sh NAME
+.Nm arp
+.Nd Address Resolution Protocol
+.Sh SYNOPSIS
+.Em "pseudo-device ether"
+.Sh DESCRIPTION
+The Address Resolution Protocol (ARP) is a protocol used to dynamically
+map between Internet host addresses and 10Mb/s Ethernet addresses.
+It is used by all the 10Mb/s Ethernet interface drivers.
+It is not specific to Internet protocols or to 10Mb/s Ethernet,
+but this implementation currently supports only that combination.
+.Pp
+ARP caches Internet-Ethernet address mappings. 
+When an interface requests a mapping for an address not in the cache,
+ARP queues the message which requires the mapping and broadcasts
+a message on the associated network requesting the address mapping.
+If a response is provided, the new mapping is cached and any pending
+message is transmitted.
+ARP will queue at most one packet while waiting for a response to a
+mapping request;
+only the most recently ``transmitted'' packet is kept.
+If the target host does not respond after several requests,
+the host is considered to be down for a short period (normally 20 seconds),
+allowing an error to be returned to transmission attempts during this
+interval.
+The error is
+.Li EHOSTDOWN
+for a non-responding destination host, and
+.Li EHOSTUNREACH
+for a non-responding router.
+.Pp
+The ARP cache is stored in the system routing table as
+dynamically-created host routes.
+The route to a directly-attached Ethernet network is installed as a
+.Dq cloning
+route (one with the
+.Li RTF_CLONING
+flag set),
+causing routes to individual hosts on that network to be created on
+demand.
+These routes time out periodically (normally 20 minutes after validated;
+entries are not validated when not in use).
+An entry for a host which is not responding is a
+.Dq reject
+route (one with the
+.Li RTF_REJECT
+flag set).
+.Pp
+ARP entries may be added, deleted or changed with the
+.Xr arp 8
+utility.
+Manually-added entries may be temporary or permanent,
+and may be
+.Dq published ,
+in which case the system will respond to ARP requests for that host
+as if it were the target of the request.
+.Pp
+In the past,
+ARP was used to negotiate the use of a trailer encapsulation.
+This is no longer supported.
+.Pp
+ARP watches passively for hosts impersonating the local host (i.e. a host
+which responds to an ARP mapping request for the local host's address).
+.Sh DIAGNOSTICS
+.Em "duplicate IP address %x!! sent from ethernet address: %x:%x:%x:%x:%x:%x."
+ARP has discovered another host on the local network which responds to
+mapping requests for its own Internet address with a different Ethernet
+address, generally indicating that two hosts are attempting to use the
+same Internet address.
+.Sh SEE ALSO
+.Xr inet 4 ,
+.Xr route 4 ,
+.Xr arp 8 ,
+.Xr ifconfig 8 ,
+.Xr route 8
+.sp
+.Rs
+.%A Plummer, D.
+.%B "An Ethernet Address Resolution Protocol"
+.%T RFC826
+.Re
+.Rs
+.%A Leffler, S.J.
+.%A Karels, M.J.
+.%B "Trailer Encapsulations
+.%T RFC893
+.Re
+
diff --git a/bootparams/Makefile b/bootparams/Makefile
new file mode 100644
index 0000000..8e40018
--- /dev/null
+++ b/bootparams/Makefile
@@ -0,0 +1,46 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = bootparams
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Aggregate
+
+TOOLS = bootparamd.tproj bpwhoami.tproj
+
+LIBRARIES = bootparams
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = aggregate.make
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/bootparams/Makefile.postamble b/bootparams/Makefile.postamble
new file mode 100644
index 0000000..411cde6
--- /dev/null
+++ b/bootparams/Makefile.postamble
@@ -0,0 +1,100 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGES: langages in which the project is written (default "English")
+#  English_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/bootparams/Makefile.preamble b/bootparams/Makefile.preamble
new file mode 100644
index 0000000..0bf1e82
--- /dev/null
+++ b/bootparams/Makefile.preamble
@@ -0,0 +1,138 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.  For library projects you should
+#       set this to something like /Developer/Headers/$(NAME).  Do not set
+#       this variable for framework projects unless you do not want the
+#       header files included in the framework.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. This defaults to
+#       DYNAMIC.
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+OTHER_GARBAGE = *~
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Uncomment to suppress generation of a KeyValueCoding index when installing 
+# frameworks (This index is used by WOB and IB to determine keys available
+# for an object).  Set to YES by default.
+# PREINDEX_FRAMEWORK = NO
+
+# Change this definition to install projects somewhere other than the
+# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
+# and "" on other systems.
+# DSTROOT = $(HOME)
diff --git a/bootparams/PB.project b/bootparams/PB.project
new file mode 100644
index 0000000..631206a
--- /dev/null
+++ b/bootparams/PB.project
@@ -0,0 +1,22 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        H_FILES = (); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        SUBPROJECTS = (bootparams, bootparamd.tproj, bpwhoami.tproj); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = bootparams; 
+    PROJECTTYPE = Aggregate; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/bootparams/bootparamd.tproj/Makefile b/bootparams/bootparamd.tproj/Makefile
new file mode 100644
index 0000000..ae0309c
--- /dev/null
+++ b/bootparams/bootparamd.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = bootparamd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = bootparamd.c bootparam_proc.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /Library/Executables
+PDO_UNIX_INSTALLDIR = /bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/bootparams/bootparamd.tproj/Makefile.postamble b/bootparams/bootparamd.tproj/Makefile.postamble
new file mode 100644
index 0000000..411cde6
--- /dev/null
+++ b/bootparams/bootparamd.tproj/Makefile.postamble
@@ -0,0 +1,100 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGES: langages in which the project is written (default "English")
+#  English_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/bootparams/bootparamd.tproj/Makefile.preamble b/bootparams/bootparamd.tproj/Makefile.preamble
new file mode 100644
index 0000000..db3f4e7
--- /dev/null
+++ b/bootparams/bootparamd.tproj/Makefile.preamble
@@ -0,0 +1,140 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.  For library projects you should
+#       set this to something like /Developer/Headers/$(NAME).  Do not set
+#       this variable for framework projects unless you do not want the
+#       header files included in the framework.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. This defaults to
+#       DYNAMIC.
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+OTHER_GARBAGE = *~
+OTHER_LIBS = -lbootparams
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Uncomment to suppress generation of a KeyValueCoding index when installing 
+# frameworks (This index is used by WOB and IB to determine keys available
+# for an object).  Set to YES by default.
+# PREINDEX_FRAMEWORK = NO
+
+# Change this definition to install projects somewhere other than the
+# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
+# and "" on other systems.
+# DSTROOT = $(HOME)
+
diff --git a/bootparams/bootparamd.tproj/PB.project b/bootparams/bootparamd.tproj/PB.project
new file mode 100644
index 0000000..89f2397
--- /dev/null
+++ b/bootparams/bootparamd.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_LINKED = (bootparamd.c, bootparam_proc.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_INSTALLDIR = /bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = bootparamd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = /Library/Executables; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/bootparams/bootparamd.tproj/bootparam_proc.c b/bootparams/bootparamd.tproj/bootparam_proc.c
new file mode 100644
index 0000000..faa0ff3
--- /dev/null
+++ b/bootparams/bootparamd.tproj/bootparam_proc.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * BOOTPARAMS server
+ * Copyright 1998, Apple Computer Inc.  Unpublished.
+ *
+ * Written by Marc Majka
+ */
+
+#include <rpc/rpc.h>
+#include "bootparam_prot.h"
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <bootparams.h>
+#include <syslog.h>
+
+extern int debug;
+extern unsigned long route_addr;
+extern char domain_name[];
+
+struct hostent *h;
+static char hostname[MAXHOSTNAMELEN];
+
+bp_whoami_res *
+bootparamproc_whoami_1_svc(whoami, req)
+bp_whoami_arg *whoami;
+struct svc_req *req;
+{
+	long haddr;
+	static bp_whoami_res res;
+	struct bootparamsent *bp;
+
+	if (debug)
+	{
+		fprintf(stderr,"whoami %d.%d.%d.%d\n", 
+			255 & whoami->client_address.bp_address_u.ip_addr.net,
+			255 & whoami->client_address.bp_address_u.ip_addr.host,
+			255 & whoami->client_address.bp_address_u.ip_addr.lh,
+			255 & whoami->client_address.bp_address_u.ip_addr.impno);
+	}
+
+	bcopy((char *)&whoami->client_address.bp_address_u.ip_addr,
+		(char *)&haddr, sizeof(haddr));
+	h = gethostbyaddr((char *)&haddr, sizeof(haddr), AF_INET);
+	if (h == NULL)
+	{
+		if (debug) fprintf(stderr,"whoami failed: gethostbyaddr\n");
+		return NULL;
+	}
+
+	/* check whether subsequent bpgetfile requests would succeed */
+	bp = bootparams_getbyname(h->h_name);
+	if (bp == NULL) {
+	    	if (debug) 
+		    fprintf(stderr, "whoami failed: bootparams_getbyname\n");
+		return NULL;
+	}
+
+	sprintf(hostname, "%s", h->h_name);
+	res.client_name = hostname;
+
+	res.domain_name = domain_name;
+
+	res.router_address.address_type = IP_ADDR_TYPE;
+	bcopy(&route_addr, &res.router_address.bp_address_u.ip_addr, 4);
+
+	if (debug)
+	{
+		fprintf(stderr, "whoami name=%s domain=%s router=%d.%d.%d.%d\n", 
+			res.client_name,
+			res.domain_name,
+			255 & res.router_address.bp_address_u.ip_addr.net,
+			255 & res.router_address.bp_address_u.ip_addr.host,
+			255 & res.router_address.bp_address_u.ip_addr.lh,
+			255 & res.router_address.bp_address_u.ip_addr.impno);
+	}
+
+	return (&res);
+}
+
+bp_getfile_res *
+bootparamproc_getfile_1_svc(getfile, req)
+bp_getfile_arg *getfile;
+struct svc_req *req;
+{
+	static bp_getfile_res res;
+	struct bootparamsent *bp;
+	static char s[1024];
+	char *p;
+	int i, len;
+
+	if (debug)
+	{
+		fprintf(stderr, "getfile %s %s\n",
+			getfile->client_name, getfile->file_id);
+	}
+
+	bp = bootparams_getbyname(getfile->client_name);
+	if (bp == NULL)
+	{
+		if (debug)
+		{
+			fprintf(stderr, "can't find bootparams for %s\n",
+				getfile->client_name);
+			fprintf(stderr, "getfile failed\n");
+		}
+		return NULL;
+	}
+
+	len = strlen(getfile->file_id) + 1;
+	sprintf(s, "%s=", getfile->file_id);
+
+	for (i = 0; bp->bp_bootparams[i] != NULL; i++)
+	{
+		if (!strncmp(s, bp->bp_bootparams[i], len)) break;
+	}
+
+	if (bp->bp_bootparams[i] == NULL)
+	{
+		if (debug)
+		{
+			fprintf(stderr, "can't find bootparam %s\n", getfile->file_id);
+			fprintf(stderr, "getfile failed\n");
+		}
+		return NULL;
+	}
+
+	sprintf(s, bp->bp_bootparams[i] + len);
+	p = strchr(s, ':');
+	if (p == NULL)
+	{
+		hostname[0] = '\0';
+		res.server_name = hostname;
+		res.server_address.bp_address_u.ip_addr.net = 0;
+		res.server_address.bp_address_u.ip_addr.host = 0;
+		res.server_address.bp_address_u.ip_addr.lh = 0;
+		res.server_address.bp_address_u.ip_addr.impno = 0;
+		res.server_address.address_type = 1;
+		res.server_path = s;
+
+		if (debug)
+		{
+     		 fprintf(stderr, "getfile server=%s (%d.%d.%d.%d) path=%s\n",
+	  		   res.server_name,
+	  		   255 & res.server_address.bp_address_u.ip_addr.net,
+	  		   255 & res.server_address.bp_address_u.ip_addr.host,
+	   		  255 & res.server_address.bp_address_u.ip_addr.lh,
+	   		  255 & res.server_address.bp_address_u.ip_addr.impno,
+				res.server_path);
+		}
+		return (&res);
+	}
+
+	*p = '\0';
+	p++;
+	h = gethostbyname(s);
+	if (h == NULL)
+	{
+		if (debug)
+		{
+			fprintf(stderr, "can't find server %s\n", s);
+			fprintf(stderr, "getfile failed\n");
+		}
+		return NULL;
+	}
+
+ 	res.server_name = s;
+	res.server_path = p;
+	bcopy(h->h_addr, &res.server_address.bp_address_u.ip_addr, h->h_length);
+	res.server_address.address_type = IP_ADDR_TYPE;
+
+    if (debug)
+	{
+      fprintf(stderr, "getfile server=%s (%d.%d.%d.%d) path=%s\n",
+	     res.server_name,
+	     255 & res.server_address.bp_address_u.ip_addr.net,
+	     255 & res.server_address.bp_address_u.ip_addr.host,
+	     255 & res.server_address.bp_address_u.ip_addr.lh,
+	     255 & res.server_address.bp_address_u.ip_addr.impno,
+		res.server_path);
+	}
+
+    return (&res);
+}
diff --git a/bootparams/bootparamd.tproj/bootparamd.c b/bootparams/bootparamd.tproj/bootparamd.c
new file mode 100644
index 0000000..e76bd42
--- /dev/null
+++ b/bootparams/bootparamd.tproj/bootparamd.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * BOOTPARAMS server
+ * Copyright 1998, Apple Computer Inc.  Unpublished.
+ *
+ * Written by Marc Majka
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include "bootparam_prot.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int debug = 0;
+char *progname;
+
+unsigned long route_addr;
+char domain_name[MAXHOSTNAMELEN];
+
+int _rpcsvcdirty;
+extern void bootparamprog_1();
+
+extern int getdomainname(char*, int);
+
+void
+usage(void)
+{
+	fprintf(stderr, "usage: %s [-d] [-r router]\n", progname);
+	exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+	SVCXPRT *transp;
+	int i;
+	struct hostent *h;
+	char str[256];
+	FILE *fp;
+	
+	progname = strrchr(argv[0],'/');
+	if (progname) progname++;
+	else progname = argv[0];
+
+	route_addr = 0;
+
+	for (i = 1; i < argc; i++)
+	{
+		if (!strcmp(argv[i], "-d"))
+		{
+			debug = 1;
+		}
+		else if (!strcmp(argv[i], "-r"))
+		{
+			i++;
+			if (i >= argc) usage();
+
+			route_addr = inet_addr(argv[i]);
+			if (route_addr == -1)
+			{
+				h = gethostbyname(argv[i]);
+				if (h == NULL)
+				{
+					fprintf(stderr, "%s: Can't find host %s\n",
+						progname, argv[i]);
+					exit(1);
+				}
+
+				bcopy(h->h_addr, (char *)&route_addr, sizeof(route_addr));
+			}
+		}
+		else usage();
+	}
+
+	if (route_addr == 0)
+	{
+		fp = popen("/usr/sbin/netstat -r -n", "r");
+		while (NULL != fgets(str, 256, fp))
+		{
+			if (strncmp(str, "default ", 8)) continue;
+			if (!strncmp(str + 17, "link", 4)) continue;
+			route_addr = inet_addr(str+17);
+			break;
+		}
+		pclose(fp);
+	}
+
+	domain_name[0] = '\0';
+	if (getdomainname(domain_name, sizeof(domain_name)) != 0)
+	    domain_name[0] = '\0';
+
+	if (debug == 0) daemon(0,0);		
+
+	openlog(progname, 0, LOG_DAEMON);
+	pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS);
+
+	transp = svcudp_create(RPC_ANYSOCK);
+	if (transp == NULL)
+	{
+		syslog(LOG_ERR, "Can't create udp service.");
+		exit(1);
+	}
+
+	if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS, bootparamprog_1, IPPROTO_UDP))
+	{
+		syslog(LOG_ERR, "Can't register service.");
+		exit(1);
+	}
+
+	svc_run();
+	
+	syslog(LOG_ERR, "svc_run returned");
+	exit(1);
+}
+
+
diff --git a/bootparams/bootparams/Makefile b/bootparams/bootparams/Makefile
new file mode 100644
index 0000000..931d5c9
--- /dev/null
+++ b/bootparams/bootparams/Makefile
@@ -0,0 +1,52 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = bootparams
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Library
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
+            bootparam_prot.x
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CURRENTLY_ACTIVE_VERSION = YES
+DEPLOY_WITH_VERSION_NAME = A
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = library.make
+NEXTSTEP_INSTALLDIR = /usr/local/lib
+WINDOWS_INSTALLDIR = /Developer/Libraries
+PDO_UNIX_INSTALLDIR = /lib
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+WINDOWS_PUBLIC_HEADERS_DIR = $(HOMEDRIVE)$(LOCAL_DEVELOPER_DIR)/Headers/$(NAME)
+
+PDO_UNIX_PUBLIC_HEADERS_DIR = $(LOCAL_DEVELOPER_DIR)/Headers/$(NAME)
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/bootparams/bootparams/Makefile.postamble b/bootparams/bootparams/Makefile.postamble
new file mode 100644
index 0000000..a939e58
--- /dev/null
+++ b/bootparams/bootparams/Makefile.postamble
@@ -0,0 +1,109 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGES: langages in which the project is written (default "English")
+#  English_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Needed since a .x file in Other Sources will require a corresponding .o
+%_xdr.c: %.x
+	$(RPCGEN) $(ALL_RPCFLAGS) -c -o $(SYM_DIR)/$*_xdr.c $*.x
+
+%_svc.c: %.x
+	$(RPCGEN) $(ALL_RPCFLAGS) -m -o $(SYM_DIR)/$*_svc.c $*.x
+
+after_install:
+	$(RM) -rf $(INSTALLED_PRODUCTS)
diff --git a/bootparams/bootparams/Makefile.preamble b/bootparams/bootparams/Makefile.preamble
new file mode 100644
index 0000000..9253661
--- /dev/null
+++ b/bootparams/bootparams/Makefile.preamble
@@ -0,0 +1,144 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+AFTER_INSTALL = after_install
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.  For library projects you should
+#       set this to something like /Developer/Headers/$(NAME).  Do not set
+#       this variable for framework projects unless you do not want the
+#       header files included in the framework.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. This defaults to
+#       DYNAMIC.
+LIBRARY_STYLE = STATIC
+
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+OTHER_GARBAGE = *~
+OTHER_PROJECT_HEADERS = bootparam_prot.h
+OTHER_OFILES = bootparam_prot_xdr.o bootparam_prot_svc.o
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Uncomment to suppress generation of a KeyValueCoding index when installing 
+# frameworks (This index is used by WOB and IB to determine keys available
+# for an object).  Set to YES by default.
+# PREINDEX_FRAMEWORK = NO
+
+# Change this definition to install projects somewhere other than the
+# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
+# and "" on other systems.
+# DSTROOT = $(HOME)
+-include ../../Makefile.include
diff --git a/bootparams/bootparams/PB.project b/bootparams/bootparams/PB.project
new file mode 100644
index 0000000..d753020
--- /dev/null
+++ b/bootparams/bootparams/PB.project
@@ -0,0 +1,30 @@
+{
+    CURRENTLY_ACTIVE_VERSION = YES; 
+    DEPLOY_WITH_VERSION_NAME = A; 
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, bootparam_prot.x); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/local/lib; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_INSTALLDIR = /lib; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PDO_UNIX_PUBLICHEADERSDIR = "$(LOCAL_DEVELOPER_DIR)/Headers/$(NAME)"; 
+    PROJECTNAME = bootparams; 
+    PROJECTTYPE = Library; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = /Developer/Libraries; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+    WINDOWS_PUBLICHEADERSDIR = "$(HOMEDRIVE)$(LOCAL_DEVELOPER_DIR)/Headers/$(NAME)"; 
+}
diff --git a/bootparams/bootparams/bootparam_prot.x b/bootparams/bootparams/bootparam_prot.x
new file mode 100644
index 0000000..0339a81
--- /dev/null
+++ b/bootparams/bootparams/bootparam_prot.x
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* @(#)bootparam_prot.x	2.1 88/08/01 4.0 RPCSRC */
+/* @(#)bootparam_prot.x 1.2 87/06/24 Copyr 1987 Sun Micro */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * RPC for bootparms service.
+ * There are two procedures:
+ *   WHOAMI takes a net address and returns a client name and also a
+ *	likely net address for routing
+ *   GETFILE takes a client name and file identifier and returns the
+ *	server name, server net address and pathname for the file.
+ *   file identifiers typically include root, swap, pub and dump
+ */
+
+#ifdef RPC_HDR
+%#include <rpc/types.h>
+%#include <sys/time.h>
+%#include <sys/errno.h>
+#endif
+
+const MAX_MACHINE_NAME  = 255;
+const MAX_PATH_LEN	= 1024;
+const MAX_FILEID	= 32;
+const IP_ADDR_TYPE	= 1;
+
+typedef	string	bp_machine_name_t<MAX_MACHINE_NAME>;
+typedef	string	bp_path_t<MAX_PATH_LEN>;
+typedef	string	bp_fileid_t<MAX_FILEID>;
+
+struct	ip_addr_t {
+	char	net;
+	char	host;
+	char	lh;
+	char	impno;
+};
+
+union bp_address switch (int address_type) {
+	case IP_ADDR_TYPE:
+		ip_addr_t	ip_addr;
+};
+
+struct bp_whoami_arg {
+	bp_address		client_address;
+};
+
+struct bp_whoami_res {
+	bp_machine_name_t	client_name;
+	bp_machine_name_t	domain_name;
+	bp_address		router_address;
+};
+
+struct bp_getfile_arg {
+	bp_machine_name_t	client_name;
+	bp_fileid_t		file_id;
+};
+	
+struct bp_getfile_res {
+	bp_machine_name_t	server_name;
+	bp_address		server_address;
+	bp_path_t		server_path;
+};
+
+program BOOTPARAMPROG {
+	version BOOTPARAMVERS {
+		bp_whoami_res	BOOTPARAMPROC_WHOAMI(bp_whoami_arg) = 1;
+		bp_getfile_res	BOOTPARAMPROC_GETFILE(bp_getfile_arg) = 2;
+	} = 1;
+} = 100026;
diff --git a/bootparams/bpwhoami.tproj/Makefile b/bootparams/bpwhoami.tproj/Makefile
new file mode 100644
index 0000000..1cf44ad
--- /dev/null
+++ b/bootparams/bpwhoami.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = bpwhoami
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = bpwhoami.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /Library/Executables
+PDO_UNIX_INSTALLDIR = /bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/bootparams/bpwhoami.tproj/Makefile.postamble b/bootparams/bpwhoami.tproj/Makefile.postamble
new file mode 100644
index 0000000..411cde6
--- /dev/null
+++ b/bootparams/bpwhoami.tproj/Makefile.postamble
@@ -0,0 +1,100 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGES: langages in which the project is written (default "English")
+#  English_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/bootparams/bpwhoami.tproj/Makefile.preamble b/bootparams/bpwhoami.tproj/Makefile.preamble
new file mode 100644
index 0000000..5a48598
--- /dev/null
+++ b/bootparams/bpwhoami.tproj/Makefile.preamble
@@ -0,0 +1,139 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.  For library projects you should
+#       set this to something like /Developer/Headers/$(NAME).  Do not set
+#       this variable for framework projects unless you do not want the
+#       header files included in the framework.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. This defaults to
+#       DYNAMIC.
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+OTHER_GARBAGE = *~
+OTHER_LIBS = -lbootparams
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Uncomment to suppress generation of a KeyValueCoding index when installing 
+# frameworks (This index is used by WOB and IB to determine keys available
+# for an object).  Set to YES by default.
+# PREINDEX_FRAMEWORK = NO
+
+# Change this definition to install projects somewhere other than the
+# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
+# and "" on other systems.
+# DSTROOT = $(HOME)
diff --git a/bootparams/bpwhoami.tproj/PB.project b/bootparams/bpwhoami.tproj/PB.project
new file mode 100644
index 0000000..516c248
--- /dev/null
+++ b/bootparams/bpwhoami.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_LINKED = (bpwhoami.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_INSTALLDIR = /bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = bpwhoami; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = /Library/Executables; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/bootparams/bpwhoami.tproj/bpwhoami.c b/bootparams/bpwhoami.tproj/bpwhoami.c
new file mode 100644
index 0000000..c846417
--- /dev/null
+++ b/bootparams/bpwhoami.tproj/bpwhoami.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* 
+ * Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved
+ *
+ * bpwhoami.c
+ * - do a bootparams whoami call and echo the results to stdout
+ *
+ * The output is of the form:
+ * host_name=<hostname>
+ * nis_domain=<nis domain name>
+ * router=<router ip address>
+ * server_name=<server host name>
+ * server_ip_address=<server ip address>
+ *
+ * The program will exit with the following codes:
+ * 0	Successfully retrieved info
+ * 1	RPC timed out while attempting to retrieve info
+ * 2	Unrecoverable error ie. don't bother trying to call again
+ *
+ * Modification History:
+ * Aug  5, 1997		Dieter Siegund (dieter@apple.com)
+ * - lifted code from the old hostname -AUTOMATIC- source
+ */
+
+
+#include <sys/param.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+void usage __P((void));
+
+#include <netdb.h>
+#include <signal.h>
+#include <mach/boolean.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl_compat.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <net/if.h>
+#include <rpc/rpc.h>
+#include <arpa/inet.h>
+#include "bootparam_prot.h"
+
+struct in_addr		ip_address;
+struct in_addr		net_mask;
+
+static __inline__
+u_long iptohl(struct in_addr ip)
+{
+    return (ntohl(ip.s_addr));
+}
+
+static __inline__ boolean_t
+in_subnet(struct in_addr netaddr, struct in_addr netmask, struct in_addr ip)
+{
+    if ((iptohl(ip) & iptohl(netmask)) 
+	!= (iptohl(netaddr) & iptohl(netmask))) {
+	return (FALSE);
+    }
+    return (TRUE);
+}
+
+bool_t
+each_whoresult(result, from)
+     bp_whoami_res		*result;
+     struct sockaddr_in	*from;
+{
+	if (result) {
+	    struct hostent *	host;
+	    struct in_addr *	router;
+
+	    /*
+	     * guard against bogus router replies by making sure
+	     * that the default router is on the same subnet
+	     */
+	    router = (struct in_addr *)
+		&result->router_address.bp_address_u.ip_addr;
+	    if (in_subnet(*router, net_mask, ip_address)) {
+		if (result->client_name && result->client_name[0])
+		    printf("host_name=%s\n", result->client_name); 
+		if (result->domain_name && result->domain_name[0])
+		    printf("nis_domain=%s\n", result->domain_name);
+		printf("router=%s\n", inet_ntoa(*router));
+		host = gethostbyaddr((char *) &from->sin_addr,
+				     sizeof (from->sin_addr), AF_INET);
+		if (host) {
+		    printf("server_name=%s\n", host->h_name);
+		}
+		printf("server_ip_address=%s\n", inet_ntoa(from->sin_addr));
+		return(TRUE);
+	    }
+	}
+	return(FALSE);
+}
+
+#define MAX_IF		16
+
+static boolean_t
+getFirstInterface(struct ifreq * ret_p)
+{
+    struct ifconf 	ifconf;	/* points to ifreq */
+    struct ifreq  *	ifreq = NULL;
+    struct ifreq *	ifrp;
+    int			size = sizeof(struct ifreq) * MAX_IF;
+    int			sockfd;
+
+    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+	fprintf(stderr, "bpwhoami: socket call failed\n");
+	return (FALSE);
+    }
+
+    while (1) {
+	if (ifreq != NULL)
+	    ifreq = (struct ifreq *)realloc(ifreq, size);
+	else
+	    ifreq = (struct ifreq *)malloc(size);
+
+	if (ifreq == NULL)
+	    goto err;
+
+	ifconf.ifc_len = size;
+	ifconf.ifc_req = ifreq;
+	if (ioctl(sockfd, SIOCGIFCONF, (caddr_t)&ifconf) < 0
+	    || ifconf.ifc_len <= 0) {
+	    fprintf(stderr, "bpwhoami: ioctl SIOCGIFCONF failed\n");
+	    goto err;
+	}
+	if ((ifconf.ifc_len + sizeof(struct ifreq)) < size)
+	    break;
+	size *= 2;
+    }
+#define IFR_NEXT(ifr)	\
+    ((struct ifreq *) ((char *) (ifr) + sizeof(*(ifr)) + \
+		       MAX(0, (int) (ifr)->ifr_addr.sa_len \
+			   - (int) sizeof((ifr)->ifr_addr))))
+    for (ifrp = (struct ifreq *) ifconf.ifc_buf;
+	 (char *) ifrp < &ifconf.ifc_buf[ifconf.ifc_len];
+	 ifrp = IFR_NEXT(ifrp)) {
+	if (ifrp->ifr_addr.sa_family == AF_INET) {
+	    struct ifreq	ifr;
+
+	    strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
+	    if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t)&ifr) < 0)
+		;
+	    else if ((ifr.ifr_flags & IFF_LOOPBACK)
+		     || !(ifr.ifr_flags & IFF_UP))
+		;
+	    else if (ioctl(sockfd, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) 
+		;
+	    else {
+		net_mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
+		*ret_p = *ifrp;
+		close(sockfd);
+		if (ifreq)
+		    free(ifreq);
+		return (TRUE);
+	    }
+	}
+    }
+  err:
+    close(sockfd);
+    if (ifreq)
+	free(ifreq);
+    return (FALSE);
+}
+
+/*
+ * Routine: bp_whoami
+ * Function:
+ *	Do a BOOTPARAMS WHOAMI RPC to find out hostname, domain,
+ *	bootparams server, default router.
+ */
+int
+bp_whoami()
+{
+	extern enum clnt_stat	clnt_broadcast();
+	struct ifreq		ifr;
+	struct sockaddr_in	*sockin;
+	enum clnt_stat		stat;
+	struct bp_whoami_arg	who_arg;
+	struct bp_whoami_res	who_res;
+
+	if (getFirstInterface(&ifr) == FALSE)
+	    return (2);
+
+	sockin = (struct sockaddr_in *) &ifr.ifr_addr;
+	ip_address = sockin->sin_addr;
+	who_arg.client_address.bp_address_u.ip_addr =
+	    *((ip_addr_t *)&sockin->sin_addr);
+	who_arg.client_address.address_type = IP_ADDR_TYPE;
+	bzero(&who_res, sizeof (who_res));
+
+	/*
+	 * Broadcast the whoami.
+	 */
+	stat = clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS,
+			      BOOTPARAMPROC_WHOAMI, xdr_bp_whoami_arg,
+			      &who_arg, xdr_bp_whoami_res, &who_res,
+			      each_whoresult);
+
+	if (stat == RPC_SUCCESS) {
+	    return (0);
+	}
+	if (stat == RPC_TIMEDOUT)
+	    return (1);
+	fprintf(stderr, "bpwhoami: ");
+	clnt_perrno(stat);
+	return (2);
+}
+
+int
+main(argc,argv)
+     int argc;
+     char *argv[];
+{
+    exit(bp_whoami());
+}
diff --git a/domainname.tproj/Makefile b/domainname.tproj/Makefile
new file mode 100644
index 0000000..12a1e35
--- /dev/null
+++ b/domainname.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = domainname
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = domainname.c
+
+OTHERSRCS = Makefile.dist domainname.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /bin
+WINDOWS_INSTALLDIR = /bin
+PDO_UNIX_INSTALLDIR = /bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/domainname.tproj/Makefile.dist b/domainname.tproj/Makefile.dist
new file mode 100644
index 0000000..755ae0d
--- /dev/null
+++ b/domainname.tproj/Makefile.dist
@@ -0,0 +1,6 @@
+#	from: @(#)Makefile	5.3 (Berkeley) 5/11/90
+#	$Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:57:38 wsanchez Exp $
+
+PROG=	domainname
+
+.include <bsd.prog.mk>
diff --git a/domainname.tproj/PB.project b/domainname.tproj/PB.project
new file mode 100644
index 0000000..b16d0b9
--- /dev/null
+++ b/domainname.tproj/PB.project
@@ -0,0 +1,36 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LINKED = (domainname.c); 
+        OTHER_SOURCES = (Makefile.dist, domainname.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = domainname; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/domainname.tproj/domainname.1 b/domainname.tproj/domainname.1
new file mode 100644
index 0000000..074bf43
--- /dev/null
+++ b/domainname.tproj/domainname.1
@@ -0,0 +1,60 @@
+.\" Copyright (c) 1983, 1988, 1990 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	from: @(#)domainname.1	6.8 (Berkeley) 7/27/91
+.\"	$Id: domainname.1,v 1.1.1.1 1999/05/02 03:57:38 wsanchez Exp $
+.\"
+.Dd July 27, 1991
+.Dt DOMAINNAME 1
+.Os BSD 4.2
+.Sh NAME
+.Nm domainname
+.Nd set or print the name of the current domain
+.Sh SYNOPSIS
+.Nm domainname
+.Op Ar name-of-domain
+.Sh DESCRIPTION
+.Nm Domainname
+prints the domain name of the current host.  The super-user can
+set the domain name by supplying an argument; this is usually done in the
+network initialization script
+.Pa /etc/netstart ,
+normally run at boot
+time.
+.Sh SEE ALSO
+.Xr hostname 1 ,
+.Xr getdomainname 2 ,
+.Xr setdomainname 2 
+.Sh HISTORY
+The
+.Nm domainname
+command appeared in
+.Bx 4.2 .
diff --git a/domainname.tproj/domainname.c b/domainname.tproj/domainname.c
new file mode 100644
index 0000000..a229731
--- /dev/null
+++ b/domainname.tproj/domainname.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$Id: domainname.c,v 1.1.1.1 1999/05/02 03:57:38 wsanchez Exp $";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+static void usage __P((void));
+
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	char dom[MAXHOSTNAMELEN];
+
+	if( argc>2 ) {
+		usage ();
+		/* NOTREACHED */
+	}
+
+	if( argc==2 ) {
+		if( setdomainname(argv[1], strlen(argv[1])+1) == -1) {
+			perror("setdomainname");
+			exit(1);
+		}
+	} else {
+		if( getdomainname(dom, sizeof(dom)) == -1) {
+			perror("getdomainname");
+			exit(1);
+		}
+		printf("%s\n", dom);
+	}
+
+	exit(0);
+}
+
+static void
+usage ()
+{
+	(void)fprintf(stderr, "usage: domainname [name-of-domain]\n");
+	exit(1);
+}
diff --git a/ftp.tproj/Makefile b/ftp.tproj/Makefile
new file mode 100644
index 0000000..980a8c2
--- /dev/null
+++ b/ftp.tproj/Makefile
@@ -0,0 +1,52 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ftp
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = extern.h ftp_var.h pathnames.h
+
+CFILES = cmds.c cmdtab.c domacro.c ftp.c ftp_var.c main.c\
+         ruserpass.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
+            h.template ftp.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ftp.tproj/Makefile.postamble b/ftp.tproj/Makefile.postamble
new file mode 100644
index 0000000..7823726
--- /dev/null
+++ b/ftp.tproj/Makefile.postamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
diff --git a/ftp.tproj/Makefile.preamble b/ftp.tproj/Makefile.preamble
new file mode 100644
index 0000000..74ce95a
--- /dev/null
+++ b/ftp.tproj/Makefile.preamble
@@ -0,0 +1,130 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES =
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
diff --git a/ftp.tproj/PB.project b/ftp.tproj/PB.project
new file mode 100644
index 0000000..3b40ec2
--- /dev/null
+++ b/ftp.tproj/PB.project
@@ -0,0 +1,34 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (extern.h, ftp_var.h, pathnames.h); 
+        OTHER_LINKED = (cmds.c, cmdtab.c, domacro.c, ftp.c, ftp_var.c, main.c, ruserpass.c); 
+        OTHER_SOURCES = (
+            Makefile.preamble, 
+            Makefile, 
+            Makefile.postamble, 
+            m.template, 
+            h.template, 
+            ftp.1
+        ); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ftp; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ftp.tproj/cmds.c b/ftp.tproj/cmds.c
new file mode 100644
index 0000000..6dd3f48
--- /dev/null
+++ b/ftp.tproj/cmds.c
@@ -0,0 +1,2236 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * FTP User Program -- Command Routines.
+ */
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/ftp.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <glob.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "ftp_var.h"
+#include "pathnames.h"
+
+jmp_buf	jabort;
+char   *mname;
+char   *home = "/";
+
+/*
+ * `Another' gets another argument, and stores the new argc and argv.
+ * It reverts to the top level (via main.c's intr()) on EOF/error.
+ *
+ * Returns false if no new arguments have been added.
+ */
+int
+another(pargc, pargv, prompt)
+	int *pargc;
+	char ***pargv;
+	char *prompt;
+{
+	int len = strlen(line), ret;
+
+	if (len >= sizeof(line) - 3) {
+		printf("sorry, arguments too long\n");
+		intr();
+	}
+	printf("(%s) ", prompt);
+	line[len++] = ' ';
+	if (fgets(&line[len], sizeof(line) - len, stdin) == NULL)
+		intr();
+	len += strlen(&line[len]);
+	if (len > 0 && line[len - 1] == '\n')
+		line[len - 1] = '\0';
+	makeargv();
+	ret = margc > *pargc;
+	*pargc = margc;
+	*pargv = margv;
+	return (ret);
+}
+
+/*
+ * Connect to peer server and
+ * auto-login, if possible.
+ */
+void
+setpeer(argc, argv)
+	int argc;
+	char *argv[];
+{
+	char *host;
+	short port;
+
+	if (connected) {
+		printf("Already connected to %s, use close first.\n",
+			hostname);
+		code = -1;
+		return;
+	}
+	if (argc < 2)
+		(void) another(&argc, &argv, "to");
+	if (argc < 2 || argc > 3) {
+		printf("usage: %s host-name [port]\n", argv[0]);
+		code = -1;
+		return;
+	}
+	port = sp->s_port;
+	if (argc > 2) {
+		port = atoi(argv[2]);
+		if (port <= 0) {
+			printf("%s: bad port number-- %s\n", argv[1], argv[2]);
+			printf ("usage: %s host-name [port]\n", argv[0]);
+			code = -1;
+			return;
+		}
+		port = htons(port);
+	}
+	host = hookup(argv[1], port);
+	if (host) {
+		int overbose;
+
+		connected = 1;
+		/*
+		 * Set up defaults for FTP.
+		 */
+		(void) strcpy(typename, "ascii"), type = TYPE_A;
+		curtype = TYPE_A;
+		(void) strcpy(formname, "non-print"), form = FORM_N;
+		(void) strcpy(modename, "stream"), mode = MODE_S;
+		(void) strcpy(structname, "file"), stru = STRU_F;
+		(void) strcpy(bytename, "8"), bytesize = 8;
+		if (autologin)
+			(void) login(argv[1]);
+
+#if (defined(unix) || defined(__APPLE__)) && NBBY == 8
+/*
+ * this ifdef is to keep someone form "porting" this to an incompatible
+ * system and not checking this out. This way they have to think about it.
+ */
+		overbose = verbose;
+		if (debug == 0)
+			verbose = -1;
+		if (command("SYST") == COMPLETE && overbose) {
+			char *cp, c;
+			cp = strchr(reply_string+4, ' ');
+			if (cp == NULL)
+				cp = strchr(reply_string+4, '\r');
+			if (cp) {
+				if (cp[-1] == '.')
+					cp--;
+				c = *cp;
+				*cp = '\0';
+			}
+
+			printf("Remote system type is %s.\n",
+				reply_string+4);
+			if (cp)
+				*cp = c;
+		}
+		if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) {
+			if (proxy)
+				unix_proxy = 1;
+			else
+				unix_server = 1;
+			/*
+			 * Set type to 0 (not specified by user),
+			 * meaning binary by default, but don't bother
+			 * telling server.  We can use binary
+			 * for text files unless changed by the user.
+			 */
+			type = 0;
+			(void) strcpy(typename, "binary");
+			if (overbose)
+			    printf("Using %s mode to transfer files.\n",
+				typename);
+		} else {
+			if (proxy)
+				unix_proxy = 0;
+			else
+				unix_server = 0;
+			if (overbose && 
+			    !strncmp(reply_string, "215 TOPS20", 10))
+				printf(
+"Remember to set tenex mode when transfering binary files from this machine.\n");
+		}
+		verbose = overbose;
+#endif /* unix */
+	}
+}
+
+struct	types {
+	char	*t_name;
+	char	*t_mode;
+	int	t_type;
+	char	*t_arg;
+} types[] = {
+	{ "ascii",	"A",	TYPE_A,	0 },
+	{ "binary",	"I",	TYPE_I,	0 },
+	{ "image",	"I",	TYPE_I,	0 },
+	{ "ebcdic",	"E",	TYPE_E,	0 },
+	{ "tenex",	"L",	TYPE_L,	bytename },
+	{ NULL }
+};
+
+/*
+ * Set transfer type.
+ */
+void
+settype(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct types *p;
+	int comret;
+
+	if (argc > 2) {
+		char *sep;
+
+		printf("usage: %s [", argv[0]);
+		sep = " ";
+		for (p = types; p->t_name; p++) {
+			printf("%s%s", sep, p->t_name);
+			sep = " | ";
+		}
+		printf(" ]\n");
+		code = -1;
+		return;
+	}
+	if (argc < 2) {
+		printf("Using %s mode to transfer files.\n", typename);
+		code = 0;
+		return;
+	}
+	for (p = types; p->t_name; p++)
+		if (strcmp(argv[1], p->t_name) == 0)
+			break;
+	if (p->t_name == 0) {
+		printf("%s: unknown mode\n", argv[1]);
+		code = -1;
+		return;
+	}
+	if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
+		comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
+	else
+		comret = command("TYPE %s", p->t_mode);
+	if (comret == COMPLETE) {
+		(void) strcpy(typename, p->t_name);
+		curtype = type = p->t_type;
+	}
+}
+
+/*
+ * Internal form of settype; changes current type in use with server
+ * without changing our notion of the type for data transfers.
+ * Used to change to and from ascii for listings.
+ */
+void
+changetype(newtype, show)
+	int newtype, show;
+{
+	struct types *p;
+	int comret, oldverbose = verbose;
+
+	if (newtype == 0)
+		newtype = TYPE_I;
+	if (newtype == curtype)
+		return;
+	if (debug == 0 && show == 0)
+		verbose = 0;
+	for (p = types; p->t_name; p++)
+		if (newtype == p->t_type)
+			break;
+	if (p->t_name == 0) {
+		printf("ftp: internal error: unknown type %d\n", newtype);
+		return;
+	}
+	if (newtype == TYPE_L && bytename[0] != '\0')
+		comret = command("TYPE %s %s", p->t_mode, bytename);
+	else
+		comret = command("TYPE %s", p->t_mode);
+	if (comret == COMPLETE)
+		curtype = newtype;
+	verbose = oldverbose;
+}
+
+char *stype[] = {
+	"type",
+	"",
+	0
+};
+
+/*
+ * Set binary transfer type.
+ */
+/*VARARGS*/
+void
+setbinary(argc, argv)
+	int argc;
+	char **argv;
+{
+
+	stype[1] = "binary";
+	settype(2, stype);
+}
+
+/*
+ * Set ascii transfer type.
+ */
+/*VARARGS*/
+void
+setascii(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	stype[1] = "ascii";
+	settype(2, stype);
+}
+
+/*
+ * Set tenex transfer type.
+ */
+/*VARARGS*/
+void
+settenex(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	stype[1] = "tenex";
+	settype(2, stype);
+}
+
+/*
+ * Set file transfer mode.
+ */
+/*ARGSUSED*/
+void
+setftmode(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	printf("We only support %s mode, sorry.\n", modename);
+	code = -1;
+}
+
+/*
+ * Set file transfer format.
+ */
+/*ARGSUSED*/
+void
+setform(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	printf("We only support %s format, sorry.\n", formname);
+	code = -1;
+}
+
+/*
+ * Set file transfer structure.
+ */
+/*ARGSUSED*/
+void
+setstruct(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	printf("We only support %s structure, sorry.\n", structname);
+	code = -1;
+}
+
+/*
+ * Send a single file.
+ */
+void
+put(argc, argv)
+	int argc;
+	char *argv[];
+{
+	char *cmd;
+	int loc = 0;
+	char *oldargv1, *oldargv2;
+
+	if (argc == 2) {
+		argc++;
+		argv[2] = argv[1];
+		loc++;
+	}
+	if (argc < 2 && !another(&argc, &argv, "local-file"))
+		goto usage;
+	if (argc < 3 && !another(&argc, &argv, "remote-file")) {
+usage:
+		printf("usage: %s local-file remote-file\n", argv[0]);
+		code = -1;
+		return;
+	}
+	oldargv1 = argv[1];
+	oldargv2 = argv[2];
+	if (!globulize(&argv[1])) {
+		code = -1;
+		return;
+	}
+	/*
+	 * If "globulize" modifies argv[1], and argv[2] is a copy of
+	 * the old argv[1], make it a copy of the new argv[1].
+	 */
+	if (argv[1] != oldargv1 && argv[2] == oldargv1) {
+		argv[2] = argv[1];
+	}
+	cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
+	if (loc && ntflag) {
+		argv[2] = dotrans(argv[2]);
+	}
+	if (loc && mapflag) {
+		argv[2] = domap(argv[2]);
+	}
+	sendrequest(cmd, argv[1], argv[2],
+	    argv[1] != oldargv1 || argv[2] != oldargv2);
+}
+
+/*
+ * Send multiple files.
+ */
+void
+mput(argc, argv)
+	int argc;
+	char **argv;
+{
+	int i;
+	sig_t oldintr;
+	int ointer;
+	char *tp;
+
+	if (argc < 2 && !another(&argc, &argv, "local-files")) {
+		printf("usage: %s local-files\n", argv[0]);
+		code = -1;
+		return;
+	}
+	mname = argv[0];
+	mflag = 1;
+	oldintr = signal(SIGINT, mabort);
+	(void) setjmp(jabort);
+	if (proxy) {
+		char *cp, *tp2, tmpbuf[MAXPATHLEN];
+
+		while ((cp = remglob(argv,0)) != NULL) {
+			if (*cp == 0) {
+				mflag = 0;
+				continue;
+			}
+			if (mflag && confirm(argv[0], cp)) {
+				tp = cp;
+				if (mcase) {
+					while (*tp && !islower(*tp)) {
+						tp++;
+					}
+					if (!*tp) {
+						tp = cp;
+						tp2 = tmpbuf;
+						while ((*tp2 = *tp) != NULL) {
+						     if (isupper(*tp2)) {
+						        *tp2 = 'a' + *tp2 - 'A';
+						     }
+						     tp++;
+						     tp2++;
+						}
+					}
+					tp = tmpbuf;
+				}
+				if (ntflag) {
+					tp = dotrans(tp);
+				}
+				if (mapflag) {
+					tp = domap(tp);
+				}
+				sendrequest((sunique) ? "STOU" : "STOR",
+				    cp, tp, cp != tp || !interactive);
+				if (!mflag && fromatty) {
+					ointer = interactive;
+					interactive = 1;
+					if (confirm("Continue with","mput")) {
+						mflag++;
+					}
+					interactive = ointer;
+				}
+			}
+		}
+		(void) signal(SIGINT, oldintr);
+		mflag = 0;
+		return;
+	}
+	for (i = 1; i < argc; i++) {
+		char **cpp, **gargs;
+		glob_t gl;
+		int flags;
+
+		if (!doglob) {
+			if (mflag && confirm(argv[0], argv[i])) {
+				tp = (ntflag) ? dotrans(argv[i]) : argv[i];
+				tp = (mapflag) ? domap(tp) : tp;
+				sendrequest((sunique) ? "STOU" : "STOR",
+				    argv[i], tp, tp != argv[i] || !interactive);
+				if (!mflag && fromatty) {
+					ointer = interactive;
+					interactive = 1;
+					if (confirm("Continue with","mput")) {
+						mflag++;
+					}
+					interactive = ointer;
+				}
+			}
+			continue;
+		}
+
+		memset(&gl, 0, sizeof(gl));
+		flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+		if (glob(argv[i], flags, NULL, &gl) || gl.gl_pathc == 0) {
+			warnx("%s: not found", argv[i]);
+			globfree(&gl);
+			continue;
+		}
+		for (cpp = gl.gl_pathv; cpp && *cpp != NULL; cpp++) {
+			if (mflag && confirm(argv[0], *cpp)) {
+				tp = (ntflag) ? dotrans(*cpp) : *cpp;
+				tp = (mapflag) ? domap(tp) : tp;
+				sendrequest((sunique) ? "STOU" : "STOR",
+				    *cpp, tp, *cpp != tp || !interactive);
+				if (!mflag && fromatty) {
+					ointer = interactive;
+					interactive = 1;
+					if (confirm("Continue with","mput")) {
+						mflag++;
+					}
+					interactive = ointer;
+				}
+			}
+		}
+		globfree(&gl);
+	}
+	(void) signal(SIGINT, oldintr);
+	mflag = 0;
+}
+
+void
+reget(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	(void) getit(argc, argv, 1, "r+w");
+}
+
+void
+get(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	(void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );
+}
+
+/*
+ * Receive one file.
+ */
+int
+getit(argc, argv, restartit, mode)
+	int argc;
+	char *argv[];
+	char *mode;
+	int restartit;
+{
+	int loc = 0;
+	char *oldargv1, *oldargv2;
+
+	if (argc == 2) {
+		argc++;
+		argv[2] = argv[1];
+		loc++;
+	}
+	if (argc < 2 && !another(&argc, &argv, "remote-file"))
+		goto usage;
+	if (argc < 3 && !another(&argc, &argv, "local-file")) {
+usage:
+		printf("usage: %s remote-file [ local-file ]\n", argv[0]);
+		code = -1;
+		return (0);
+	}
+	oldargv1 = argv[1];
+	oldargv2 = argv[2];
+	if (!globulize(&argv[2])) {
+		code = -1;
+		return (0);
+	}
+	if (loc && mcase) {
+		char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN];
+
+		while (*tp && !islower(*tp)) {
+			tp++;
+		}
+		if (!*tp) {
+			tp = argv[2];
+			tp2 = tmpbuf;
+			while ((*tp2 = *tp) != NULL) {
+				if (isupper(*tp2)) {
+					*tp2 = 'a' + *tp2 - 'A';
+				}
+				tp++;
+				tp2++;
+			}
+			argv[2] = tmpbuf;
+		}
+	}
+	if (loc && ntflag)
+		argv[2] = dotrans(argv[2]);
+	if (loc && mapflag)
+		argv[2] = domap(argv[2]);
+	if (restartit) {
+		struct stat stbuf;
+		int ret;
+
+		ret = stat(argv[2], &stbuf);
+		if (restartit == 1) {
+			if (ret < 0) {
+				warn("local: %s", argv[2]);
+				return (0);
+			}
+			restart_point = stbuf.st_size;
+		} else {
+			if (ret == 0) {
+				int overbose;
+
+				overbose = verbose;
+				if (debug == 0)
+					verbose = -1;
+				if (command("MDTM %s", argv[1]) == COMPLETE) {
+					int yy, mo, day, hour, min, sec;
+					struct tm *tm;
+					verbose = overbose;
+					sscanf(reply_string,
+					    "%*s %04d%02d%02d%02d%02d%02d",
+					    &yy, &mo, &day, &hour, &min, &sec);
+					tm = gmtime(&stbuf.st_mtime);
+					tm->tm_mon++;
+					if (tm->tm_year > yy%100)
+						return (1);
+					if ((tm->tm_year == yy%100 && 
+					    tm->tm_mon > mo) ||
+					   (tm->tm_mon == mo && 
+					    tm->tm_mday > day) ||
+					   (tm->tm_mday == day && 
+					    tm->tm_hour > hour) ||
+					   (tm->tm_hour == hour && 
+					    tm->tm_min > min) ||
+					   (tm->tm_min == min && 
+					    tm->tm_sec > sec))
+						return (1);
+				} else {
+					printf("%s\n", reply_string);
+					verbose = overbose;
+					return (0);
+				}
+			}
+		}
+	}
+
+	recvrequest("RETR", argv[2], argv[1], mode,
+	    argv[1] != oldargv1 || argv[2] != oldargv2);
+	restart_point = 0;
+	return (0);
+}
+
+/* ARGSUSED */
+void
+mabort(signo)
+	int signo;
+{
+	int ointer;
+
+	printf("\n");
+	(void) fflush(stdout);
+	if (mflag && fromatty) {
+		ointer = interactive;
+		interactive = 1;
+		if (confirm("Continue with", mname)) {
+			interactive = ointer;
+			longjmp(jabort,0);
+		}
+		interactive = ointer;
+	}
+	mflag = 0;
+	longjmp(jabort,0);
+}
+
+/*
+ * Get multiple files.
+ */
+void
+mget(argc, argv)
+	int argc;
+	char **argv;
+{
+	sig_t oldintr;
+	int ch, ointer;
+	char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN];
+
+	if (argc < 2 && !another(&argc, &argv, "remote-files")) {
+		printf("usage: %s remote-files\n", argv[0]);
+		code = -1;
+		return;
+	}
+	mname = argv[0];
+	mflag = 1;
+	oldintr = signal(SIGINT, mabort);
+	(void) setjmp(jabort);
+	while ((cp = remglob(argv,proxy)) != NULL) {
+		if (*cp == '\0') {
+			mflag = 0;
+			continue;
+		}
+		if (mflag && confirm(argv[0], cp)) {
+			tp = cp;
+			if (mcase) {
+				for (tp2 = tmpbuf; ch = *tp++;)
+					*tp2++ = isupper(ch) ? tolower(ch) : ch;
+				tp = tmpbuf;
+			}
+			if (ntflag) {
+				tp = dotrans(tp);
+			}
+			if (mapflag) {
+				tp = domap(tp);
+			}
+			recvrequest("RETR", tp, cp, "w",
+			    tp != cp || !interactive);
+			if (!mflag && fromatty) {
+				ointer = interactive;
+				interactive = 1;
+				if (confirm("Continue with","mget")) {
+					mflag++;
+				}
+				interactive = ointer;
+			}
+		}
+	}
+	(void) signal(SIGINT,oldintr);
+	mflag = 0;
+}
+
+char *
+remglob(argv,doswitch)
+	char *argv[];
+	int doswitch;
+{
+	char temp[16];
+	static char buf[MAXPATHLEN];
+	static FILE *ftemp = NULL;
+	static char **args;
+	int oldverbose, oldhash;
+	char *cp, *mode;
+
+	if (!mflag) {
+		if (!doglob) {
+			args = NULL;
+		}
+		else {
+			if (ftemp) {
+				(void) fclose(ftemp);
+				ftemp = NULL;
+			}
+		}
+		return (NULL);
+	}
+	if (!doglob) {
+		if (args == NULL)
+			args = argv;
+		if ((cp = *++args) == NULL)
+			args = NULL;
+		return (cp);
+	}
+	if (ftemp == NULL) {
+		(void) strcpy(temp, _PATH_TMP);
+		(void) mktemp(temp);
+		oldverbose = verbose, verbose = 0;
+		oldhash = hash, hash = 0;
+		if (doswitch) {
+			pswitch(!proxy);
+		}
+		for (mode = "w"; *++argv != NULL; mode = "a")
+			recvrequest ("NLST", temp, *argv, mode, 0);
+		if (doswitch) {
+			pswitch(!proxy);
+		}
+		verbose = oldverbose; hash = oldhash;
+		ftemp = fopen(temp, "r");
+		(void) unlink(temp);
+		if (ftemp == NULL) {
+			printf("can't find list of remote files, oops\n");
+			return (NULL);
+		}
+	}
+	if (fgets(buf, sizeof (buf), ftemp) == NULL) {
+		(void) fclose(ftemp), ftemp = NULL;
+		return (NULL);
+	}
+	if ((cp = strchr(buf, '\n')) != NULL)
+		*cp = '\0';
+	return (buf);
+}
+
+char *
+onoff(bool)
+	int bool;
+{
+
+	return (bool ? "on" : "off");
+}
+
+/*
+ * Show status.
+ */
+/*ARGSUSED*/
+void
+status(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int i;
+
+	if (connected)
+		printf("Connected to %s.\n", hostname);
+	else
+		printf("Not connected.\n");
+	if (!proxy) {
+		pswitch(1);
+		if (connected) {
+			printf("Connected for proxy commands to %s.\n", hostname);
+		}
+		else {
+			printf("No proxy connection.\n");
+		}
+		pswitch(0);
+	}
+	printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
+		modename, typename, formname, structname);
+	printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 
+		onoff(verbose), onoff(bell), onoff(interactive),
+		onoff(doglob));
+	printf("Store unique: %s; Receive unique: %s\n", onoff(sunique),
+		onoff(runique));
+	printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag));
+	if (ntflag) {
+		printf("Ntrans: (in) %s (out) %s\n", ntin,ntout);
+	}
+	else {
+		printf("Ntrans: off\n");
+	}
+	if (mapflag) {
+		printf("Nmap: (in) %s (out) %s\n", mapin, mapout);
+	}
+	else {
+		printf("Nmap: off\n");
+	}
+	printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
+		onoff(hash), onoff(sendport));
+	if (macnum > 0) {
+		printf("Macros:\n");
+		for (i=0; i<macnum; i++) {
+			printf("\t%s\n",macros[i].mac_name);
+		}
+	}
+	code = 0;
+}
+
+/*
+ * Set beep on cmd completed mode.
+ */
+/*VARARGS*/
+void
+setbell(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	bell = !bell;
+	printf("Bell mode %s.\n", onoff(bell));
+	code = bell;
+}
+
+/*
+ * Turn on packet tracing.
+ */
+/*VARARGS*/
+void
+settrace(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	trace = !trace;
+	printf("Packet tracing %s.\n", onoff(trace));
+	code = trace;
+}
+
+/*
+ * Toggle hash mark printing during transfers.
+ */
+/*VARARGS*/
+void
+sethash(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	hash = !hash;
+	printf("Hash mark printing %s", onoff(hash));
+	code = hash;
+	if (hash)
+		printf(" (%d bytes/hash mark)", 1024);
+	printf(".\n");
+}
+
+/*
+ * Turn on printing of server echo's.
+ */
+/*VARARGS*/
+void
+setverbose(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	verbose = !verbose;
+	printf("Verbose mode %s.\n", onoff(verbose));
+	code = verbose;
+}
+
+/*
+ * Toggle PORT cmd use before each data connection.
+ */
+/*VARARGS*/
+void
+setport(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	sendport = !sendport;
+	printf("Use of PORT cmds %s.\n", onoff(sendport));
+	code = sendport;
+}
+
+/*
+ * Turn on interactive prompting
+ * during mget, mput, and mdelete.
+ */
+/*VARARGS*/
+void
+setprompt(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	interactive = !interactive;
+	printf("Interactive mode %s.\n", onoff(interactive));
+	code = interactive;
+}
+
+/*
+ * Toggle metacharacter interpretation
+ * on local file names.
+ */
+/*VARARGS*/
+void
+setglob(argc, argv)
+	int argc;
+	char *argv[];
+{
+	
+	doglob = !doglob;
+	printf("Globbing %s.\n", onoff(doglob));
+	code = doglob;
+}
+
+/*
+ * Set debugging mode on/off and/or
+ * set level of debugging.
+ */
+/*VARARGS*/
+void
+setdebug(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int val;
+
+	if (argc > 1) {
+		val = atoi(argv[1]);
+		if (val < 0) {
+			printf("%s: bad debugging value.\n", argv[1]);
+			code = -1;
+			return;
+		}
+	} else
+		val = !debug;
+	debug = val;
+	if (debug)
+		options |= SO_DEBUG;
+	else
+		options &= ~SO_DEBUG;
+	printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
+	code = debug > 0;
+}
+
+/*
+ * Set current working directory
+ * on remote machine.
+ */
+void
+cd(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc < 2 && !another(&argc, &argv, "remote-directory")) {
+		printf("usage: %s remote-directory\n", argv[0]);
+		code = -1;
+		return;
+	}
+	if (command("CWD %s", argv[1]) == ERROR && code == 500) {
+		if (verbose)
+			printf("CWD command not recognized, trying XCWD\n");
+		(void) command("XCWD %s", argv[1]);
+	}
+}
+
+/*
+ * Set current working directory
+ * on local machine.
+ */
+void
+lcd(argc, argv)
+	int argc;
+	char *argv[];
+{
+	char buf[MAXPATHLEN];
+
+	if (argc < 2)
+		argc++, argv[1] = home;
+	if (argc != 2) {
+		printf("usage: %s local-directory\n", argv[0]);
+		code = -1;
+		return;
+	}
+	if (!globulize(&argv[1])) {
+		code = -1;
+		return;
+	}
+	if (chdir(argv[1]) < 0) {
+		warn("local: %s", argv[1]);
+		code = -1;
+		return;
+	}
+	if (getwd(buf) != NULL)
+		printf("Local directory now %s\n", buf);
+	else
+		warnx("getwd: %s", buf);
+	code = 0;
+}
+
+/*
+ * Delete a single file.
+ */
+void
+delete(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc < 2 && !another(&argc, &argv, "remote-file")) {
+		printf("usage: %s remote-file\n", argv[0]);
+		code = -1;
+		return;
+	}
+	(void) command("DELE %s", argv[1]);
+}
+
+/*
+ * Delete multiple files.
+ */
+void
+mdelete(argc, argv)
+	int argc;
+	char **argv;
+{
+	sig_t oldintr;
+	int ointer;
+	char *cp;
+
+	if (argc < 2 && !another(&argc, &argv, "remote-files")) {
+		printf("usage: %s remote-files\n", argv[0]);
+		code = -1;
+		return;
+	}
+	mname = argv[0];
+	mflag = 1;
+	oldintr = signal(SIGINT, mabort);
+	(void) setjmp(jabort);
+	while ((cp = remglob(argv,0)) != NULL) {
+		if (*cp == '\0') {
+			mflag = 0;
+			continue;
+		}
+		if (mflag && confirm(argv[0], cp)) {
+			(void) command("DELE %s", cp);
+			if (!mflag && fromatty) {
+				ointer = interactive;
+				interactive = 1;
+				if (confirm("Continue with", "mdelete")) {
+					mflag++;
+				}
+				interactive = ointer;
+			}
+		}
+	}
+	(void) signal(SIGINT, oldintr);
+	mflag = 0;
+}
+
+/*
+ * Rename a remote file.
+ */
+void
+renamefile(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc < 2 && !another(&argc, &argv, "from-name"))
+		goto usage;
+	if (argc < 3 && !another(&argc, &argv, "to-name")) {
+usage:
+		printf("%s from-name to-name\n", argv[0]);
+		code = -1;
+		return;
+	}
+	if (command("RNFR %s", argv[1]) == CONTINUE)
+		(void) command("RNTO %s", argv[2]);
+}
+
+/*
+ * Get a directory listing
+ * of remote files.
+ */
+void
+ls(argc, argv)
+	int argc;
+	char *argv[];
+{
+	char *cmd;
+
+	if (argc < 2)
+		argc++, argv[1] = NULL;
+	if (argc < 3)
+		argc++, argv[2] = "-";
+	if (argc > 3) {
+		printf("usage: %s remote-directory local-file\n", argv[0]);
+		code = -1;
+		return;
+	}
+	cmd = argv[0][0] == 'n' ? "NLST" : "LIST";
+	if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
+		code = -1;
+		return;
+	}
+	if (strcmp(argv[2], "-") && *argv[2] != '|')
+		if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) {
+			code = -1;
+			return;
+	}
+	recvrequest(cmd, argv[2], argv[1], "w", 0);
+}
+
+/*
+ * Get a directory listing
+ * of multiple remote files.
+ */
+void
+mls(argc, argv)
+	int argc;
+	char **argv;
+{
+	sig_t oldintr;
+	int ointer, i;
+	char *cmd, mode[1], *dest;
+
+	if (argc < 2 && !another(&argc, &argv, "remote-files"))
+		goto usage;
+	if (argc < 3 && !another(&argc, &argv, "local-file")) {
+usage:
+		printf("usage: %s remote-files local-file\n", argv[0]);
+		code = -1;
+		return;
+	}
+	dest = argv[argc - 1];
+	argv[argc - 1] = NULL;
+	if (strcmp(dest, "-") && *dest != '|')
+		if (!globulize(&dest) ||
+		    !confirm("output to local-file:", dest)) {
+			code = -1;
+			return;
+	}
+	cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
+	mname = argv[0];
+	mflag = 1;
+	oldintr = signal(SIGINT, mabort);
+	(void) setjmp(jabort);
+	for (i = 1; mflag && i < argc-1; ++i) {
+		*mode = (i == 1) ? 'w' : 'a';
+		recvrequest(cmd, dest, argv[i], mode, 0);
+		if (!mflag && fromatty) {
+			ointer = interactive;
+			interactive = 1;
+			if (confirm("Continue with", argv[0])) {
+				mflag ++;
+			}
+			interactive = ointer;
+		}
+	}
+	(void) signal(SIGINT, oldintr);
+	mflag = 0;
+}
+
+/*
+ * Do a shell escape
+ */
+/*ARGSUSED*/
+void
+shell(argc, argv)
+	int argc;
+	char **argv;
+{
+	pid_t pid;
+	sig_t old1, old2;
+	char shellnam[40], *shell, *namep; 
+	union wait status;
+
+	old1 = signal (SIGINT, SIG_IGN);
+	old2 = signal (SIGQUIT, SIG_IGN);
+	if ((pid = fork()) == 0) {
+		for (pid = 3; pid < 20; pid++)
+			(void) close(pid);
+		(void) signal(SIGINT, SIG_DFL);
+		(void) signal(SIGQUIT, SIG_DFL);
+		shell = getenv("SHELL");
+		if (shell == NULL)
+			shell = _PATH_BSHELL;
+		namep = strrchr(shell,'/');
+		if (namep == NULL)
+			namep = shell;
+		(void) strcpy(shellnam,"-");
+		(void) strcat(shellnam, ++namep);
+		if (strcmp(namep, "sh") != 0)
+			shellnam[0] = '+';
+		if (debug) {
+			printf ("%s\n", shell);
+			(void) fflush (stdout);
+		}
+		if (argc > 1) {
+			execl(shell,shellnam,"-c",altarg,(char *)0);
+		}
+		else {
+			execl(shell,shellnam,(char *)0);
+		}
+		warn("%s", shell);
+		code = -1;
+		exit(1);
+	}
+	if (pid > 0)
+		while (wait((int *)&status) != pid)
+			;
+	(void) signal(SIGINT, old1);
+	(void) signal(SIGQUIT, old2);
+	if (pid == -1) {
+		warn("%s", "Try again later");
+		code = -1;
+	}
+	else {
+		code = 0;
+	}
+}
+
+/*
+ * Send new user information (re-login)
+ */
+void
+user(argc, argv)
+	int argc;
+	char **argv;
+{
+	char acct[80];
+	int n, aflag = 0;
+
+	if (argc < 2)
+		(void) another(&argc, &argv, "username");
+	if (argc < 2 || argc > 4) {
+		printf("usage: %s username [password] [account]\n", argv[0]);
+		code = -1;
+		return;
+	}
+	n = command("USER %s", argv[1]);
+	if (n == CONTINUE) {
+		if (argc < 3 )
+			argv[2] = getpass("Password: "), argc++;
+		n = command("PASS %s", argv[2]);
+	}
+	if (n == CONTINUE) {
+		if (argc < 4) {
+			printf("Account: "); (void) fflush(stdout);
+			(void) fgets(acct, sizeof(acct) - 1, stdin);
+			acct[strlen(acct) - 1] = '\0';
+			argv[3] = acct; argc++;
+		}
+		n = command("ACCT %s", argv[3]);
+		aflag++;
+	}
+	if (n != COMPLETE) {
+		fprintf(stdout, "Login failed.\n");
+		return;
+	}
+	if (!aflag && argc == 4) {
+		(void) command("ACCT %s", argv[3]);
+	}
+}
+
+/*
+ * Print working directory.
+ */
+/*VARARGS*/
+void
+pwd(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int oldverbose = verbose;
+
+	/*
+	 * If we aren't verbose, this doesn't do anything!
+	 */
+	verbose = 1;
+	if (command("PWD") == ERROR && code == 500) {
+		printf("PWD command not recognized, trying XPWD\n");
+		(void) command("XPWD");
+	}
+	verbose = oldverbose;
+}
+
+/*
+ * Make a directory.
+ */
+void
+makedir(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc < 2 && !another(&argc, &argv, "directory-name")) {
+		printf("usage: %s directory-name\n", argv[0]);
+		code = -1;
+		return;
+	}
+	if (command("MKD %s", argv[1]) == ERROR && code == 500) {
+		if (verbose)
+			printf("MKD command not recognized, trying XMKD\n");
+		(void) command("XMKD %s", argv[1]);
+	}
+}
+
+/*
+ * Remove a directory.
+ */
+void
+removedir(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc < 2 && !another(&argc, &argv, "directory-name")) {
+		printf("usage: %s directory-name\n", argv[0]);
+		code = -1;
+		return;
+	}
+	if (command("RMD %s", argv[1]) == ERROR && code == 500) {
+		if (verbose)
+			printf("RMD command not recognized, trying XRMD\n");
+		(void) command("XRMD %s", argv[1]);
+	}
+}
+
+/*
+ * Send a line, verbatim, to the remote machine.
+ */
+void
+quote(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc < 2 && !another(&argc, &argv, "command line to send")) {
+		printf("usage: %s line-to-send\n", argv[0]);
+		code = -1;
+		return;
+	}
+	quote1("", argc, argv);
+}
+
+/*
+ * Send a SITE command to the remote machine.  The line
+ * is sent verbatim to the remote machine, except that the
+ * word "SITE" is added at the front.
+ */
+void
+site(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc < 2 && !another(&argc, &argv, "arguments to SITE command")) {
+		printf("usage: %s line-to-send\n", argv[0]);
+		code = -1;
+		return;
+	}
+	quote1("SITE ", argc, argv);
+}
+
+/*
+ * Turn argv[1..argc) into a space-separated string, then prepend initial text.
+ * Send the result as a one-line command and get response.
+ */
+void
+quote1(initial, argc, argv)
+	char *initial;
+	int argc;
+	char **argv;
+{
+	int i, len;
+	char buf[BUFSIZ];		/* must be >= sizeof(line) */
+
+	(void) strcpy(buf, initial);
+	if (argc > 1) {
+		len = strlen(buf);
+		len += strlen(strcpy(&buf[len], argv[1]));
+		for (i = 2; i < argc; i++) {
+			buf[len++] = ' ';
+			len += strlen(strcpy(&buf[len], argv[i]));
+		}
+	}
+	if (command(buf) == PRELIM) {
+		while (getreply(0) == PRELIM)
+			continue;
+	}
+}
+
+void
+do_chmod(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc < 2 && !another(&argc, &argv, "mode"))
+		goto usage;
+	if (argc < 3 && !another(&argc, &argv, "file-name")) {
+usage:
+		printf("usage: %s mode file-name\n", argv[0]);
+		code = -1;
+		return;
+	}
+	(void) command("SITE CHMOD %s %s", argv[1], argv[2]);
+}
+
+void
+do_umask(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int oldverbose = verbose;
+
+	verbose = 1;
+	(void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]);
+	verbose = oldverbose;
+}
+
+void
+idle(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int oldverbose = verbose;
+
+	verbose = 1;
+	(void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]);
+	verbose = oldverbose;
+}
+
+/*
+ * Ask the other side for help.
+ */
+void
+rmthelp(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int oldverbose = verbose;
+
+	verbose = 1;
+	(void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
+	verbose = oldverbose;
+}
+
+/*
+ * Terminate session and exit.
+ */
+/*VARARGS*/
+void
+quit(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (connected)
+		disconnect(0, 0);
+	pswitch(1);
+	if (connected) {
+		disconnect(0, 0);
+	}
+	exit(0);
+}
+
+/*
+ * Terminate session, but don't exit.
+ */
+void
+disconnect(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (!connected)
+		return;
+	(void) command("QUIT");
+	if (cout) {
+		(void) fclose(cout);
+	}
+	cout = NULL;
+	connected = 0;
+	data = -1;
+	if (!proxy) {
+		macnum = 0;
+	}
+}
+
+int
+confirm(cmd, file)
+	char *cmd, *file;
+{
+	char line[BUFSIZ];
+
+	if (!interactive)
+		return (1);
+	printf("%s %s? ", cmd, file);
+	(void) fflush(stdout);
+	if (fgets(line, sizeof line, stdin) == NULL)
+		return (0);
+	return (*line != 'n' && *line != 'N');
+}
+
+void
+fatal(msg)
+	char *msg;
+{
+
+	errx(1, "%s", msg);
+}
+
+/*
+ * Glob a local file name specification with
+ * the expectation of a single return value.
+ * Can't control multiple values being expanded
+ * from the expression, we return only the first.
+ */
+int
+globulize(cpp)
+	char **cpp;
+{
+	glob_t gl;
+	int flags;
+
+	if (!doglob)
+		return (1);
+
+	flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+	memset(&gl, 0, sizeof(gl));
+	if (glob(*cpp, flags, NULL, &gl) ||
+	    gl.gl_pathc == 0) {
+		warnx("%s: not found", *cpp);
+		globfree(&gl);
+		return (0);
+	}
+	*cpp = strdup(gl.gl_pathv[0]);	/* XXX - wasted memory */
+	globfree(&gl);
+	return (1);
+}
+
+void
+account(argc,argv)
+	int argc;
+	char **argv;
+{
+	char acct[50], *ap;
+
+	if (argc > 1) {
+		++argv;
+		--argc;
+		(void) strncpy(acct,*argv,49);
+		acct[49] = '\0';
+		while (argc > 1) {
+			--argc;
+			++argv;
+			(void) strncat(acct,*argv, 49-strlen(acct));
+		}
+		ap = acct;
+	}
+	else {
+		ap = getpass("Account:");
+	}
+	(void) command("ACCT %s", ap);
+}
+
+jmp_buf abortprox;
+
+void
+proxabort()
+{
+
+	if (!proxy) {
+		pswitch(1);
+	}
+	if (connected) {
+		proxflag = 1;
+	}
+	else {
+		proxflag = 0;
+	}
+	pswitch(0);
+	longjmp(abortprox,1);
+}
+
+void
+doproxy(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct cmd *c;
+	sig_t oldintr;
+
+	if (argc < 2 && !another(&argc, &argv, "command")) {
+		printf("usage: %s command\n", argv[0]);
+		code = -1;
+		return;
+	}
+	c = getcmd(argv[1]);
+	if (c == (struct cmd *) -1) {
+		printf("?Ambiguous command\n");
+		(void) fflush(stdout);
+		code = -1;
+		return;
+	}
+	if (c == 0) {
+		printf("?Invalid command\n");
+		(void) fflush(stdout);
+		code = -1;
+		return;
+	}
+	if (!c->c_proxy) {
+		printf("?Invalid proxy command\n");
+		(void) fflush(stdout);
+		code = -1;
+		return;
+	}
+	if (setjmp(abortprox)) {
+		code = -1;
+		return;
+	}
+	oldintr = signal(SIGINT, proxabort);
+	pswitch(1);
+	if (c->c_conn && !connected) {
+		printf("Not connected\n");
+		(void) fflush(stdout);
+		pswitch(0);
+		(void) signal(SIGINT, oldintr);
+		code = -1;
+		return;
+	}
+	(*c->c_handler)(argc-1, argv+1);
+	if (connected) {
+		proxflag = 1;
+	}
+	else {
+		proxflag = 0;
+	}
+	pswitch(0);
+	(void) signal(SIGINT, oldintr);
+}
+
+void
+setcase(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	mcase = !mcase;
+	printf("Case mapping %s.\n", onoff(mcase));
+	code = mcase;
+}
+
+void
+setcr(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	crflag = !crflag;
+	printf("Carriage Return stripping %s.\n", onoff(crflag));
+	code = crflag;
+}
+
+void
+setntrans(argc,argv)
+	int argc;
+	char *argv[];
+{
+	if (argc == 1) {
+		ntflag = 0;
+		printf("Ntrans off.\n");
+		code = ntflag;
+		return;
+	}
+	ntflag++;
+	code = ntflag;
+	(void) strncpy(ntin, argv[1], 16);
+	ntin[16] = '\0';
+	if (argc == 2) {
+		ntout[0] = '\0';
+		return;
+	}
+	(void) strncpy(ntout, argv[2], 16);
+	ntout[16] = '\0';
+}
+
+char *
+dotrans(name)
+	char *name;
+{
+	static char new[MAXPATHLEN];
+	char *cp1, *cp2 = new;
+	int i, ostop, found;
+
+	for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++)
+		continue;
+	for (cp1 = name; *cp1; cp1++) {
+		found = 0;
+		for (i = 0; *(ntin + i) && i < 16; i++) {
+			if (*cp1 == *(ntin + i)) {
+				found++;
+				if (i < ostop) {
+					*cp2++ = *(ntout + i);
+				}
+				break;
+			}
+		}
+		if (!found) {
+			*cp2++ = *cp1;
+		}
+	}
+	*cp2 = '\0';
+	return (new);
+}
+
+void
+setnmap(argc, argv)
+	int argc;
+	char *argv[];
+{
+	char *cp;
+
+	if (argc == 1) {
+		mapflag = 0;
+		printf("Nmap off.\n");
+		code = mapflag;
+		return;
+	}
+	if (argc < 3 && !another(&argc, &argv, "mapout")) {
+		printf("Usage: %s [mapin mapout]\n",argv[0]);
+		code = -1;
+		return;
+	}
+	mapflag = 1;
+	code = 1;
+	cp = strchr(altarg, ' ');
+	if (proxy) {
+		while(*++cp == ' ')
+			continue;
+		altarg = cp;
+		cp = strchr(altarg, ' ');
+	}
+	*cp = '\0';
+	(void) strncpy(mapin, altarg, MAXPATHLEN - 1);
+	while (*++cp == ' ')
+		continue;
+	(void) strncpy(mapout, cp, MAXPATHLEN - 1);
+}
+
+char *
+domap(name)
+	char *name;
+{
+	static char new[MAXPATHLEN];
+	char *cp1 = name, *cp2 = mapin;
+	char *tp[9], *te[9];
+	int i, toks[9], toknum = 0, match = 1;
+
+	for (i=0; i < 9; ++i) {
+		toks[i] = 0;
+	}
+	while (match && *cp1 && *cp2) {
+		switch (*cp2) {
+			case '\\':
+				if (*++cp2 != *cp1) {
+					match = 0;
+				}
+				break;
+			case '$':
+				if (*(cp2+1) >= '1' && (*cp2+1) <= '9') {
+					if (*cp1 != *(++cp2+1)) {
+						toks[toknum = *cp2 - '1']++;
+						tp[toknum] = cp1;
+						while (*++cp1 && *(cp2+1)
+							!= *cp1);
+						te[toknum] = cp1;
+					}
+					cp2++;
+					break;
+				}
+				/* FALLTHROUGH */
+			default:
+				if (*cp2 != *cp1) {
+					match = 0;
+				}
+				break;
+		}
+		if (match && *cp1) {
+			cp1++;
+		}
+		if (match && *cp2) {
+			cp2++;
+		}
+	}
+	if (!match && *cp1) /* last token mismatch */
+	{
+		toks[toknum] = 0;
+	}
+	cp1 = new;
+	*cp1 = '\0';
+	cp2 = mapout;
+	while (*cp2) {
+		match = 0;
+		switch (*cp2) {
+			case '\\':
+				if (*(cp2 + 1)) {
+					*cp1++ = *++cp2;
+				}
+				break;
+			case '[':
+LOOP:
+				if (*++cp2 == '$' && isdigit(*(cp2+1))) { 
+					if (*++cp2 == '0') {
+						char *cp3 = name;
+
+						while (*cp3) {
+							*cp1++ = *cp3++;
+						}
+						match = 1;
+					}
+					else if (toks[toknum = *cp2 - '1']) {
+						char *cp3 = tp[toknum];
+
+						while (cp3 != te[toknum]) {
+							*cp1++ = *cp3++;
+						}
+						match = 1;
+					}
+				}
+				else {
+					while (*cp2 && *cp2 != ',' && 
+					    *cp2 != ']') {
+						if (*cp2 == '\\') {
+							cp2++;
+						}
+						else if (*cp2 == '$' &&
+   						        isdigit(*(cp2+1))) {
+							if (*++cp2 == '0') {
+							   char *cp3 = name;
+
+							   while (*cp3) {
+								*cp1++ = *cp3++;
+							   }
+							}
+							else if (toks[toknum =
+							    *cp2 - '1']) {
+							   char *cp3=tp[toknum];
+
+							   while (cp3 !=
+								  te[toknum]) {
+								*cp1++ = *cp3++;
+							   }
+							}
+						}
+						else if (*cp2) {
+							*cp1++ = *cp2++;
+						}
+					}
+					if (!*cp2) {
+						printf("nmap: unbalanced brackets\n");
+						return (name);
+					}
+					match = 1;
+					cp2--;
+				}
+				if (match) {
+					while (*++cp2 && *cp2 != ']') {
+					      if (*cp2 == '\\' && *(cp2 + 1)) {
+							cp2++;
+					      }
+					}
+					if (!*cp2) {
+						printf("nmap: unbalanced brackets\n");
+						return (name);
+					}
+					break;
+				}
+				switch (*++cp2) {
+					case ',':
+						goto LOOP;
+					case ']':
+						break;
+					default:
+						cp2--;
+						goto LOOP;
+				}
+				break;
+			case '$':
+				if (isdigit(*(cp2 + 1))) {
+					if (*++cp2 == '0') {
+						char *cp3 = name;
+
+						while (*cp3) {
+							*cp1++ = *cp3++;
+						}
+					}
+					else if (toks[toknum = *cp2 - '1']) {
+						char *cp3 = tp[toknum];
+
+						while (cp3 != te[toknum]) {
+							*cp1++ = *cp3++;
+						}
+					}
+					break;
+				}
+				/* intentional drop through */
+			default:
+				*cp1++ = *cp2;
+				break;
+		}
+		cp2++;
+	}
+	*cp1 = '\0';
+	if (!*new) {
+		return (name);
+	}
+	return (new);
+}
+
+void
+setpassive(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	passivemode = !passivemode;
+	printf("Passive mode %s.\n", onoff(passivemode));
+	code = passivemode;
+}
+
+void
+setsunique(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	sunique = !sunique;
+	printf("Store unique %s.\n", onoff(sunique));
+	code = sunique;
+}
+
+void
+setrunique(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	runique = !runique;
+	printf("Receive unique %s.\n", onoff(runique));
+	code = runique;
+}
+
+/* change directory to perent directory */
+void
+cdup(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (command("CDUP") == ERROR && code == 500) {
+		if (verbose)
+			printf("CDUP command not recognized, trying XCUP\n");
+		(void) command("XCUP");
+	}
+}
+
+/* restart transfer at specific point */
+void
+restart(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc != 2)
+		printf("restart: offset not specified\n");
+	else {
+		restart_point = atol(argv[1]);
+		printf("restarting at %qd. %s\n", restart_point,
+		    "execute get, put or append to initiate transfer");
+	}
+}
+
+/* show remote system type */
+void
+syst(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	(void) command("SYST");
+}
+
+void
+macdef(argc, argv)
+	int argc;
+	char *argv[];
+{
+	char *tmp;
+	int c;
+
+	if (macnum == 16) {
+		printf("Limit of 16 macros have already been defined\n");
+		code = -1;
+		return;
+	}
+	if (argc < 2 && !another(&argc, &argv, "macro name")) {
+		printf("Usage: %s macro_name\n",argv[0]);
+		code = -1;
+		return;
+	}
+	if (interactive) {
+		printf("Enter macro line by line, terminating it with a null line\n");
+	}
+	(void) strncpy(macros[macnum].mac_name, argv[1], 8);
+	if (macnum == 0) {
+		macros[macnum].mac_start = macbuf;
+	}
+	else {
+		macros[macnum].mac_start = macros[macnum - 1].mac_end + 1;
+	}
+	tmp = macros[macnum].mac_start;
+	while (tmp != macbuf+4096) {
+		if ((c = getchar()) == EOF) {
+			printf("macdef:end of file encountered\n");
+			code = -1;
+			return;
+		}
+		if ((*tmp = c) == '\n') {
+			if (tmp == macros[macnum].mac_start) {
+				macros[macnum++].mac_end = tmp;
+				code = 0;
+				return;
+			}
+			if (*(tmp-1) == '\0') {
+				macros[macnum++].mac_end = tmp - 1;
+				code = 0;
+				return;
+			}
+			*tmp = '\0';
+		}
+		tmp++;
+	}
+	while (1) {
+		while ((c = getchar()) != '\n' && c != EOF)
+			/* LOOP */;
+		if (c == EOF || getchar() == '\n') {
+			printf("Macro not defined - 4k buffer exceeded\n");
+			code = -1;
+			return;
+		}
+	}
+}
+
+/*
+ * get size of file on remote machine
+ */
+void
+sizecmd(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (argc < 2 && !another(&argc, &argv, "filename")) {
+		printf("usage: %s filename\n", argv[0]);
+		code = -1;
+		return;
+	}
+	(void) command("SIZE %s", argv[1]);
+}
+
+/*
+ * get last modification time of file on remote machine
+ */
+void
+modtime(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int overbose;
+
+	if (argc < 2 && !another(&argc, &argv, "filename")) {
+		printf("usage: %s filename\n", argv[0]);
+		code = -1;
+		return;
+	}
+	overbose = verbose;
+	if (debug == 0)
+		verbose = -1;
+	if (command("MDTM %s", argv[1]) == COMPLETE) {
+		int yy, mo, day, hour, min, sec;
+		sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo,
+			&day, &hour, &min, &sec);
+		/* might want to print this in local time */
+		printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
+			mo, day, yy, hour, min, sec);
+	} else
+		printf("%s\n", reply_string);
+	verbose = overbose;
+}
+
+/*
+ * show status on reomte machine
+ */
+void
+rmtstatus(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	(void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
+}
+
+/*
+ * get file if modtime is more recent than current file
+ */
+void
+newer(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	if (getit(argc, argv, -1, "w"))
+		printf("Local file \"%s\" is newer than remote file \"%s\"\n",
+			argv[2], argv[1]);
+}
diff --git a/ftp.tproj/cmdtab.c b/ftp.tproj/cmdtab.c
new file mode 100644
index 0000000..177dd59
--- /dev/null
+++ b/ftp.tproj/cmdtab.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include "ftp_var.h"
+
+/*
+ * User FTP -- Command Tables.
+ */
+
+char	accounthelp[] =	"send account command to remote server";
+char	appendhelp[] =	"append to a file";
+char	asciihelp[] =	"set ascii transfer type";
+char	beephelp[] =	"beep when command completed";
+char	binaryhelp[] =	"set binary transfer type";
+char	casehelp[] =	"toggle mget upper/lower case id mapping";
+char	cdhelp[] =	"change remote working directory";
+char	cduphelp[] = 	"change remote working directory to parent directory";
+char	chmodhelp[] =	"change file permissions of remote file";
+char	connecthelp[] =	"connect to remote tftp";
+char	crhelp[] =	"toggle carriage return stripping on ascii gets";
+char	deletehelp[] =	"delete remote file";
+char	debughelp[] =	"toggle/set debugging mode";
+char	dirhelp[] =	"list contents of remote directory";
+char	disconhelp[] =	"terminate ftp session";
+char	domachelp[] = 	"execute macro";
+char	formhelp[] =	"set file transfer format";
+char	globhelp[] =	"toggle metacharacter expansion of local file names";
+char	hashhelp[] =	"toggle printing `#' for each buffer transferred";
+char	helphelp[] =	"print local help information";
+char	idlehelp[] =	"get (set) idle timer on remote side";
+char	lcdhelp[] =	"change local working directory";
+char	lshelp[] =	"list contents of remote directory";
+char	macdefhelp[] =  "define a macro";
+char	mdeletehelp[] =	"delete multiple files";
+char	mdirhelp[] =	"list contents of multiple remote directories";
+char	mgethelp[] =	"get multiple files";
+char	mkdirhelp[] =	"make directory on the remote machine";
+char	mlshelp[] =	"list contents of multiple remote directories";
+char	modtimehelp[] = "show last modification time of remote file";
+char	modehelp[] =	"set file transfer mode";
+char	mputhelp[] =	"send multiple files";
+char	newerhelp[] =	"get file if remote file is newer than local file ";
+char	nlisthelp[] =	"nlist contents of remote directory";
+char	nmaphelp[] =	"set templates for default file name mapping";
+char	ntranshelp[] =	"set translation table for default file name mapping";
+char	porthelp[] =	"toggle use of PORT cmd for each data connection";
+char	prompthelp[] =	"force interactive prompting on multiple commands";
+char	proxyhelp[] =	"issue command on alternate connection";
+char	pwdhelp[] =	"print working directory on remote machine";
+char	quithelp[] =	"terminate ftp session and exit";
+char	quotehelp[] =	"send arbitrary ftp command";
+char	receivehelp[] =	"receive file";
+char	regethelp[] =	"get file restarting at end of local file";
+char	remotehelp[] =	"get help from remote server";
+char	renamehelp[] =	"rename file";
+char	restarthelp[]=	"restart file transfer at bytecount";
+char	rmdirhelp[] =	"remove directory on the remote machine";
+char	rmtstatushelp[]="show status of remote machine";
+char	runiquehelp[] = "toggle store unique for local files";
+char	resethelp[] =	"clear queued command replies";
+char	sendhelp[] =	"send one file";
+char	passivehelp[] =	"enter passive transfer mode";
+char	sitehelp[] =	"send site specific command to remote server\n\t\tTry \"rhelp site\" or \"site help\" for more information";
+char	shellhelp[] =	"escape to the shell";
+char	sizecmdhelp[] = "show size of remote file";
+char	statushelp[] =	"show current status";
+char	structhelp[] =	"set file transfer structure";
+char	suniquehelp[] = "toggle store unique on remote machine";
+char	systemhelp[] =  "show remote system type";
+char	tenexhelp[] =	"set tenex file transfer type";
+char	tracehelp[] =	"toggle packet tracing";
+char	typehelp[] =	"set file transfer type";
+char	umaskhelp[] =	"get (set) umask on remote side";
+char	userhelp[] =	"send new user information";
+char	verbosehelp[] =	"toggle verbose mode";
+
+struct cmd cmdtab[] = {
+	{ "!",		shellhelp,	0,	0,	0,	shell },
+	{ "$",		domachelp,	1,	0,	0,	domacro },
+	{ "account",	accounthelp,	0,	1,	1,	account},
+	{ "append",	appendhelp,	1,	1,	1,	put },
+	{ "ascii",	asciihelp,	0,	1,	1,	setascii },
+	{ "bell",	beephelp,	0,	0,	0,	setbell },
+	{ "binary",	binaryhelp,	0,	1,	1,	setbinary },
+	{ "bye",	quithelp,	0,	0,	0,	quit },
+	{ "case",	casehelp,	0,	0,	1,	setcase },
+	{ "cd",		cdhelp,		0,	1,	1,	cd },
+	{ "cdup",	cduphelp,	0,	1,	1,	cdup },
+	{ "chmod",	chmodhelp,	0,	1,	1,	do_chmod },
+	{ "close",	disconhelp,	0,	1,	1,	disconnect },
+	{ "cr",		crhelp,		0,	0,	0,	setcr },
+	{ "delete",	deletehelp,	0,	1,	1,	delete },
+	{ "debug",	debughelp,	0,	0,	0,	setdebug },
+	{ "dir",	dirhelp,	1,	1,	1,	ls },
+	{ "disconnect",	disconhelp,	0,	1,	1,	disconnect },
+	{ "form",	formhelp,	0,	1,	1,	setform },
+	{ "get",	receivehelp,	1,	1,	1,	get },
+	{ "glob",	globhelp,	0,	0,	0,	setglob },
+	{ "hash",	hashhelp,	0,	0,	0,	sethash },
+	{ "help",	helphelp,	0,	0,	1,	help },
+	{ "idle",	idlehelp,	0,	1,	1,	idle },
+	{ "image",	binaryhelp,	0,	1,	1,	setbinary },
+	{ "lcd",	lcdhelp,	0,	0,	0,	lcd },
+	{ "ls",		lshelp,		1,	1,	1,	ls },
+	{ "macdef",	macdefhelp,	0,	0,	0,	macdef },
+	{ "mdelete",	mdeletehelp,	1,	1,	1,	mdelete },
+	{ "mdir",	mdirhelp,	1,	1,	1,	mls },
+	{ "mget",	mgethelp,	1,	1,	1,	mget },
+	{ "mkdir",	mkdirhelp,	0,	1,	1,	makedir },
+	{ "mls",	mlshelp,	1,	1,	1,	mls },
+	{ "mode",	modehelp,	0,	1,	1,	setftmode },
+	{ "modtime",	modtimehelp,	0,	1,	1,	modtime },
+	{ "mput",	mputhelp,	1,	1,	1,	mput },
+	{ "newer",	newerhelp,	1,	1,	1,	newer },
+	{ "nmap",	nmaphelp,	0,	0,	1,	setnmap },
+	{ "nlist",	nlisthelp,	1,	1,	1,	ls },
+	{ "ntrans",	ntranshelp,	0,	0,	1,	setntrans },
+	{ "open",	connecthelp,	0,	0,	1,	setpeer },
+	{ "passive",	passivehelp,	0,	0,	0,	setpassive },
+	{ "prompt",	prompthelp,	0,	0,	0,	setprompt },
+	{ "proxy",	proxyhelp,	0,	0,	1,	doproxy },
+	{ "sendport",	porthelp,	0,	0,	0,	setport },
+	{ "put",	sendhelp,	1,	1,	1,	put },
+	{ "pwd",	pwdhelp,	0,	1,	1,	pwd },
+	{ "quit",	quithelp,	0,	0,	0,	quit },
+	{ "quote",	quotehelp,	1,	1,	1,	quote },
+	{ "recv",	receivehelp,	1,	1,	1,	get },
+	{ "reget",	regethelp,	1,	1,	1,	reget },
+	{ "rstatus",	rmtstatushelp,	0,	1,	1,	rmtstatus },
+	{ "rhelp",	remotehelp,	0,	1,	1,	rmthelp },
+	{ "rename",	renamehelp,	0,	1,	1,	renamefile },
+	{ "reset",	resethelp,	0,	1,	1,	reset },
+	{ "restart",	restarthelp,	1,	1,	1,	restart },
+	{ "rmdir",	rmdirhelp,	0,	1,	1,	removedir },
+	{ "runique",	runiquehelp,	0,	0,	1,	setrunique },
+	{ "send",	sendhelp,	1,	1,	1,	put },
+	{ "site",	sitehelp,	0,	1,	1,	site },
+	{ "size",	sizecmdhelp,	1,	1,	1,	sizecmd },
+	{ "status",	statushelp,	0,	0,	1,	status },
+	{ "struct",	structhelp,	0,	1,	1,	setstruct },
+	{ "system",	systemhelp,	0,	1,	1,	syst },
+	{ "sunique",	suniquehelp,	0,	0,	1,	setsunique },
+	{ "tenex",	tenexhelp,	0,	1,	1,	settenex },
+	{ "trace",	tracehelp,	0,	0,	0,	settrace },
+	{ "type",	typehelp,	0,	1,	1,	settype },
+	{ "user",	userhelp,	0,	1,	1,	user },
+	{ "umask",	umaskhelp,	0,	1,	1,	do_umask },
+	{ "verbose",	verbosehelp,	0,	0,	0,	setverbose },
+	{ "?",		helphelp,	0,	0,	1,	help },
+	{ 0 },
+};
+
+int	NCMDS = (sizeof (cmdtab) / sizeof (cmdtab[0])) - 1;
diff --git a/ftp.tproj/domacro.c b/ftp.tproj/domacro.c
new file mode 100644
index 0000000..19f0539
--- /dev/null
+++ b/ftp.tproj/domacro.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <ctype.h>
+#include <signal.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include "ftp_var.h"
+
+void
+domacro(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int i, j, count = 2, loopflg = 0;
+	char *cp1, *cp2, line2[200];
+	struct cmd *c;
+
+	if (argc < 2 && !another(&argc, &argv, "macro name")) {
+		printf("Usage: %s macro_name.\n", argv[0]);
+		code = -1;
+		return;
+	}
+	for (i = 0; i < macnum; ++i) {
+		if (!strncmp(argv[1], macros[i].mac_name, 9)) {
+			break;
+		}
+	}
+	if (i == macnum) {
+		printf("'%s' macro not found.\n", argv[1]);
+		code = -1;
+		return;
+	}
+	(void) strcpy(line2, line);
+TOP:
+	cp1 = macros[i].mac_start;
+	while (cp1 != macros[i].mac_end) {
+		while (isspace(*cp1)) {
+			cp1++;
+		}
+		cp2 = line;
+		while (*cp1 != '\0') {
+		      switch(*cp1) {
+		   	    case '\\':
+				 *cp2++ = *++cp1;
+				 break;
+			    case '$':
+				 if (isdigit(*(cp1+1))) {
+				    j = 0;
+				    while (isdigit(*++cp1)) {
+					  j = 10*j +  *cp1 - '0';
+				    }
+				    cp1--;
+				    if (argc - 2 >= j) {
+					(void) strcpy(cp2, argv[j+1]);
+					cp2 += strlen(argv[j+1]);
+				    }
+				    break;
+				 }
+				 if (*(cp1+1) == 'i') {
+					loopflg = 1;
+					cp1++;
+					if (count < argc) {
+					   (void) strcpy(cp2, argv[count]);
+					   cp2 += strlen(argv[count]);
+					}
+					break;
+				}
+				/* intentional drop through */
+			    default:
+				*cp2++ = *cp1;
+				break;
+		      }
+		      if (*cp1 != '\0') {
+			 cp1++;
+		      }
+		}
+		*cp2 = '\0';
+		makeargv();
+		c = getcmd(margv[0]);
+		if (c == (struct cmd *)-1) {
+			printf("?Ambiguous command\n");
+			code = -1;
+		}
+		else if (c == 0) {
+			printf("?Invalid command\n");
+			code = -1;
+		}
+		else if (c->c_conn && !connected) {
+			printf("Not connected.\n");
+			code = -1;
+		}
+		else {
+			if (verbose) {
+				printf("%s\n",line);
+			}
+			(*c->c_handler)(margc, margv);
+			if (bell && c->c_bell) {
+				(void) putchar('\007');
+			}
+			(void) strcpy(line, line2);
+			makeargv();
+			argc = margc;
+			argv = margv;
+		}
+		if (cp1 != macros[i].mac_end) {
+			cp1++;
+		}
+	}
+	if (loopflg && ++count < argc) {
+		goto TOP;
+	}
+}
diff --git a/ftp.tproj/extern.h b/ftp.tproj/extern.h
new file mode 100644
index 0000000..e23f324
--- /dev/null
+++ b/ftp.tproj/extern.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1994 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)extern.h	8.3 (Berkeley) 10/9/94
+ */
+
+struct timeval;
+struct fd_set;
+
+void    abort_remote __P((FILE *));
+void    abortpt __P(());
+void    abortrecv __P(());
+void    abortsend __P(());
+void	account __P((int, char **));
+int	another __P((int *, char ***, char *));
+void	blkfree __P((char **));
+void	cd __P((int, char **));
+void	cdup __P((int, char **));
+void	changetype __P((int, int));
+void	cmdabort __P(());
+void	cmdscanner __P((int));
+int	command __P((const char *, ...));
+int	confirm __P((char *, char *));
+FILE   *dataconn __P((char *));
+void	delete __P((int, char **));
+void	disconnect __P((int, char **));
+void	do_chmod __P((int, char **));
+void	do_umask __P((int, char **));
+void	domacro __P((int, char **));
+char   *domap __P((char *));
+void	doproxy __P((int, char **));
+char   *dotrans __P((char *));
+int     empty __P((struct fd_set *, int));
+void	fatal __P((char *));
+void	get __P((int, char **));
+struct cmd *getcmd __P((char *));
+int	getit __P((int, char **, int, char *));
+int	getreply __P((int));
+int	globulize __P((char **));
+char   *gunique __P((char *));
+void	help __P((int, char **));
+char   *hookup __P((char *, int));
+void	idle __P((int, char **));
+int     initconn __P((void));
+void	intr __P(());
+void	lcd __P((int, char **));
+int	login __P((char *));
+void	lostpeer __P(());
+void	ls __P((int, char **));
+void	mabort __P((int));
+void	macdef __P((int, char **));
+void	makeargv __P((void));
+void	makedir __P((int, char **));
+void	mdelete __P((int, char **));
+void	mget __P((int, char **));
+void	mls __P((int, char **));
+void	modtime __P((int, char **));
+void	mput __P((int, char **));
+char   *onoff __P((int));
+void	newer __P((int, char **));
+void	proxabort __P(());
+void    proxtrans __P((char *, char *, char *));
+void    psabort __P(());
+void    pswitch __P((int));
+void    ptransfer __P((char *, long, struct timeval *, struct timeval *));
+void	put __P((int, char **));
+void	pwd __P((int, char **));
+void	quit __P((int, char **));
+void	quote __P((int, char **));
+void	quote1 __P((char *, int, char **));
+void    recvrequest __P((char *, char *, char *, char *, int));
+void	reget __P((int, char **));
+char   *remglob __P((char **, int));
+void	removedir __P((int, char **));
+void	renamefile __P((int, char **));
+void    reset __P((int, char **));
+void	restart __P((int, char **));
+void	rmthelp __P((int, char **));
+void	rmtstatus __P((int, char **));
+int	ruserpass __P((char *, char **, char **, char **));
+void    sendrequest __P((char *, char *, char *, int));
+void	setascii __P((int, char **));
+void	setbell __P((int, char **));
+void	setbinary __P((int, char **));
+void	setcase __P((int, char **));
+void	setcr __P((int, char **));
+void	setdebug __P((int, char **));
+void	setform __P((int, char **));
+void	setftmode __P((int, char **));
+void	setglob __P((int, char **));
+void	sethash __P((int, char **));
+void	setnmap __P((int, char **));
+void	setntrans __P((int, char **));
+void	setpassive __P((int, char **));
+void	setpeer __P((int, char **));
+void	setport __P((int, char **));
+void	setprompt __P((int, char **));
+void	setrunique __P((int, char **));
+void	setstruct __P((int, char **));
+void	setsunique __P((int, char **));
+void	settenex __P((int, char **));
+void	settrace __P((int, char **));
+void	settype __P((int, char **));
+void	setverbose __P((int, char **));
+void	shell __P((int, char **));
+void	site __P((int, char **));
+void	sizecmd __P((int, char **));
+char   *slurpstring __P((void));
+void	status __P((int, char **));
+void	syst __P((int, char **));
+void    tvsub __P((struct timeval *, struct timeval *, struct timeval *));
+void	user __P((int, char **));
+
+extern jmp_buf	abortprox;
+extern int	abrtflag;
+extern struct	cmd cmdtab[];
+extern FILE	*cout;
+extern int	data;
+extern char    *home;
+extern jmp_buf	jabort;
+extern int	proxy;
+extern char	reply_string[];
+extern off_t	restart_point;
+extern int	NCMDS;
diff --git a/ftp.tproj/ftp.1 b/ftp.tproj/ftp.1
new file mode 100644
index 0000000..79dcbae
--- /dev/null
+++ b/ftp.tproj/ftp.1
@@ -0,0 +1,1157 @@
+.\" Copyright (c) 1985, 1989, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)ftp.1	8.3 (Berkeley) 10/9/94
+.\"
+.Dd October 9, 1994
+.Dt FTP 1
+.Os BSD 4.2
+.Sh NAME
+.Nm ftp
+.Nd
+.Tn ARPANET
+file transfer program
+.Sh SYNOPSIS
+.Nm ftp
+.Op Fl v
+.Op Fl d
+.Op Fl i
+.Op Fl n
+.Op Fl g
+.Op Ar host
+.Sh DESCRIPTION
+.Nm Ftp
+is the user interface to the
+.Tn ARPANET
+standard File Transfer Protocol.
+The program allows a user to transfer files to and from a
+remote network site.
+.Pp
+Options may be specified at the command line, or to the
+command interpreter.
+.Bl -tag -width flag
+.It Fl v
+Verbose option forces
+.Nm ftp
+to show all responses from the remote server, as well
+as report on data transfer statistics.
+.It Fl n
+Restrains
+.Nm ftp
+from attempting \*(Lqauto-login\*(Rq upon initial connection.
+If auto-login is enabled,
+.Nm ftp
+will check the
+.Pa .netrc
+(see below) file in the user's home directory for an entry describing
+an account on the remote machine.
+If no entry exists,
+.Nm ftp
+will prompt for the remote machine login name (default is the user
+identity on the local machine), and, if necessary, prompt for a password
+and an account with which to login.
+.It Fl i
+Turns off interactive prompting during
+multiple file transfers.
+.It Fl d
+Enables debugging.
+.It Fl g
+Disables file name globbing.
+.El
+.Pp
+The client host with which
+.Nm ftp
+is to communicate may be specified on the command line.
+If this is done,
+.Nm ftp
+will immediately attempt to establish a connection to an
+.Tn FTP
+server on that host; otherwise,
+.Nm ftp
+will enter its command interpreter and await instructions
+from the user.
+When
+.Nm ftp
+is awaiting commands from the user the prompt
+.Ql ftp>
+is provided to the user.
+The following commands are recognized
+by
+.Nm ftp  :
+.Bl -tag -width Fl
+.It Ic \&! Op Ar command Op Ar args
+Invoke an interactive shell on the local machine.
+If there are arguments, the first is taken to be a command to execute
+directly, with the rest of the arguments as its arguments.
+.It Ic \&$ Ar macro-name Op Ar args
+Execute the macro
+.Ar macro-name
+that was defined with the
+.Ic macdef
+command.
+Arguments are passed to the macro unglobbed.
+.It Ic account Op Ar passwd
+Supply a supplemental password required by a remote system for access
+to resources once a login has been successfully completed.
+If no argument is included, the user will be prompted for an account
+password in a non-echoing input mode.
+.It Ic append Ar local-file Op Ar remote-file
+Append a local file to a file on the remote machine.
+If
+.Ar remote-file
+is left unspecified, the local file name is used in naming the
+remote file after being altered by any
+.Ic ntrans
+or
+.Ic nmap
+setting.
+File transfer uses the current settings for
+.Ic type  ,
+.Ic format ,
+.Ic mode  ,
+and
+.Ic structure .
+.It Ic ascii
+Set the file transfer
+.Ic type
+to network
+.Tn ASCII .
+This is the default type.
+.It Ic bell
+Arrange that a bell be sounded after each file transfer
+command is completed.
+.It Ic binary
+Set the file transfer
+.Ic type
+to support binary image transfer.
+.It Ic bye
+Terminate the
+.Tn FTP
+session with the remote server
+and exit
+.Nm ftp  .
+An end of file will also terminate the session and exit.
+.It Ic case
+Toggle remote computer file name case mapping during
+.Ic mget
+commands.
+When
+.Ic case
+is on (default is off), remote computer file names with all letters in
+upper case are written in the local directory with the letters mapped
+to lower case.
+.It Ic \&cd Ar remote-directory
+Change the working directory on the remote machine
+to
+.Ar remote-directory  .
+.It Ic cdup
+Change the remote machine working directory to the parent of the
+current remote machine working directory.
+.It Ic chmod Ar mode file-name
+Change the permission modes of the file
+.Ar file-name
+on the remote
+sytem to
+.Ar mode  .
+.It Ic close
+Terminate the
+.Tn FTP
+session with the remote server, and
+return to the command interpreter.
+Any defined macros are erased.
+.It Ic \&cr
+Toggle carriage return stripping during
+ascii type file retrieval.
+Records are denoted by a carriage return/linefeed sequence
+during ascii type file transfer.
+When
+.Ic \&cr
+is on (the default), carriage returns are stripped from this
+sequence to conform with the
+.Ux
+single linefeed record
+delimiter.
+Records on
+.Pf non\- Ns Ux
+remote systems may contain single linefeeds;
+when an ascii type transfer is made, these linefeeds may be
+distinguished from a record delimiter only when
+.Ic \&cr
+is off.
+.It Ic delete Ar remote-file
+Delete the file
+.Ar remote-file
+on the remote machine.
+.It Ic debug Op Ar debug-value
+Toggle debugging mode.
+If an optional
+.Ar debug-value
+is specified it is used to set the debugging level.
+When debugging is on,
+.Nm ftp
+prints each command sent to the remote machine, preceded
+by the string
+.Ql \-\->
+.It Xo
+.Ic dir
+.Op Ar remote-directory
+.Op Ar local-file
+.Xc
+Print a listing of the directory contents in the
+directory,
+.Ar remote-directory  ,
+and, optionally, placing the output in
+.Ar local-file  .
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic dir
+output.
+If no directory is specified, the current working
+directory on the remote machine is used.
+If no local
+file is specified, or
+.Ar local-file
+is
+.Fl  ,
+output comes to the terminal.
+.It Ic disconnect
+A synonym for
+.Ar close  .
+.It Ic form Ar format
+Set the file transfer
+.Ic form
+to
+.Ar format  .
+The default format is \*(Lqfile\*(Rq.
+.It Ic get Ar remote-file Op Ar local-file
+Retrieve the
+.Ar remote-file
+and store it on the local machine.
+If the local
+file name is not specified, it is given the same
+name it has on the remote machine, subject to
+alteration by the current
+.Ic case  ,
+.Ic ntrans ,
+and
+.Ic nmap
+settings.
+The current settings for
+.Ic type  ,
+.Ic form ,
+.Ic mode  ,
+and
+.Ic structure
+are used while transferring the file.
+.It Ic glob
+Toggle filename expansion for
+.Ic mdelete  ,
+.Ic mget
+and
+.Ic mput  .
+If globbing is turned off with
+.Ic glob  ,
+the file name arguments
+are taken literally and not expanded.
+Globbing for
+.Ic mput
+is done as in
+.Xr csh 1 .
+For
+.Ic mdelete
+and
+.Ic mget  ,
+each remote file name is expanded
+separately on the remote machine and the lists are not merged.
+Expansion of a directory name is likely to be
+different from expansion of the name of an ordinary file:
+the exact result depends on the foreign operating system and ftp server,
+and can be previewed by doing
+.Ql mls remote-files \-
+Note:
+.Ic mget
+and
+.Ic mput
+are not meant to transfer
+entire directory subtrees of files.
+That can be done by
+transferring a
+.Xr tar 1
+archive of the subtree (in binary mode).
+.It Ic hash
+Toggle hash-sign (``#'') printing for each data block
+transferred.
+The size of a data block is 1024 bytes.
+.It Ic help Op Ar command
+Print an informative message about the meaning of
+.Ar command  .
+If no argument is given,
+.Nm ftp
+prints a list of the known commands.
+.It Ic idle Op Ar seconds
+Set the inactivity timer on the remote server to
+.Ar seconds
+seconds.
+If
+.Ar seconds
+is omitted, the current inactivity timer is printed.
+.It Ic lcd Op Ar directory
+Change the working directory on the local machine.
+If
+no
+.Ar directory
+is specified, the user's home directory is used.
+.It Xo
+.Ic \&ls
+.Op Ar remote-directory
+.Op Ar local-file
+.Xc
+Print a listing of the contents of a
+directory on the remote machine.
+The listing includes any system-dependent information that the server
+chooses to include; for example, most
+.Ux
+systems will produce
+output from the command
+.Ql ls \-l .
+(See also
+.Ic nlist . )
+If
+.Ar remote-directory
+is left unspecified, the current working directory is used.
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic \&ls
+output.
+If no local file is specified, or if
+.Ar local-file
+is
+.Sq Fl ,
+the output is sent to the terminal.
+.It Ic macdef Ar macro-name
+Define a macro.
+Subsequent lines are stored as the macro
+.Ar macro-name  ;
+a null line (consecutive newline characters
+in a file or
+carriage returns from the terminal) terminates macro input mode.
+There is a limit of 16 macros and 4096 total characters in all
+defined macros.
+Macros remain defined until a
+.Ic close
+command is executed.
+The macro processor interprets `$' and `\e' as special characters.
+A `$' followed by a number (or numbers) is replaced by the
+corresponding argument on the macro invocation command line.
+A `$' followed by an `i' signals that macro processor that the
+executing macro is to be looped.
+On the first pass `$i' is
+replaced by the first argument on the macro invocation command line,
+on the second pass it is replaced by the second argument, and so on.
+A `\e' followed by any character is replaced by that character.
+Use the `\e' to prevent special treatment of the `$'.
+.It Ic mdelete Op Ar remote-files
+Delete the
+.Ar remote-files
+on the remote machine.
+.It Ic mdir Ar remote-files local-file
+Like
+.Ic dir  ,
+except multiple remote files may be specified.
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic mdir
+output.
+.It Ic mget Ar remote-files
+Expand the
+.Ar remote-files
+on the remote machine
+and do a
+.Ic get
+for each file name thus produced.
+See
+.Ic glob
+for details on the filename expansion.
+Resulting file names will then be processed according to
+.Ic case  ,
+.Ic ntrans ,
+and
+.Ic nmap
+settings.
+Files are transferred into the local working directory,
+which can be changed with
+.Ql lcd directory ;
+new local directories can be created with
+.Ql "\&! mkdir directory" .
+.It Ic mkdir Ar directory-name
+Make a directory on the remote machine.
+.It Ic mls Ar remote-files local-file
+Like
+.Ic nlist  ,
+except multiple remote files may be specified,
+and the
+.Ar local-file
+must be specified.
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic mls
+output.
+.It Ic mode Op Ar mode-name
+Set the file transfer
+.Ic mode
+to
+.Ar mode-name  .
+The default mode is \*(Lqstream\*(Rq mode.
+.It Ic modtime Ar file-name
+Show the last modification time of the file on the remote machine.
+.It Ic mput Ar local-files
+Expand wild cards in the list of local files given as arguments
+and do a
+.Ic put
+for each file in the resulting list.
+See
+.Ic glob
+for details of filename expansion.
+Resulting file names will then be processed according to
+.Ic ntrans
+and
+.Ic nmap
+settings.
+.It Ic newer Ar file-name
+Get the file only if the modification time of the remote file is more
+recent that the file on the current system.
+If the file does not
+exist on the current system, the remote file is considered
+.Ic newer  .
+Otherwise, this command is identical to
+.Ar get  .
+.It Xo
+.Ic nlist
+.Op Ar remote-directory
+.Op Ar local-file
+.Xc
+Print a  list of the files in a
+directory on the remote machine.
+If
+.Ar remote-directory
+is left unspecified, the current working directory is used.
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic nlist
+output.
+If no local file is specified, or if
+.Ar local-file
+is
+.Fl  ,
+the output is sent to the terminal.
+.It Ic nmap Op Ar inpattern outpattern
+Set or unset the filename mapping mechanism.
+If no arguments are specified, the filename mapping mechanism is unset.
+If arguments are specified, remote filenames are mapped during
+.Ic mput
+commands and
+.Ic put
+commands issued without a specified remote target filename.
+If arguments are specified, local filenames are mapped during
+.Ic mget
+commands and
+.Ic get
+commands issued without a specified local target filename.
+This command is useful when connecting to a
+.No non\- Ns Ux
+remote computer
+with different file naming conventions or practices.
+The mapping follows the pattern set by
+.Ar inpattern
+and
+.Ar outpattern  .
+.Op Ar Inpattern
+is a template for incoming filenames (which may have already been
+processed according to the
+.Ic ntrans
+and
+.Ic case
+settings).
+Variable templating is accomplished by including the
+sequences `$1', `$2', ..., `$9' in
+.Ar inpattern  .
+Use `\\' to prevent this special treatment of the `$' character.
+All other characters are treated literally, and are used to determine the
+.Ic nmap
+.Op Ar inpattern
+variable values.
+For example, given
+.Ar inpattern
+$1.$2 and the remote file name "mydata.data", $1 would have the value
+"mydata", and $2 would have the value "data".
+The
+.Ar outpattern
+determines the resulting mapped filename.
+The sequences `$1', `$2', ...., `$9' are replaced by any value resulting
+from the
+.Ar inpattern
+template.
+The sequence `$0' is replace by the original filename.
+Additionally, the sequence
+.Ql Op Ar seq1 , Ar seq2
+is replaced by
+.Op Ar seq1
+if
+.Ar seq1
+is not a null string; otherwise it is replaced by
+.Ar seq2 .
+For example, the command
+.Pp
+.Bd -literal -offset indent -compact
+nmap $1.$2.$3 [$1,$2].[$2,file]
+.Ed
+.Pp
+would yield
+the output filename "myfile.data" for input filenames "myfile.data" and
+"myfile.data.old", "myfile.file" for the input filename "myfile", and
+"myfile.myfile" for the input filename ".myfile".
+Spaces may be included in
+.Ar outpattern  ,
+as in the example: `nmap $1 sed "s/  *$//" > $1' .
+Use the `\e' character to prevent special treatment
+of the `$','[','[', and `,' characters.
+.It Ic ntrans Op Ar inchars Op Ar outchars
+Set or unset the filename character translation mechanism.
+If no arguments are specified, the filename character
+translation mechanism is unset.
+If arguments are specified, characters in
+remote filenames are translated during
+.Ic mput
+commands and
+.Ic put
+commands issued without a specified remote target filename.
+If arguments are specified, characters in
+local filenames are translated during
+.Ic mget
+commands and
+.Ic get
+commands issued without a specified local target filename.
+This command is useful when connecting to a
+.No non\- Ns Ux
+remote computer
+with different file naming conventions or practices.
+Characters in a filename matching a character in
+.Ar inchars
+are replaced with the corresponding character in
+.Ar outchars  .
+If the character's position in
+.Ar inchars
+is longer than the length of
+.Ar outchars  ,
+the character is deleted from the file name.
+.It Ic open Ar host Op Ar port
+Establish a connection to the specified
+.Ar host
+.Tn FTP
+server.
+An optional port number may be supplied,
+in which case,
+.Nm ftp
+will attempt to contact an
+.Tn FTP
+server at that port.
+If the
+.Ic auto-login
+option is on (default),
+.Nm ftp
+will also attempt to automatically log the user in to
+the
+.Tn FTP
+server (see below).
+.It Ic passive
+Toggle passive mode.  If passive mode is turned on
+(default is off), the ftp client will
+send a
+.Dv PASV
+command for all data connections instead of the usual
+.Dv PORT
+command.  The
+.Dv PASV
+command requests that the remote server open a port for the data connection
+and return the address of that port.  The remote server listens on that
+port and the client connects to it.  When using the more traditional
+.Dv PORT
+command, the client listens on a port and sends that address to the remote
+server, who connects back to it.  Passive mode is useful when using
+.Nm ftp
+through a gateway router or host that controls the directionality of
+traffic.
+(Note that though ftp servers are required to support the
+.Dv PASV
+command by RFC 1123, some do not.)
+.It Ic prompt
+Toggle interactive prompting.
+Interactive prompting
+occurs during multiple file transfers to allow the
+user to selectively retrieve or store files.
+If prompting is turned off (default is on), any
+.Ic mget
+or
+.Ic mput
+will transfer all files, and any
+.Ic mdelete
+will delete all files.
+.It Ic proxy Ar ftp-command
+Execute an ftp command on a secondary control connection.
+This command allows simultaneous connection to two remote ftp
+servers for transferring files between the two servers.
+The first
+.Ic proxy
+command should be an
+.Ic open  ,
+to establish the secondary control connection.
+Enter the command "proxy ?" to see other ftp commands executable on the
+secondary connection.
+The following commands behave differently when prefaced by
+.Ic proxy  :
+.Ic open
+will not define new macros during the auto-login process,
+.Ic close
+will not erase existing macro definitions,
+.Ic get
+and
+.Ic mget
+transfer files from the host on the primary control connection
+to the host on the secondary control connection, and
+.Ic put  ,
+.Ic mput ,
+and
+.Ic append
+transfer files from the host on the secondary control connection
+to the host on the primary control connection.
+Third party file transfers depend upon support of the ftp protocol
+.Dv PASV
+command by the server on the secondary control connection.
+.It Ic put Ar local-file Op Ar remote-file
+Store a local file on the remote machine.
+If
+.Ar remote-file
+is left unspecified, the local file name is used
+after processing according to any
+.Ic ntrans
+or
+.Ic nmap
+settings
+in naming the remote file.
+File transfer uses the
+current settings for
+.Ic type  ,
+.Ic format ,
+.Ic mode  ,
+and
+.Ic structure  .
+.It Ic pwd
+Print the name of the current working directory on the remote
+machine.
+.It Ic quit
+A synonym for
+.Ic bye  .
+.It Ic quote Ar arg1 arg2 ...
+The arguments specified are sent, verbatim, to the remote
+.Tn FTP
+server.
+.It Ic recv Ar remote-file Op Ar local-file
+A synonym for get.
+.It Ic reget Ar remote-file Op Ar local-file
+Reget acts like get, except that if
+.Ar local-file
+exists and is
+smaller than
+.Ar remote-file  ,
+.Ar local-file
+is presumed to be
+a partially transferred copy of
+.Ar remote-file
+and the transfer
+is continued from the apparent point of failure.
+This command
+is useful when transferring very large files over networks that
+are prone to dropping connections.
+.It Ic remotehelp Op Ar command-name
+Request help from the remote
+.Tn FTP
+server.
+If a
+.Ar command-name
+is specified it is supplied to the server as well.
+.It Ic remotestatus Op Ar file-name
+With no arguments, show status of remote machine.
+If
+.Ar file-name
+is specified, show status of
+.Ar file-name
+on remote machine.
+.It Xo
+.Ic rename
+.Op Ar from
+.Op Ar to
+.Xc
+Rename the file
+.Ar from
+on the remote machine, to the file
+.Ar to  .
+.It Ic reset
+Clear reply queue.
+This command re-synchronizes command/reply sequencing with the remote
+ftp server.
+Resynchronization may be necessary following a violation of the ftp protocol
+by the remote server.
+.It Ic restart Ar marker
+Restart the immediately following
+.Ic get
+or
+.Ic put
+at the
+indicated
+.Ar marker  .
+On
+.Ux
+systems, marker is usually a byte
+offset into the file.
+.It Ic rmdir Ar directory-name
+Delete a directory on the remote machine.
+.It Ic runique
+Toggle storing of files on the local system with unique filenames.
+If a file already exists with a name equal to the target
+local filename for a
+.Ic get
+or
+.Ic mget
+command, a ".1" is appended to the name.
+If the resulting name matches another existing file,
+a ".2" is appended to the original name.
+If this process continues up to ".99", an error
+message is printed, and the transfer does not take place.
+The generated unique filename will be reported.
+Note that
+.Ic runique
+will not affect local files generated from a shell command
+(see below).
+The default value is off.
+.It Ic send Ar local-file Op Ar remote-file
+A synonym for put.
+.It Ic sendport
+Toggle the use of
+.Dv PORT
+commands.
+By default,
+.Nm ftp
+will attempt to use a
+.Dv PORT
+command when establishing
+a connection for each data transfer.
+The use of
+.Dv PORT
+commands can prevent delays
+when performing multiple file transfers.
+If the
+.Dv PORT
+command fails,
+.Nm ftp
+will use the default data port.
+When the use of
+.Dv PORT
+commands is disabled, no attempt will be made to use
+.Dv PORT
+commands for each data transfer.
+This is useful
+for certain
+.Tn FTP
+implementations which do ignore
+.Dv PORT
+commands but, incorrectly, indicate they've been accepted.
+.It Ic site Ar arg1 arg2 ...
+The arguments specified are sent, verbatim, to the remote
+.Tn FTP
+server as a
+.Dv SITE
+command.
+.It Ic size Ar file-name
+Return size of
+.Ar file-name
+on remote machine.
+.It Ic status
+Show the current status of
+.Nm ftp  .
+.It Ic struct Op Ar struct-name
+Set the file transfer
+.Ar structure
+to
+.Ar struct-name .
+By default \*(Lqstream\*(Rq structure is used.
+.It Ic sunique
+Toggle storing of files on remote machine under unique file names.
+Remote ftp server must support ftp protocol
+.Dv STOU
+command for
+successful completion.
+The remote server will report unique name.
+Default value is off.
+.It Ic system
+Show the type of operating system running on the remote machine.
+.It Ic tenex
+Set the file transfer type to that needed to
+talk to
+.Tn TENEX
+machines.
+.It Ic trace
+Toggle packet tracing.
+.It Ic type Op Ar type-name
+Set the file transfer
+.Ic type
+to
+.Ar type-name  .
+If no type is specified, the current type
+is printed.
+The default type is network
+.Tn ASCII .
+.It Ic umask Op Ar newmask
+Set the default umask on the remote server to
+.Ar newmask  .
+If
+.Ar newmask
+is omitted, the current umask is printed.
+.It Xo
+.Ic user Ar user-name
+.Op Ar password
+.Op Ar account
+.Xc
+Identify yourself to the remote
+.Tn FTP
+server.
+If the
+.Ar password
+is not specified and the server requires it,
+.Nm ftp
+will prompt the user for it (after disabling local echo).
+If an
+.Ar account
+field is not specified, and the
+.Tn FTP
+server
+requires it, the user will be prompted for it.
+If an
+.Ar account
+field is specified, an account command will
+be relayed to the remote server after the login sequence
+is completed if the remote server did not require it
+for logging in.
+Unless
+.Nm ftp
+is invoked with \*(Lqauto-login\*(Rq disabled, this
+process is done automatically on initial connection to
+the
+.Tn FTP
+server.
+.It Ic verbose
+Toggle verbose mode.
+In verbose mode, all responses from
+the
+.Tn FTP
+server are displayed to the user.
+In addition,
+if verbose is on, when a file transfer completes, statistics
+regarding the efficiency of the transfer are reported.
+By default,
+verbose is on.
+.It Ic ? Op Ar command
+A synonym for help.
+.El
+.Pp
+Command arguments which have embedded spaces may be quoted with
+quote `"' marks.
+.Sh ABORTING A FILE TRANSFER
+To abort a file transfer, use the terminal interrupt key
+(usually Ctrl-C).
+Sending transfers will be immediately halted.
+Receiving transfers will be halted by sending a ftp protocol
+.Dv ABOR
+command to the remote server, and discarding any further data received.
+The speed at which this is accomplished depends upon the remote
+server's support for
+.Dv ABOR
+processing.
+If the remote server does not support the
+.Dv ABOR
+command, an
+.Ql ftp>
+prompt will not appear until the remote server has completed
+sending the requested file.
+.Pp
+The terminal interrupt key sequence will be ignored when
+.Nm ftp
+has completed any local processing and is awaiting a reply
+from the remote server.
+A long delay in this mode may result from the ABOR processing described
+above, or from unexpected behavior by the remote server, including
+violations of the ftp protocol.
+If the delay results from unexpected remote server behavior, the local
+.Nm ftp
+program must be killed by hand.
+.Sh FILE NAMING CONVENTIONS
+Files specified as arguments to
+.Nm ftp
+commands are processed according to the following rules.
+.Bl -enum
+.It
+If the file name
+.Sq Fl
+is specified, the
+.Ar stdin
+(for reading) or
+.Ar stdout
+(for writing) is used.
+.It
+If the first character of the file name is
+.Sq \&| ,
+the
+remainder of the argument is interpreted as a shell command.
+.Nm Ftp
+then forks a shell, using
+.Xr popen 3
+with the argument supplied, and reads (writes) from the stdout
+(stdin).
+If the shell command includes spaces, the argument
+must be quoted; e.g.
+\*(Lq" ls -lt"\*(Rq.
+A particularly
+useful example of this mechanism is: \*(Lqdir more\*(Rq.
+.It
+Failing the above checks, if ``globbing'' is enabled,
+local file names are expanded
+according to the rules used in the
+.Xr csh  1  ;
+c.f. the
+.Ic glob
+command.
+If the
+.Nm ftp
+command expects a single local file (.e.g.
+.Ic put  ) ,
+only the first filename generated by the "globbing" operation is used.
+.It
+For
+.Ic mget
+commands and
+.Ic get
+commands with unspecified local file names, the local filename is
+the remote filename, which may be altered by a
+.Ic case  ,
+.Ic ntrans ,
+or
+.Ic nmap
+setting.
+The resulting filename may then be altered if
+.Ic runique
+is on.
+.It
+For
+.Ic mput
+commands and
+.Ic put
+commands with unspecified remote file names, the remote filename is
+the local filename, which may be altered by a
+.Ic ntrans
+or
+.Ic nmap
+setting.
+The resulting filename may then be altered by the remote server if
+.Ic sunique
+is on.
+.El
+.Sh FILE TRANSFER PARAMETERS
+The FTP specification specifies many parameters which may
+affect a file transfer.
+The
+.Ic type
+may be one of \*(Lqascii\*(Rq, \*(Lqimage\*(Rq (binary),
+\*(Lqebcdic\*(Rq, and \*(Lqlocal byte size\*(Rq (for
+.Tn PDP Ns -10's
+and
+.Tn PDP Ns -20's
+mostly).
+.Nm Ftp
+supports the ascii and image types of file transfer,
+plus local byte size 8 for
+.Ic tenex
+mode transfers.
+.Pp
+.Nm Ftp
+supports only the default values for the remaining
+file transfer parameters:
+.Ic mode  ,
+.Ic form ,
+and
+.Ic struct  .
+.Sh THE .netrc FILE
+The
+.Pa .netrc
+file contains login and initialization information
+used by the auto-login process.
+It resides in the user's home directory.
+The following tokens are recognized; they may be separated by spaces,
+tabs, or new-lines:
+.Bl -tag -width password
+.It Ic machine Ar name
+Identify a remote machine
+.Ar name .
+The auto-login process searches the
+.Pa .netrc
+file for a
+.Ic machine
+token that matches the remote machine specified on the
+.Nm ftp
+command line or as an
+.Ic open
+command argument.
+Once a match is made, the subsequent
+.Pa .netrc
+tokens are processed,
+stopping when the end of file is reached or another
+.Ic machine
+or a
+.Ic default
+token is encountered.
+.It Ic default
+This is the same as
+.Ic machine
+.Ar name
+except that
+.Ic default
+matches any name.
+There can be only one
+.Ic default
+token, and it must be after all
+.Ic machine
+tokens.
+This is normally used as:
+.Pp
+.Dl default login anonymous password user@site
+.Pp
+thereby giving the user
+.Ar automatic
+anonymous ftp login to
+machines not specified in
+.Pa .netrc .
+This can be overridden
+by using the
+.Fl n
+flag to disable auto-login.
+.It Ic login Ar name
+Identify a user on the remote machine.
+If this token is present, the auto-login process will initiate
+a login using the specified
+.Ar name .
+.It Ic password Ar string
+Supply a password.
+If this token is present, the auto-login process will supply the
+specified string if the remote server requires a password as part
+of the login process.
+Note that if this token is present in the
+.Pa .netrc
+file for any user other
+than
+.Ar anonymous  ,
+.Nm ftp
+will abort the auto-login process if the
+.Pa .netrc
+is readable by
+anyone besides the user.
+.It Ic account Ar string
+Supply an additional account password.
+If this token is present, the auto-login process will supply the
+specified string if the remote server requires an additional
+account password, or the auto-login process will initiate an
+.Dv ACCT
+command if it does not.
+.It Ic macdef Ar name
+Define a macro.
+This token functions like the
+.Nm ftp
+.Ic macdef
+command functions.
+A macro is defined with the specified name; its contents begin with the
+next
+.Pa .netrc
+line and continue until a null line (consecutive new-line
+characters) is encountered.
+If a macro named
+.Ic init
+is defined, it is automatically executed as the last step in the
+auto-login process.
+.El
+.Sh ENVIRONMENT
+.Nm Ftp
+utilizes the following environment variables.
+.Bl -tag -width Fl
+.It Ev HOME
+For default location of a
+.Pa .netrc
+file, if one exists.
+.It Ev SHELL
+For default shell.
+.El
+.Sh SEE ALSO
+.Xr ftpd 8
+.Sh HISTORY
+The
+.Nm ftp
+command appeared in
+.Bx 4.2 .
+.Sh BUGS
+Correct execution of many commands depends upon proper behavior
+by the remote server.
+.Pp
+An error in the treatment of carriage returns
+in the
+.Bx 4.2
+ascii-mode transfer code
+has been corrected.
+This correction may result in incorrect transfers of binary files
+to and from
+.Bx 4.2
+servers using the ascii type.
+Avoid this problem by using the binary image type.
diff --git a/ftp.tproj/ftp.c b/ftp.tproj/ftp.c
new file mode 100644
index 0000000..a2a54a9
--- /dev/null
+++ b/ftp.tproj/ftp.c
@@ -0,0 +1,1542 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/file.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+#include <arpa/ftp.h>
+#include <arpa/telnet.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "ftp_var.h"
+
+extern int h_errno;
+
+struct	sockaddr_in hisctladdr;
+struct	sockaddr_in data_addr;
+int	data = -1;
+int	abrtflag = 0;
+jmp_buf	ptabort;
+int	ptabflg;
+int	ptflag = 0;
+struct	sockaddr_in myctladdr;
+off_t	restart_point = 0;
+
+FILE	*cin, *cout;
+
+char *
+hookup(host, port)
+	char *host;
+	int port;
+{
+	struct hostent *hp = 0;
+	int s, len, tos;
+	static char hostnamebuf[80];
+
+	memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
+	hisctladdr.sin_addr.s_addr = inet_addr(host);
+	if (hisctladdr.sin_addr.s_addr != -1) {
+		hisctladdr.sin_family = AF_INET;
+		(void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));
+	} else {
+		hp = gethostbyname(host);
+		if (hp == NULL) {
+			warnx("%s: %s", host, hstrerror(h_errno));
+			code = -1;
+			return ((char *) 0);
+		}
+		hisctladdr.sin_family = hp->h_addrtype;
+		memmove((caddr_t)&hisctladdr.sin_addr,
+				hp->h_addr_list[0], hp->h_length);
+		(void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
+	}
+	hostname = hostnamebuf;
+	s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
+	if (s < 0) {
+		warn("socket");
+		code = -1;
+		return (0);
+	}
+	hisctladdr.sin_port = port;
+	while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
+		if (hp && hp->h_addr_list[1]) {
+			int oerrno = errno;
+			char *ia;
+
+			ia = inet_ntoa(hisctladdr.sin_addr);
+			errno = oerrno;
+			warn("connect to address %s", ia);
+			hp->h_addr_list++;
+			memmove((caddr_t)&hisctladdr.sin_addr,
+					hp->h_addr_list[0], hp->h_length);
+			fprintf(stdout, "Trying %s...\n",
+				inet_ntoa(hisctladdr.sin_addr));
+			(void) close(s);
+			s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
+			if (s < 0) {
+				warn("socket");
+				code = -1;
+				return (0);
+			}
+			continue;
+		}
+		warn("connect");
+		code = -1;
+		goto bad;
+	}
+	len = sizeof (myctladdr);
+	if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
+		warn("getsockname");
+		code = -1;
+		goto bad;
+	}
+#ifdef IP_TOS
+	tos = IPTOS_LOWDELAY;
+	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
+		warn("setsockopt TOS (ignored)");
+#endif
+	cin = fdopen(s, "r");
+	cout = fdopen(s, "w");
+	if (cin == NULL || cout == NULL) {
+		warnx("fdopen failed.");
+		if (cin)
+			(void) fclose(cin);
+		if (cout)
+			(void) fclose(cout);
+		code = -1;
+		goto bad;
+	}
+	if (verbose)
+		printf("Connected to %s.\n", hostname);
+	if (getreply(0) > 2) { 	/* read startup message from server */
+		if (cin)
+			(void) fclose(cin);
+		if (cout)
+			(void) fclose(cout);
+		code = -1;
+		goto bad;
+	}
+#ifdef SO_OOBINLINE
+	{
+	int on = 1;
+
+	if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on))
+		< 0 && debug) {
+			warn("setsockopt");
+		}
+	}
+#endif /* SO_OOBINLINE */
+
+	return (hostname);
+bad:
+	(void) close(s);
+	return ((char *)0);
+}
+
+int
+login(host)
+	char *host;
+{
+	char tmp[80];
+	char *user, *pass, *acct;
+	int n, aflag = 0;
+
+	user = pass = acct = 0;
+	if (ruserpass(host, &user, &pass, &acct) < 0) {
+		code = -1;
+		return (0);
+	}
+	while (user == NULL) {
+		char *myname = getlogin();
+
+		if (myname == NULL) {
+			struct passwd *pp = getpwuid(getuid());
+
+			if (pp != NULL)
+				myname = pp->pw_name;
+		}
+		if (myname)
+			printf("Name (%s:%s): ", host, myname);
+		else
+			printf("Name (%s): ", host);
+		(void) fgets(tmp, sizeof(tmp) - 1, stdin);
+		tmp[strlen(tmp) - 1] = '\0';
+		if (*tmp == '\0')
+			user = myname;
+		else
+			user = tmp;
+	}
+	n = command("USER %s", user);
+	if (n == CONTINUE) {
+		if (pass == NULL)
+			pass = getpass("Password:");
+		n = command("PASS %s", pass);
+	}
+	if (n == CONTINUE) {
+		aflag++;
+		acct = getpass("Account:");
+		n = command("ACCT %s", acct);
+	}
+	if (n != COMPLETE) {
+		warnx("Login failed.");
+		return (0);
+	}
+	if (!aflag && acct != NULL)
+		(void) command("ACCT %s", acct);
+	if (proxy)
+		return (1);
+	for (n = 0; n < macnum; ++n) {
+		if (!strcmp("init", macros[n].mac_name)) {
+			(void) strcpy(line, "$init");
+			makeargv();
+			domacro(margc, margv);
+			break;
+		}
+	}
+	return (1);
+}
+
+void
+cmdabort()
+{
+
+	printf("\n");
+	(void) fflush(stdout);
+	abrtflag++;
+	if (ptflag)
+		longjmp(ptabort,1);
+}
+
+int command(const char *fmt, ...)
+{
+	va_list ap;
+	int r;
+	sig_t oldintr;
+
+	abrtflag = 0;
+	if (debug) {
+		printf("---> ");
+		va_start(ap, fmt);
+		if (strncmp("PASS ", fmt, 5) == 0)
+			printf("PASS XXXX");
+		else 
+			vfprintf(stdout, fmt, ap);
+		va_end(ap);
+		printf("\n");
+		(void) fflush(stdout);
+	}
+	if (cout == NULL) {
+		warn("No control connection for command");
+		code = -1;
+		return (0);
+	}
+	oldintr = signal(SIGINT, cmdabort);
+	va_start(ap, fmt);
+	vfprintf(cout, fmt, ap);
+	va_end(ap);
+	fprintf(cout, "\r\n");
+	(void) fflush(cout);
+	cpend = 1;
+	r = getreply(!strcmp(fmt, "QUIT"));
+	if (abrtflag && oldintr != SIG_IGN)
+		(*oldintr)(SIGINT);
+	(void) signal(SIGINT, oldintr);
+	return (r);
+}
+
+char reply_string[BUFSIZ];		/* last line of previous reply */
+
+int
+getreply(expecteof)
+	int expecteof;
+{
+	int c, n;
+	int dig;
+	int originalcode = 0, continuation = 0;
+	sig_t oldintr;
+	int pflag = 0;
+	char *cp, *pt = pasv;
+
+	oldintr = signal(SIGINT, cmdabort);
+	for (;;) {
+		dig = n = code = 0;
+		cp = reply_string;
+		while ((c = getc(cin)) != '\n') {
+			if (c == IAC) {     /* handle telnet commands */
+				switch (c = getc(cin)) {
+				case WILL:
+				case WONT:
+					c = getc(cin);
+					fprintf(cout, "%c%c%c", IAC, DONT, c);
+					(void) fflush(cout);
+					break;
+				case DO:
+				case DONT:
+					c = getc(cin);
+					fprintf(cout, "%c%c%c", IAC, WONT, c);
+					(void) fflush(cout);
+					break;
+				default:
+					break;
+				}
+				continue;
+			}
+			dig++;
+			if (c == EOF) {
+				if (expecteof) {
+					(void) signal(SIGINT,oldintr);
+					code = 221;
+					return (0);
+				}
+				lostpeer();
+				if (verbose) {
+					printf("421 Service not available, remote server has closed connection\n");
+					(void) fflush(stdout);
+				}
+				code = 421;
+				return (4);
+			}
+			if (c != '\r' && (verbose > 0 ||
+			    (verbose > -1 && n == '5' && dig > 4))) {
+				if (proxflag &&
+				   (dig == 1 || dig == 5 && verbose == 0))
+					printf("%s:",hostname);
+				(void) putchar(c);
+			}
+			if (dig < 4 && isdigit(c))
+				code = code * 10 + (c - '0');
+			if (!pflag && code == 227)
+				pflag = 1;
+			if (dig > 4 && pflag == 1 && isdigit(c))
+				pflag = 2;
+			if (pflag == 2) {
+				if (c != '\r' && c != ')')
+					*pt++ = c;
+				else {
+					*pt = '\0';
+					pflag = 3;
+				}
+			}
+			if (dig == 4 && c == '-') {
+				if (continuation)
+					code = 0;
+				continuation++;
+			}
+			if (n == 0)
+				n = c;
+			if (cp < &reply_string[sizeof(reply_string) - 1])
+				*cp++ = c;
+		}
+		if (verbose > 0 || verbose > -1 && n == '5') {
+			(void) putchar(c);
+			(void) fflush (stdout);
+		}
+		if (continuation && code != originalcode) {
+			if (originalcode == 0)
+				originalcode = code;
+			continue;
+		}
+		*cp = '\0';
+		if (n != '1')
+			cpend = 0;
+		(void) signal(SIGINT,oldintr);
+		if (code == 421 || originalcode == 421)
+			lostpeer();
+		if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
+			(*oldintr)(SIGINT);
+		return (n - '0');
+	}
+}
+
+int
+empty(mask, sec)
+	struct fd_set *mask;
+	int sec;
+{
+	struct timeval t;
+
+	t.tv_sec = (long) sec;
+	t.tv_usec = 0;
+	return (select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t));
+}
+
+jmp_buf	sendabort;
+
+void
+abortsend()
+{
+
+	mflag = 0;
+	abrtflag = 0;
+	printf("\nsend aborted\nwaiting for remote to finish abort\n");
+	(void) fflush(stdout);
+	longjmp(sendabort, 1);
+}
+
+#define HASHBYTES 1024
+
+void
+sendrequest(cmd, local, remote, printnames)
+	char *cmd, *local, *remote;
+	int printnames;
+{
+	struct stat st;
+	struct timeval start, stop;
+	int c, d;
+	FILE *fin, *dout = 0, *popen();
+	int (*closefunc) __P((FILE *));
+	sig_t oldintr, oldintp;
+	long bytes = 0, hashbytes = HASHBYTES;
+	char *lmode, buf[BUFSIZ], *bufp;
+
+	if (verbose && printnames) {
+		if (local && *local != '-')
+			printf("local: %s ", local);
+		if (remote)
+			printf("remote: %s\n", remote);
+	}
+	if (proxy) {
+		proxtrans(cmd, local, remote);
+		return;
+	}
+	if (curtype != type)
+		changetype(type, 0);
+	closefunc = NULL;
+	oldintr = NULL;
+	oldintp = NULL;
+	lmode = "w";
+	if (setjmp(sendabort)) {
+		while (cpend) {
+			(void) getreply(0);
+		}
+		if (data >= 0) {
+			(void) close(data);
+			data = -1;
+		}
+		if (oldintr)
+			(void) signal(SIGINT,oldintr);
+		if (oldintp)
+			(void) signal(SIGPIPE,oldintp);
+		code = -1;
+		return;
+	}
+	oldintr = signal(SIGINT, abortsend);
+	if (strcmp(local, "-") == 0)
+		fin = stdin;
+	else if (*local == '|') {
+		oldintp = signal(SIGPIPE,SIG_IGN);
+		fin = popen(local + 1, "r");
+		if (fin == NULL) {
+			warn("%s", local + 1);
+			(void) signal(SIGINT, oldintr);
+			(void) signal(SIGPIPE, oldintp);
+			code = -1;
+			return;
+		}
+		closefunc = pclose;
+	} else {
+		fin = fopen(local, "r");
+		if (fin == NULL) {
+			warn("local: %s", local);
+			(void) signal(SIGINT, oldintr);
+			code = -1;
+			return;
+		}
+		closefunc = fclose;
+		if (fstat(fileno(fin), &st) < 0 ||
+		    (st.st_mode&S_IFMT) != S_IFREG) {
+			fprintf(stdout, "%s: not a plain file.\n", local);
+			(void) signal(SIGINT, oldintr);
+			fclose(fin);
+			code = -1;
+			return;
+		}
+	}
+	if (initconn()) {
+		(void) signal(SIGINT, oldintr);
+		if (oldintp)
+			(void) signal(SIGPIPE, oldintp);
+		code = -1;
+		if (closefunc != NULL)
+			(*closefunc)(fin);
+		return;
+	}
+	if (setjmp(sendabort))
+		goto abort;
+
+	if (restart_point &&
+	    (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
+		int rc;
+
+		switch (curtype) {
+		case TYPE_A:
+			rc = fseek(fin, (long) restart_point, SEEK_SET);
+			break;
+		case TYPE_I:
+		case TYPE_L:
+			rc = lseek(fileno(fin), restart_point, SEEK_SET);
+			break;
+		}
+		if (rc < 0) {
+			warn("local: %s", local);
+			restart_point = 0;
+			if (closefunc != NULL)
+				(*closefunc)(fin);
+			return;
+		}
+		if (command("REST %ld", (long) restart_point)
+			!= CONTINUE) {
+			restart_point = 0;
+			if (closefunc != NULL)
+				(*closefunc)(fin);
+			return;
+		}
+		restart_point = 0;
+		lmode = "r+w";
+	}
+	if (remote) {
+		if (command("%s %s", cmd, remote) != PRELIM) {
+			(void) signal(SIGINT, oldintr);
+			if (oldintp)
+				(void) signal(SIGPIPE, oldintp);
+			if (closefunc != NULL)
+				(*closefunc)(fin);
+			return;
+		}
+	} else
+		if (command("%s", cmd) != PRELIM) {
+			(void) signal(SIGINT, oldintr);
+			if (oldintp)
+				(void) signal(SIGPIPE, oldintp);
+			if (closefunc != NULL)
+				(*closefunc)(fin);
+			return;
+		}
+	dout = dataconn(lmode);
+	if (dout == NULL)
+		goto abort;
+	(void) gettimeofday(&start, (struct timezone *)0);
+	oldintp = signal(SIGPIPE, SIG_IGN);
+	switch (curtype) {
+
+	case TYPE_I:
+	case TYPE_L:
+		errno = d = 0;
+		while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
+			bytes += c;
+			for (bufp = buf; c > 0; c -= d, bufp += d)
+				if ((d = write(fileno(dout), bufp, c)) <= 0)
+					break;
+			if (hash) {
+				while (bytes >= hashbytes) {
+					(void) putchar('#');
+					hashbytes += HASHBYTES;
+				}
+				(void) fflush(stdout);
+			}
+		}
+		if (hash && bytes > 0) {
+			if (bytes < HASHBYTES)
+				(void) putchar('#');
+			(void) putchar('\n');
+			(void) fflush(stdout);
+		}
+		if (c < 0)
+			warn("local: %s", local);
+		if (d < 0) {
+			if (errno != EPIPE) 
+				warn("netout");
+			bytes = -1;
+		}
+		break;
+
+	case TYPE_A:
+		while ((c = getc(fin)) != EOF) {
+			if (c == '\n') {
+				while (hash && (bytes >= hashbytes)) {
+					(void) putchar('#');
+					(void) fflush(stdout);
+					hashbytes += HASHBYTES;
+				}
+				if (ferror(dout))
+					break;
+				(void) putc('\r', dout);
+				bytes++;
+			}
+			(void) putc(c, dout);
+			bytes++;
+	/*		if (c == '\r') {			  	*/
+	/*		(void)	putc('\0', dout);  // this violates rfc */
+	/*			bytes++;				*/
+	/*		}                          			*/	
+		}
+		if (hash) {
+			if (bytes < hashbytes)
+				(void) putchar('#');
+			(void) putchar('\n');
+			(void) fflush(stdout);
+		}
+		if (ferror(fin))
+			warn("local: %s", local);
+		if (ferror(dout)) {
+			if (errno != EPIPE)
+				warn("netout");
+			bytes = -1;
+		}
+		break;
+	}
+	if (closefunc != NULL)
+		(*closefunc)(fin);
+	(void) fclose(dout);
+	(void) gettimeofday(&stop, (struct timezone *)0);
+	(void) getreply(0);
+	(void) signal(SIGINT, oldintr);
+	if (oldintp)
+		(void) signal(SIGPIPE, oldintp);
+	if (bytes > 0)
+		ptransfer("sent", bytes, &start, &stop);
+	return;
+abort:
+	(void) signal(SIGINT, oldintr);
+	if (oldintp)
+		(void) signal(SIGPIPE, oldintp);
+	if (!cpend) {
+		code = -1;
+		return;
+	}
+	if (data >= 0) {
+		(void) close(data);
+		data = -1;
+	}
+	if (dout)
+		(void) fclose(dout);
+	(void) getreply(0);
+	code = -1;
+	if (closefunc != NULL && fin != NULL)
+		(*closefunc)(fin);
+	(void) gettimeofday(&stop, (struct timezone *)0);
+	if (bytes > 0)
+		ptransfer("sent", bytes, &start, &stop);
+}
+
+jmp_buf	recvabort;
+
+void
+abortrecv()
+{
+
+	mflag = 0;
+	abrtflag = 0;
+	printf("\nreceive aborted\nwaiting for remote to finish abort\n");
+	(void) fflush(stdout);
+	longjmp(recvabort, 1);
+}
+
+void
+recvrequest(cmd, local, remote, lmode, printnames)
+	char *cmd, *local, *remote, *lmode;
+	int printnames;
+{
+	FILE *fout, *din = 0;
+	int (*closefunc) __P((FILE *));
+	sig_t oldintr, oldintp;
+	int c, d, is_retr, tcrflag, bare_lfs = 0;
+	static int bufsize;
+	static char *buf;
+	long bytes = 0, hashbytes = HASHBYTES;
+	struct timeval start, stop;
+	struct stat st;
+
+	is_retr = strcmp(cmd, "RETR") == 0;
+	if (is_retr && verbose && printnames) {
+		if (local && *local != '-')
+			printf("local: %s ", local);
+		if (remote)
+			printf("remote: %s\n", remote);
+	}
+	if (proxy && is_retr) {
+		proxtrans(cmd, local, remote);
+		return;
+	}
+	closefunc = NULL;
+	oldintr = NULL;
+	oldintp = NULL;
+	tcrflag = !crflag && is_retr;
+	if (setjmp(recvabort)) {
+		while (cpend) {
+			(void) getreply(0);
+		}
+		if (data >= 0) {
+			(void) close(data);
+			data = -1;
+		}
+		if (oldintr)
+			(void) signal(SIGINT, oldintr);
+		code = -1;
+		return;
+	}
+	oldintr = signal(SIGINT, abortrecv);
+	if (strcmp(local, "-") && *local != '|') {
+		if (access(local, 2) < 0) {
+			char *dir = strrchr(local, '/');
+
+			if (errno != ENOENT && errno != EACCES) {
+				warn("local: %s", local);
+				(void) signal(SIGINT, oldintr);
+				code = -1;
+				return;
+			}
+			if (dir != NULL)
+				*dir = 0;
+			d = access(dir ? local : ".", 2);
+			if (dir != NULL)
+				*dir = '/';
+			if (d < 0) {
+				warn("local: %s", local);
+				(void) signal(SIGINT, oldintr);
+				code = -1;
+				return;
+			}
+			if (!runique && errno == EACCES &&
+			    chmod(local, 0600) < 0) {
+				warn("local: %s", local);
+				(void) signal(SIGINT, oldintr);
+				(void) signal(SIGINT, oldintr);
+				code = -1;
+				return;
+			}
+			if (runique && errno == EACCES &&
+			   (local = gunique(local)) == NULL) {
+				(void) signal(SIGINT, oldintr);
+				code = -1;
+				return;
+			}
+		}
+		else if (runique && (local = gunique(local)) == NULL) {
+			(void) signal(SIGINT, oldintr);
+			code = -1;
+			return;
+		}
+	}
+	if (!is_retr) {
+		if (curtype != TYPE_A)
+			changetype(TYPE_A, 0);
+	} else if (curtype != type)
+		changetype(type, 0);
+	if (initconn()) {
+		(void) signal(SIGINT, oldintr);
+		code = -1;
+		return;
+	}
+	if (setjmp(recvabort))
+		goto abort;
+	if (is_retr && restart_point &&
+	    command("REST %ld", (long) restart_point) != CONTINUE)
+		return;
+	if (remote) {
+		if (command("%s %s", cmd, remote) != PRELIM) {
+			(void) signal(SIGINT, oldintr);
+			return;
+		}
+	} else {
+		if (command("%s", cmd) != PRELIM) {
+			(void) signal(SIGINT, oldintr);
+			return;
+		}
+	}
+	din = dataconn("r");
+	if (din == NULL)
+		goto abort;
+	if (strcmp(local, "-") == 0)
+		fout = stdout;
+	else if (*local == '|') {
+		oldintp = signal(SIGPIPE, SIG_IGN);
+		fout = popen(local + 1, "w");
+		if (fout == NULL) {
+			warn("%s", local+1);
+			goto abort;
+		}
+		closefunc = pclose;
+	} else {
+		fout = fopen(local, lmode);
+		if (fout == NULL) {
+			warn("local: %s", local);
+			goto abort;
+		}
+		closefunc = fclose;
+	}
+	if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)
+		st.st_blksize = BUFSIZ;
+	if (st.st_blksize > bufsize) {
+		if (buf)
+			(void) free(buf);
+		buf = malloc((unsigned)st.st_blksize);
+		if (buf == NULL) {
+			warn("malloc");
+			bufsize = 0;
+			goto abort;
+		}
+		bufsize = st.st_blksize;
+	}
+	(void) gettimeofday(&start, (struct timezone *)0);
+	switch (curtype) {
+
+	case TYPE_I:
+	case TYPE_L:
+		if (restart_point &&
+		    lseek(fileno(fout), restart_point, SEEK_SET) < 0) {
+			warn("local: %s", local);
+			if (closefunc != NULL)
+				(*closefunc)(fout);
+			return;
+		}
+		errno = d = 0;
+		while ((c = read(fileno(din), buf, bufsize)) > 0) {
+			if ((d = write(fileno(fout), buf, c)) != c)
+				break;
+			bytes += c;
+			if (hash) {
+				while (bytes >= hashbytes) {
+					(void) putchar('#');
+					hashbytes += HASHBYTES;
+				}
+				(void) fflush(stdout);
+			}
+		}
+		if (hash && bytes > 0) {
+			if (bytes < HASHBYTES)
+				(void) putchar('#');
+			(void) putchar('\n');
+			(void) fflush(stdout);
+		}
+		if (c < 0) {
+			if (errno != EPIPE)
+				warn("netin");
+			bytes = -1;
+		}
+		if (d < c) {
+			if (d < 0)
+				warn("local: %s", local);
+			else
+				warnx("%s: short write", local);
+		}
+		break;
+
+	case TYPE_A:
+		if (restart_point) {
+			int i, n, ch;
+
+			if (fseek(fout, 0L, SEEK_SET) < 0)
+				goto done;
+			n = restart_point;
+			for (i = 0; i++ < n;) {
+				if ((ch = getc(fout)) == EOF)
+					goto done;
+				if (ch == '\n')
+					i++;
+			}
+			if (fseek(fout, 0L, SEEK_CUR) < 0) {
+done:
+				warn("local: %s", local);
+				if (closefunc != NULL)
+					(*closefunc)(fout);
+				return;
+			}
+		}
+		while ((c = getc(din)) != EOF) {
+			if (c == '\n')
+				bare_lfs++;
+			while (c == '\r') {
+				while (hash && (bytes >= hashbytes)) {
+					(void) putchar('#');
+					(void) fflush(stdout);
+					hashbytes += HASHBYTES;
+				}
+				bytes++;
+				if ((c = getc(din)) != '\n' || tcrflag) {
+					if (ferror(fout))
+						goto break2;
+					(void) putc('\r', fout);
+					if (c == '\0') {
+						bytes++;
+						goto contin2;
+					}
+					if (c == EOF)
+						goto contin2;
+				}
+			}
+			(void) putc(c, fout);
+			bytes++;
+	contin2:	;
+		}
+break2:
+		if (bare_lfs) {
+			printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
+			printf("File may not have transferred correctly.\n");
+		}
+		if (hash) {
+			if (bytes < hashbytes)
+				(void) putchar('#');
+			(void) putchar('\n');
+			(void) fflush(stdout);
+		}
+		if (ferror(din)) {
+			if (errno != EPIPE)
+				warn("netin");
+			bytes = -1;
+		}
+		if (ferror(fout))
+			warn("local: %s", local);
+		break;
+	}
+	if (closefunc != NULL)
+		(*closefunc)(fout);
+	(void) signal(SIGINT, oldintr);
+	if (oldintp)
+		(void) signal(SIGPIPE, oldintp);
+	(void) fclose(din);
+	(void) gettimeofday(&stop, (struct timezone *)0);
+	(void) getreply(0);
+	if (bytes > 0 && is_retr)
+		ptransfer("received", bytes, &start, &stop);
+	return;
+abort:
+
+/* abort using RFC959 recommended IP,SYNC sequence  */
+
+	if (oldintp)
+		(void) signal(SIGPIPE, oldintr);
+	(void) signal(SIGINT, SIG_IGN);
+	if (!cpend) {
+		code = -1;
+		(void) signal(SIGINT, oldintr);
+		return;
+	}
+
+	abort_remote(din);
+	code = -1;
+	if (data >= 0) {
+		(void) close(data);
+		data = -1;
+	}
+	if (closefunc != NULL && fout != NULL)
+		(*closefunc)(fout);
+	if (din)
+		(void) fclose(din);
+	(void) gettimeofday(&stop, (struct timezone *)0);
+	if (bytes > 0)
+		ptransfer("received", bytes, &start, &stop);
+	(void) signal(SIGINT, oldintr);
+}
+
+/*
+ * Need to start a listen on the data channel before we send the command,
+ * otherwise the server's connect may fail.
+ */
+int
+initconn()
+{
+	char *p, *a;
+	int result, len, tmpno = 0;
+	int on = 1;
+	int a0, a1, a2, a3, p0, p1;
+
+	if (passivemode) {
+		data = socket(AF_INET, SOCK_STREAM, 0);
+		if (data < 0) {
+			perror("ftp: socket");
+			return(1);
+		}
+		if ((options & SO_DEBUG) &&
+		    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
+			       sizeof (on)) < 0)
+			perror("ftp: setsockopt (ignored)");
+		if (command("PASV") != COMPLETE) {
+			printf("Passive mode refused.\n");
+			goto bad;
+		}
+
+		/*
+		 * What we've got at this point is a string of comma
+		 * separated one-byte unsigned integer values.
+		 * The first four are the an IP address. The fifth is
+		 * the MSB of the port number, the sixth is the LSB.
+		 * From that we'll prepare a sockaddr_in.
+		 */
+
+		if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",
+			   &a0, &a1, &a2, &a3, &p0, &p1) != 6) {
+			printf("Passive mode address scan failure. "
+			       "Shouldn't happen!\n");
+			goto bad;
+		}
+
+		bzero(&data_addr, sizeof(data_addr));
+		data_addr.sin_family = AF_INET;
+		a = (char *)&data_addr.sin_addr.s_addr;
+		a[0] = a0 & 0xff;
+		a[1] = a1 & 0xff;
+		a[2] = a2 & 0xff;
+		a[3] = a3 & 0xff;
+		p = (char *)&data_addr.sin_port;
+		p[0] = p0 & 0xff;
+		p[1] = p1 & 0xff;
+
+		if (connect(data, (struct sockaddr *)&data_addr,
+			    sizeof(data_addr)) < 0) {
+			perror("ftp: connect");
+			goto bad;
+		}
+#ifdef IP_TOS
+		on = IPTOS_THROUGHPUT;
+		if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on,
+			       sizeof(int)) < 0)
+			perror("ftp: setsockopt TOS (ignored)");
+#endif
+		return(0);
+	}
+
+noport:
+	data_addr = myctladdr;
+	if (sendport)
+		data_addr.sin_port = 0;	/* let system pick one */ 
+	if (data != -1)
+		(void) close(data);
+	data = socket(AF_INET, SOCK_STREAM, 0);
+	if (data < 0) {
+		warn("socket");
+		if (tmpno)
+			sendport = 1;
+		return (1);
+	}
+	if (!sendport)
+		if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
+			warn("setsockopt (reuse address)");
+			goto bad;
+		}
+	if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
+		warn("bind");
+		goto bad;
+	}
+	if (options & SO_DEBUG &&
+	    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
+		warn("setsockopt (ignored)");
+	len = sizeof (data_addr);
+	if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
+		warn("getsockname");
+		goto bad;
+	}
+	if (listen(data, 1) < 0)
+		warn("listen");
+	if (sendport) {
+		a = (char *)&data_addr.sin_addr;
+		p = (char *)&data_addr.sin_port;
+#define	UC(b)	(((int)b)&0xff)
+		result =
+		    command("PORT %d,%d,%d,%d,%d,%d",
+		      UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
+		      UC(p[0]), UC(p[1]));
+		if (result == ERROR && sendport == -1) {
+			sendport = 0;
+			tmpno = 1;
+			goto noport;
+		}
+		return (result != COMPLETE);
+	}
+	if (tmpno)
+		sendport = 1;
+#ifdef IP_TOS
+	on = IPTOS_THROUGHPUT;
+	if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
+		warn("setsockopt TOS (ignored)");
+#endif
+	return (0);
+bad:
+	(void) close(data), data = -1;
+	if (tmpno)
+		sendport = 1;
+	return (1);
+}
+
+FILE *
+dataconn(lmode)
+	char *lmode;
+{
+	struct sockaddr_in from;
+	int s, fromlen = sizeof (from), tos;
+
+	if (passivemode)
+		return (fdopen(data, lmode));
+
+	s = accept(data, (struct sockaddr *) &from, &fromlen);
+	if (s < 0) {
+		warn("accept");
+		(void) close(data), data = -1;
+		return (NULL);
+	}
+	(void) close(data);
+	data = s;
+#ifdef IP_TOS
+	tos = IPTOS_THROUGHPUT;
+	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
+		warn("setsockopt TOS (ignored)");
+#endif
+	return (fdopen(data, lmode));
+}
+
+void
+ptransfer(direction, bytes, t0, t1)
+	char *direction;
+	long bytes;
+	struct timeval *t0, *t1;
+{
+	struct timeval td;
+	float s;
+	long bs;
+
+	if (verbose) {
+		tvsub(&td, t1, t0);
+		s = td.tv_sec + (td.tv_usec / 1000000.);
+#define	nz(x)	((x) == 0 ? 1 : (x))
+		bs = bytes / nz(s);
+		printf("%ld bytes %s in %.3g seconds (%ld bytes/s)\n",
+		    bytes, direction, s, bs);
+	}
+}
+
+/*
+void
+tvadd(tsum, t0)
+	struct timeval *tsum, *t0;
+{
+
+	tsum->tv_sec += t0->tv_sec;
+	tsum->tv_usec += t0->tv_usec;
+	if (tsum->tv_usec > 1000000)
+		tsum->tv_sec++, tsum->tv_usec -= 1000000;
+}
+*/
+
+void
+tvsub(tdiff, t1, t0)
+	struct timeval *tdiff, *t1, *t0;
+{
+
+	tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
+	tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
+	if (tdiff->tv_usec < 0)
+		tdiff->tv_sec--, tdiff->tv_usec += 1000000;
+}
+
+void
+psabort()
+{
+
+	abrtflag++;
+}
+
+void
+pswitch(flag)
+	int flag;
+{
+	sig_t oldintr;
+	static struct comvars {
+		int connect;
+		char name[MAXHOSTNAMELEN];
+		struct sockaddr_in mctl;
+		struct sockaddr_in hctl;
+		FILE *in;
+		FILE *out;
+		int tpe;
+		int curtpe;
+		int cpnd;
+		int sunqe;
+		int runqe;
+		int mcse;
+		int ntflg;
+		char nti[17];
+		char nto[17];
+		int mapflg;
+		char mi[MAXPATHLEN];
+		char mo[MAXPATHLEN];
+	} proxstruct, tmpstruct;
+	struct comvars *ip, *op;
+
+	abrtflag = 0;
+	oldintr = signal(SIGINT, psabort);
+	if (flag) {
+		if (proxy)
+			return;
+		ip = &tmpstruct;
+		op = &proxstruct;
+		proxy++;
+	} else {
+		if (!proxy)
+			return;
+		ip = &proxstruct;
+		op = &tmpstruct;
+		proxy = 0;
+	}
+	ip->connect = connected;
+	connected = op->connect;
+	if (hostname) {
+		(void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
+		ip->name[strlen(ip->name)] = '\0';
+	} else
+		ip->name[0] = 0;
+	hostname = op->name;
+	ip->hctl = hisctladdr;
+	hisctladdr = op->hctl;
+	ip->mctl = myctladdr;
+	myctladdr = op->mctl;
+	ip->in = cin;
+	cin = op->in;
+	ip->out = cout;
+	cout = op->out;
+	ip->tpe = type;
+	type = op->tpe;
+	ip->curtpe = curtype;
+	curtype = op->curtpe;
+	ip->cpnd = cpend;
+	cpend = op->cpnd;
+	ip->sunqe = sunique;
+	sunique = op->sunqe;
+	ip->runqe = runique;
+	runique = op->runqe;
+	ip->mcse = mcase;
+	mcase = op->mcse;
+	ip->ntflg = ntflag;
+	ntflag = op->ntflg;
+	(void) strncpy(ip->nti, ntin, 16);
+	(ip->nti)[strlen(ip->nti)] = '\0';
+	(void) strcpy(ntin, op->nti);
+	(void) strncpy(ip->nto, ntout, 16);
+	(ip->nto)[strlen(ip->nto)] = '\0';
+	(void) strcpy(ntout, op->nto);
+	ip->mapflg = mapflag;
+	mapflag = op->mapflg;
+	(void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
+	(ip->mi)[strlen(ip->mi)] = '\0';
+	(void) strcpy(mapin, op->mi);
+	(void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
+	(ip->mo)[strlen(ip->mo)] = '\0';
+	(void) strcpy(mapout, op->mo);
+	(void) signal(SIGINT, oldintr);
+	if (abrtflag) {
+		abrtflag = 0;
+		(*oldintr)(SIGINT);
+	}
+}
+
+void
+abortpt()
+{
+
+	printf("\n");
+	(void) fflush(stdout);
+	ptabflg++;
+	mflag = 0;
+	abrtflag = 0;
+	longjmp(ptabort, 1);
+}
+
+void
+proxtrans(cmd, local, remote)
+	char *cmd, *local, *remote;
+{
+	sig_t oldintr;
+	int secndflag = 0, prox_type, nfnd;
+	char *cmd2;
+	struct fd_set mask;
+
+	if (strcmp(cmd, "RETR"))
+		cmd2 = "RETR";
+	else
+		cmd2 = runique ? "STOU" : "STOR";
+	if ((prox_type = type) == 0) {
+		if (unix_server && unix_proxy)
+			prox_type = TYPE_I;
+		else
+			prox_type = TYPE_A;
+	}
+	if (curtype != prox_type)
+		changetype(prox_type, 1);
+	if (command("PASV") != COMPLETE) {
+		printf("proxy server does not support third party transfers.\n");
+		return;
+	}
+	pswitch(0);
+	if (!connected) {
+		printf("No primary connection\n");
+		pswitch(1);
+		code = -1;
+		return;
+	}
+	if (curtype != prox_type)
+		changetype(prox_type, 1);
+	if (command("PORT %s", pasv) != COMPLETE) {
+		pswitch(1);
+		return;
+	}
+	if (setjmp(ptabort))
+		goto abort;
+	oldintr = signal(SIGINT, abortpt);
+	if (command("%s %s", cmd, remote) != PRELIM) {
+		(void) signal(SIGINT, oldintr);
+		pswitch(1);
+		return;
+	}
+	sleep(2);
+	pswitch(1);
+	secndflag++;
+	if (command("%s %s", cmd2, local) != PRELIM)
+		goto abort;
+	ptflag++;
+	(void) getreply(0);
+	pswitch(0);
+	(void) getreply(0);
+	(void) signal(SIGINT, oldintr);
+	pswitch(1);
+	ptflag = 0;
+	printf("local: %s remote: %s\n", local, remote);
+	return;
+abort:
+	(void) signal(SIGINT, SIG_IGN);
+	ptflag = 0;
+	if (strcmp(cmd, "RETR") && !proxy)
+		pswitch(1);
+	else if (!strcmp(cmd, "RETR") && proxy)
+		pswitch(0);
+	if (!cpend && !secndflag) {  /* only here if cmd = "STOR" (proxy=1) */
+		if (command("%s %s", cmd2, local) != PRELIM) {
+			pswitch(0);
+			if (cpend)
+				abort_remote((FILE *) NULL);
+		}
+		pswitch(1);
+		if (ptabflg)
+			code = -1;
+		(void) signal(SIGINT, oldintr);
+		return;
+	}
+	if (cpend)
+		abort_remote((FILE *) NULL);
+	pswitch(!proxy);
+	if (!cpend && !secndflag) {  /* only if cmd = "RETR" (proxy=1) */
+		if (command("%s %s", cmd2, local) != PRELIM) {
+			pswitch(0);
+			if (cpend)
+				abort_remote((FILE *) NULL);
+			pswitch(1);
+			if (ptabflg)
+				code = -1;
+			(void) signal(SIGINT, oldintr);
+			return;
+		}
+	}
+	if (cpend)
+		abort_remote((FILE *) NULL);
+	pswitch(!proxy);
+	if (cpend) {
+		FD_ZERO(&mask);
+		FD_SET(fileno(cin), &mask);
+		if ((nfnd = empty(&mask, 10)) <= 0) {
+			if (nfnd < 0) {
+				warn("abort");
+			}
+			if (ptabflg)
+				code = -1;
+			lostpeer();
+		}
+		(void) getreply(0);
+		(void) getreply(0);
+	}
+	if (proxy)
+		pswitch(0);
+	pswitch(1);
+	if (ptabflg)
+		code = -1;
+	(void) signal(SIGINT, oldintr);
+}
+
+void
+reset(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct fd_set mask;
+	int nfnd = 1;
+
+	FD_ZERO(&mask);
+	while (nfnd > 0) {
+		FD_SET(fileno(cin), &mask);
+		if ((nfnd = empty(&mask,0)) < 0) {
+			warn("reset");
+			code = -1;
+			lostpeer();
+		}
+		else if (nfnd) {
+			(void) getreply(0);
+		}
+	}
+}
+
+char *
+gunique(local)
+	char *local;
+{
+	static char new[MAXPATHLEN];
+	char *cp = strrchr(local, '/');
+	int d, count=0;
+	char ext = '1';
+
+	if (cp)
+		*cp = '\0';
+	d = access(cp ? local : ".", 2);
+	if (cp)
+		*cp = '/';
+	if (d < 0) {
+		warn("local: %s", local);
+		return ((char *) 0);
+	}
+	(void) strcpy(new, local);
+	cp = new + strlen(new);
+	*cp++ = '.';
+	while (!d) {
+		if (++count == 100) {
+			printf("runique: can't find unique file name.\n");
+			return ((char *) 0);
+		}
+		*cp++ = ext;
+		*cp = '\0';
+		if (ext == '9')
+			ext = '0';
+		else
+			ext++;
+		if ((d = access(new, 0)) < 0)
+			break;
+		if (ext != '0')
+			cp--;
+		else if (*(cp - 2) == '.')
+			*(cp - 1) = '1';
+		else {
+			*(cp - 2) = *(cp - 2) + 1;
+			cp--;
+		}
+	}
+	return (new);
+}
+
+void
+abort_remote(din)
+	FILE *din;
+{
+	char buf[BUFSIZ];
+	int nfnd;
+	struct fd_set mask;
+
+	/*
+	 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
+	 * after urgent byte rather than before as is protocol now
+	 */
+	sprintf(buf, "%c%c%c", IAC, IP, IAC);
+	if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
+		warn("abort");
+	fprintf(cout,"%cABOR\r\n", DM);
+	(void) fflush(cout);
+	FD_ZERO(&mask);
+	FD_SET(fileno(cin), &mask);
+	if (din) { 
+		FD_SET(fileno(din), &mask);
+	}
+	if ((nfnd = empty(&mask, 10)) <= 0) {
+		if (nfnd < 0) {
+			warn("abort");
+		}
+		if (ptabflg)
+			code = -1;
+		lostpeer();
+	}
+	if (din && FD_ISSET(fileno(din), &mask)) {
+		while (read(fileno(din), buf, BUFSIZ) > 0)
+			/* LOOP */;
+	}
+	if (getreply(0) == ERROR && code == 552) {
+		/* 552 needed for nic style abort */
+		(void) getreply(0);
+	}
+	(void) getreply(0);
+}
diff --git a/ftp.tproj/ftp_var.c b/ftp.tproj/ftp_var.c
new file mode 100644
index 0000000..f1f972b
--- /dev/null
+++ b/ftp.tproj/ftp_var.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ftp_var.h	8.4 (Berkeley) 10/9/94
+ */
+
+#include <stdio.h>
+
+#include "ftp_var.h"
+
+/*
+ * FTP global variables.
+ */
+
+#include <sys/param.h>
+#include <setjmp.h>
+
+#include "extern.h"
+
+/*
+ * Options and other state info.
+ */
+int	trace;			/* trace packets exchanged */
+int	hash;			/* print # for each buffer transferred */
+int	sendport;		/* use PORT cmd for each data connection */
+int	verbose;		/* print messages coming back from server */
+int	connected;		/* connected to server */
+int	fromatty;		/* input is from a terminal */
+int	interactive;		/* interactively prompt on m* cmds */
+int	debug;			/* debugging level */
+int	bell;			/* ring bell on cmd completion */
+int	doglob;			/* glob local file names */
+int	autologin;		/* establish user account on connection */
+int	proxy;			/* proxy server connection active */
+int	proxflag;		/* proxy connection exists */
+int	sunique;		/* store files on server with unique name */
+int	runique;		/* store local files with unique name */
+int	mcase;			/* map upper to lower case for mget names */
+int	ntflag;			/* use ntin ntout tables for name translation */
+int	mapflag;		/* use mapin mapout templates on file names */
+int	code;			/* return/reply code for ftp command */
+int	crflag;			/* if 1, strip car. rets. on ascii gets */
+char	pasv[64];		/* passive port for proxy data connection */
+int	passivemode;		/* passive mode enabled */
+char	*altarg;		/* argv[1] with no shell-like preprocessing  */
+char	ntin[17];		/* input translation table */
+char	ntout[17];		/* output translation table */
+char	mapin[MAXPATHLEN];	/* input map template */
+char	mapout[MAXPATHLEN];	/* output map template */
+char	typename[32];		/* name of file transfer type */
+int	type;			/* requested file transfer type */
+int	curtype;		/* current file transfer type */
+char	structname[32];		/* name of file transfer structure */
+int	stru;			/* file transfer structure */
+char	formname[32];		/* name of file transfer format */
+int	form;			/* file transfer format */
+char	modename[32];		/* name of file transfer mode */
+int	mode;			/* file transfer mode */
+char	bytename[32];		/* local byte size in ascii */
+int	bytesize;		/* local byte size in binary */
+
+char	*hostname;		/* name of host connected to */
+int	unix_server;		/* server is unix, can use binary for ascii */
+int	unix_proxy;		/* proxy is unix, can use binary for ascii */
+
+struct	servent *sp;		/* service spec for tcp/ftp */
+
+jmp_buf	toplevel;		/* non-local goto stuff for cmd scanner */
+
+char	line[200];		/* input line buffer */
+char	*stringbase;		/* current scan point in line buffer */
+char	argbuf[200];		/* argument storage buffer */
+char	*argbase;		/* current storage point in arg buffer */
+int	margc;			/* count of arguments on input line */
+char	*margv[20];		/* args parsed from input line */
+int     cpend;                  /* flag: if != 0, then pending server reply */
+int	mflag;			/* flag: if != 0, then active multi command */
+
+int	options;		/* used during socket creation */
+
+int macnum;			/* number of defined macros */
+struct macel macros[16];
+char macbuf[4096];
diff --git a/ftp.tproj/ftp_var.h b/ftp.tproj/ftp_var.h
new file mode 100644
index 0000000..ad7f790
--- /dev/null
+++ b/ftp.tproj/ftp_var.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ftp_var.h	8.4 (Berkeley) 10/9/94
+ */
+
+/*
+ * FTP global variables.
+ */
+
+#include <sys/param.h>
+#include <setjmp.h>
+
+#include "extern.h"
+
+/*
+ * Options and other state info.
+ */
+extern int	trace;			/* trace packets exchanged */
+extern int	hash;			/* pr int # for each buffer transferred */
+extern int	sendport;		/* use PORT cmd for each data connection */
+extern int	verbose;		/* print messages coming back from server */
+extern int	connected;		/* connected to server */
+extern int	fromatty;		/* input is from a terminal */
+extern int	interactive;		/* interactively prompt on m* cmds */
+extern int	debug;			/* debugging level */
+extern int	bell;			/* ring bell on cmd completion */
+extern int	doglob;			/* glob local file names */
+extern int	autologin;		/* establish user account on connection */
+extern int	proxy;			/* proxy server connection active */
+extern int	proxflag;		/* proxy connection exists */
+extern int	sunique;		/* store files on server with unique name */
+extern int	runique;		/* store local files with unique name */
+extern int	mcase;			/* map upper to lower case for mget names */
+extern int	ntflag;			/* use ntin ntout tables for name translation */
+extern int	mapflag;		/* use mapin mapout templates on file names */
+extern int	code;			/* return/reply code for ftp command */
+extern int	crflag;			/* if 1, strip car. rets. on ascii gets */
+extern char	pasv[64];		/* passive port for proxy data connection */
+extern int	passivemode;		/* passive mode enabled */
+extern char	*altarg;		/* argv[1] with no shell-like preprocessing  */
+extern char	ntin[17];		/* input translation table */
+extern char	ntout[17];		/* output translation table */
+extern char	mapin[MAXPATHLEN];	/* input map template */
+extern char	mapout[MAXPATHLEN];	/* output map template */
+extern char	typename[32];		/* name of file transfer type */
+extern int	type;			/* requested file transfer type */
+extern int	curtype;		/* current file transfer type */
+extern char	structname[32];		/* name of file transfer structure */
+extern int	stru;			/* file transfer structure */
+extern char	formname[32];		/* name of file transfer format */
+extern int	form;			/* file transfer format */
+extern char	modename[32];		/* name of file transfer mode */
+extern int	mode;			/* file transfer mode */
+extern char	bytename[32];		/* local byte size in ascii */
+extern int	bytesize;		/* local byte size in binary */
+
+extern char	*hostname;		/* name of host connected to */
+extern int	unix_server;		/* server is unix, can use binary for ascii */
+extern int	unix_proxy;		/* proxy is unix, can use binary for ascii */
+
+extern struct	servent *sp;		/* service spec for tcp/ftp */
+
+extern jmp_buf	toplevel;		/* non-local goto stuff for cmd scanner */
+
+extern char	line[200];		/* input line buffer */
+extern char	*stringbase;		/* current scan point in line buffer */
+extern char	argbuf[200];		/* argument storage buffer */
+extern char	*argbase;		/* current storage point in arg buffer */
+extern int	margc;			/* count of arguments on input line */
+extern char	*margv[20];		/* args parsed from input line */
+extern int     cpend;                  /* flag: if != 0, then pending server reply */
+extern int	mflag;			/* flag: if != 0, then active multi command */
+
+extern int	options;		/* used during socket creation */
+
+/*
+ * Format of command table.
+ */
+struct cmd {
+	char	*c_name;	/* name of command */
+	char	*c_help;	/* help string */
+	char	c_bell;		/* give bell when command completes */
+	char	c_conn;		/* must be connected to use command */
+	char	c_proxy;	/* proxy server may execute */
+	void	(*c_handler) __P((int, char **)); /* function to call */
+};
+
+struct macel {
+	char mac_name[9];	/* macro name */
+	char *mac_start;	/* start of macro in macbuf */
+	char *mac_end;		/* end of macro in macbuf */
+};
+
+extern int macnum;			/* number of defined macros */
+extern struct macel macros[16];
+extern char macbuf[4096];
diff --git a/ftp.tproj/h.template b/ftp.tproj/h.template
new file mode 100644
index 0000000..f3c1b04
--- /dev/null
+++ b/ftp.tproj/h.template
@@ -0,0 +1,11 @@
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+#import <Foundation/Foundation.h>
+
+@interface $FILENAMESANSEXTENSION$ : NSObject
+{
+
+}
+
+@end
diff --git a/ftp.tproj/m.template b/ftp.tproj/m.template
new file mode 100644
index 0000000..1216fe5
--- /dev/null
+++ b/ftp.tproj/m.template
@@ -0,0 +1,18 @@
+$$ Lines starting with $$ are not inserted into newly created files
+$$ The following substitutions are made:
+$$
+$$ $FILENAME$                e.g. foo.m
+$$ $FILENAMESANSEXTENSION$   e.g. foo
+$$ $DIRECTORY$               e.g. /tmp/MyNewApp
+$$ $PROJECTNAME$             e.g. MyNewApp
+$$ $SUBPROJECTNAME$          e.g. TheGoodPart.subproj
+$$ $USERNAME$                e.g. mwagner
+$$ $DATE$                    e.g. Jan-1-1994
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+#import "$FILENAMESANSEXTENSION$.h"
+
+@implementation $FILENAMESANSEXTENSION$
+
+@end
diff --git a/ftp.tproj/main.c b/ftp.tproj/main.c
new file mode 100644
index 0000000..4ad3ed2
--- /dev/null
+++ b/ftp.tproj/main.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * FTP User Program -- Command Interface.
+ */
+/*#include <sys/ioctl.h>*/
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <arpa/ftp.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "ftp_var.h"
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int ch, top;
+	struct passwd *pw = NULL;
+	char *cp, homedir[MAXPATHLEN];
+
+	sp = getservbyname("ftp", "tcp");
+	if (sp == 0)
+		errx(1, "ftp/tcp: unknown service");
+	doglob = 1;
+	interactive = 1;
+	autologin = 1;
+
+	while ((ch = getopt(argc, argv, "dgintv")) != EOF) {
+		switch (ch) {
+		case 'd':
+			options |= SO_DEBUG;
+			debug++;
+			break;
+			
+		case 'g':
+			doglob = 0;
+			break;
+
+		case 'i':
+			interactive = 0;
+			break;
+
+		case 'n':
+			autologin = 0;
+			break;
+
+		case 't':
+			trace++;
+			break;
+
+		case 'v':
+			verbose++;
+			break;
+
+		default:
+			(void)fprintf(stderr,
+				"usage: ftp [-dgintv] [host [port]]\n");
+			exit(1);
+		}
+	}
+	argc -= optind;
+	argv += optind;
+
+	fromatty = isatty(fileno(stdin));
+	if (fromatty)
+		verbose++;
+	cpend = 0;	/* no pending replies */
+	proxy = 0;	/* proxy not active */
+	passivemode = 0; /* passive mode not active */
+	crflag = 1;	/* strip c.r. on ascii gets */
+	sendport = -1;	/* not using ports */
+	/*
+	 * Set up the home directory in case we're globbing.
+	 */
+	cp = getlogin();
+	if (cp != NULL) {
+		pw = getpwnam(cp);
+	}
+	if (pw == NULL)
+		pw = getpwuid(getuid());
+	if (pw != NULL) {
+		home = homedir;
+		(void) strcpy(home, pw->pw_dir);
+	}
+	if (argc > 0) {
+		char *xargv[5];
+		extern char *__progname;
+
+		if (setjmp(toplevel))
+			exit(0);
+		(void) signal(SIGINT, intr);
+		(void) signal(SIGPIPE, lostpeer);
+		xargv[0] = __progname;
+		xargv[1] = argv[0];
+		xargv[2] = argv[1];
+		xargv[3] = argv[2];
+		xargv[4] = NULL;
+		setpeer(argc+1, xargv);
+	}
+	top = setjmp(toplevel) == 0;
+	if (top) {
+		(void) signal(SIGINT, intr);
+		(void) signal(SIGPIPE, lostpeer);
+	}
+	for (;;) {
+		cmdscanner(top);
+		top = 1;
+	}
+}
+
+void
+intr()
+{
+
+	longjmp(toplevel, 1);
+}
+
+void
+lostpeer()
+{
+
+	if (connected) {
+		if (cout != NULL) {
+			(void) shutdown(fileno(cout), 1+1);
+			(void) fclose(cout);
+			cout = NULL;
+		}
+		if (data >= 0) {
+			(void) shutdown(data, 1+1);
+			(void) close(data);
+			data = -1;
+		}
+		connected = 0;
+	}
+	pswitch(1);
+	if (connected) {
+		if (cout != NULL) {
+			(void) shutdown(fileno(cout), 1+1);
+			(void) fclose(cout);
+			cout = NULL;
+		}
+		connected = 0;
+	}
+	proxflag = 0;
+	pswitch(0);
+}
+
+/*
+char *
+tail(filename)
+	char *filename;
+{
+	char *s;
+	
+	while (*filename) {
+		s = strrchr(filename, '/');
+		if (s == NULL)
+			break;
+		if (s[1])
+			return (s + 1);
+		*s = '\0';
+	}
+	return (filename);
+}
+*/
+
+/*
+ * Command parser.
+ */
+void
+cmdscanner(top)
+	int top;
+{
+	struct cmd *c;
+	int l;
+
+	if (!top)
+		(void) putchar('\n');
+	for (;;) {
+		if (fromatty) {
+			printf("ftp> ");
+			(void) fflush(stdout);
+		}
+		if (fgets(line, sizeof line, stdin) == NULL)
+			quit(0, 0);
+		l = strlen(line);
+		if (l == 0)
+			break;
+		if (line[--l] == '\n') {
+			if (l == 0)
+				break;
+			line[l] = '\0';
+		} else if (l == sizeof(line) - 2) {
+			printf("sorry, input line too long\n");
+			while ((l = getchar()) != '\n' && l != EOF)
+				/* void */;
+			break;
+		} /* else it was a line without a newline */
+		makeargv();
+		if (margc == 0) {
+			continue;
+		}
+		c = getcmd(margv[0]);
+		if (c == (struct cmd *)-1) {
+			printf("?Ambiguous command\n");
+			continue;
+		}
+		if (c == 0) {
+			printf("?Invalid command\n");
+			continue;
+		}
+		if (c->c_conn && !connected) {
+			printf("Not connected.\n");
+			continue;
+		}
+		(*c->c_handler)(margc, margv);
+		if (bell && c->c_bell)
+			(void) putchar('\007');
+		if (c->c_handler != help)
+			break;
+	}
+	(void) signal(SIGINT, intr);
+	(void) signal(SIGPIPE, lostpeer);
+}
+
+struct cmd *
+getcmd(name)
+	char *name;
+{
+	char *p, *q;
+	struct cmd *c, *found;
+	int nmatches, longest;
+
+	longest = 0;
+	nmatches = 0;
+	found = 0;
+	for (c = cmdtab; p = c->c_name; c++) {
+		for (q = name; *q == *p++; q++)
+			if (*q == 0)		/* exact match? */
+				return (c);
+		if (!*q) {			/* the name was a prefix */
+			if (q - name > longest) {
+				longest = q - name;
+				nmatches = 1;
+				found = c;
+			} else if (q - name == longest)
+				nmatches++;
+		}
+	}
+	if (nmatches > 1)
+		return ((struct cmd *)-1);
+	return (found);
+}
+
+/*
+ * Slice a string up into argc/argv.
+ */
+
+int slrflag;
+
+void
+makeargv()
+{
+	char **argp;
+
+	margc = 0;
+	argp = margv;
+	stringbase = line;		/* scan from first of buffer */
+	argbase = argbuf;		/* store from first of buffer */
+	slrflag = 0;
+	while (*argp++ = slurpstring())
+		margc++;
+}
+
+/*
+ * Parse string into argbuf;
+ * implemented with FSM to
+ * handle quoting and strings
+ */
+char *
+slurpstring()
+{
+	int got_one = 0;
+	char *sb = stringbase;
+	char *ap = argbase;
+	char *tmp = argbase;		/* will return this if token found */
+
+	if (*sb == '!' || *sb == '$') {	/* recognize ! as a token for shell */
+		switch (slrflag) {	/* and $ as token for macro invoke */
+			case 0:
+				slrflag++;
+				stringbase++;
+				return ((*sb == '!') ? "!" : "$");
+				/* NOTREACHED */
+			case 1:
+				slrflag++;
+				altarg = stringbase;
+				break;
+			default:
+				break;
+		}
+	}
+
+S0:
+	switch (*sb) {
+
+	case '\0':
+		goto OUT;
+
+	case ' ':
+	case '\t':
+		sb++; goto S0;
+
+	default:
+		switch (slrflag) {
+			case 0:
+				slrflag++;
+				break;
+			case 1:
+				slrflag++;
+				altarg = sb;
+				break;
+			default:
+				break;
+		}
+		goto S1;
+	}
+
+S1:
+	switch (*sb) {
+
+	case ' ':
+	case '\t':
+	case '\0':
+		goto OUT;	/* end of token */
+
+	case '\\':
+		sb++; goto S2;	/* slurp next character */
+
+	case '"':
+		sb++; goto S3;	/* slurp quoted string */
+
+	default:
+		*ap++ = *sb++;	/* add character to token */
+		got_one = 1;
+		goto S1;
+	}
+
+S2:
+	switch (*sb) {
+
+	case '\0':
+		goto OUT;
+
+	default:
+		*ap++ = *sb++;
+		got_one = 1;
+		goto S1;
+	}
+
+S3:
+	switch (*sb) {
+
+	case '\0':
+		goto OUT;
+
+	case '"':
+		sb++; goto S1;
+
+	default:
+		*ap++ = *sb++;
+		got_one = 1;
+		goto S3;
+	}
+
+OUT:
+	if (got_one)
+		*ap++ = '\0';
+	argbase = ap;			/* update storage pointer */
+	stringbase = sb;		/* update scan pointer */
+	if (got_one) {
+		return (tmp);
+	}
+	switch (slrflag) {
+		case 0:
+			slrflag++;
+			break;
+		case 1:
+			slrflag++;
+			altarg = (char *) 0;
+			break;
+		default:
+			break;
+	}
+	return ((char *)0);
+}
+
+#define HELPINDENT ((int) sizeof ("directory"))
+
+/*
+ * Help command.
+ * Call each command handler with argc == 0 and argv[0] == name.
+ */
+void
+help(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct cmd *c;
+
+	if (argc == 1) {
+		int i, j, w, k;
+		int columns, width = 0, lines;
+
+		printf("Commands may be abbreviated.  Commands are:\n\n");
+		for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
+			int len = strlen(c->c_name);
+
+			if (len > width)
+				width = len;
+		}
+		width = (width + 8) &~ 7;
+		columns = 80 / width;
+		if (columns == 0)
+			columns = 1;
+		lines = (NCMDS + columns - 1) / columns;
+		for (i = 0; i < lines; i++) {
+			for (j = 0; j < columns; j++) {
+				c = cmdtab + j * lines + i;
+				if (c->c_name && (!proxy || c->c_proxy)) {
+					printf("%s", c->c_name);
+				}
+				else if (c->c_name) {
+					for (k=0; k < strlen(c->c_name); k++) {
+						(void) putchar(' ');
+					}
+				}
+				if (c + lines >= &cmdtab[NCMDS]) {
+					printf("\n");
+					break;
+				}
+				w = strlen(c->c_name);
+				while (w < width) {
+					w = (w + 8) &~ 7;
+					(void) putchar('\t');
+				}
+			}
+		}
+		return;
+	}
+	while (--argc > 0) {
+		char *arg;
+		arg = *++argv;
+		c = getcmd(arg);
+		if (c == (struct cmd *)-1)
+			printf("?Ambiguous help command %s\n", arg);
+		else if (c == (struct cmd *)0)
+			printf("?Invalid help command %s\n", arg);
+		else
+			printf("%-*s\t%s\n", HELPINDENT,
+				c->c_name, c->c_help);
+	}
+}
diff --git a/ftp.tproj/pathnames.h b/ftp.tproj/pathnames.h
new file mode 100644
index 0000000..4403aa8
--- /dev/null
+++ b/ftp.tproj/pathnames.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/6/93
+ */
+
+#include <paths.h>
+
+#undef _PATH_TMP
+#define	_PATH_TMP	"/tmp/ftpXXXXXX"
diff --git a/ftp.tproj/ruserpass.c b/ftp.tproj/ruserpass.c
new file mode 100644
index 0000000..ed5a406
--- /dev/null
+++ b/ftp.tproj/ruserpass.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ftp_var.h"
+
+static	int token __P((void));
+static	FILE *cfile;
+
+#define	DEFAULT	1
+#define	LOGIN	2
+#define	PASSWD	3
+#define	ACCOUNT 4
+#define MACDEF  5
+#define	ID	10
+#define	MACH	11
+
+static char tokval[100];
+
+static struct toktab {
+	char *tokstr;
+	int tval;
+} toktab[]= {
+	{ "default",	DEFAULT },
+	{ "login",	LOGIN },
+	{ "password",	PASSWD },
+	{ "passwd",	PASSWD },
+	{ "account",	ACCOUNT },
+	{ "machine",	MACH },
+	{ "macdef",	MACDEF },
+	{ NULL,		0 }
+};
+
+int
+ruserpass(host, aname, apass, aacct)
+	char *host, **aname, **apass, **aacct;
+{
+	char *hdir, buf[BUFSIZ], *tmp;
+	char myname[MAXHOSTNAMELEN], *mydomain;
+	int t, i, c, usedefault = 0;
+	struct stat stb;
+
+	hdir = getenv("HOME");
+	if (hdir == NULL)
+		hdir = ".";
+	(void) sprintf(buf, "%s/.netrc", hdir);
+	cfile = fopen(buf, "r");
+	if (cfile == NULL) {
+		if (errno != ENOENT)
+			warn("%s", buf);
+		return (0);
+	}
+	if (gethostname(myname, sizeof(myname)) < 0)
+		myname[0] = '\0';
+	if ((mydomain = strchr(myname, '.')) == NULL)
+		mydomain = "";
+next:
+	while ((t = token())) switch(t) {
+
+	case DEFAULT:
+		usedefault = 1;
+		/* FALL THROUGH */
+
+	case MACH:
+		if (!usedefault) {
+			if (token() != ID)
+				continue;
+			/*
+			 * Allow match either for user's input host name
+			 * or official hostname.  Also allow match of 
+			 * incompletely-specified host in local domain.
+			 */
+			if (strcasecmp(host, tokval) == 0)
+				goto match;
+			if (strcasecmp(hostname, tokval) == 0)
+				goto match;
+			if ((tmp = strchr(hostname, '.')) != NULL &&
+			    strcasecmp(tmp, mydomain) == 0 &&
+			    strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
+			    tokval[tmp - hostname] == '\0')
+				goto match;
+			if ((tmp = strchr(host, '.')) != NULL &&
+			    strcasecmp(tmp, mydomain) == 0 &&
+			    strncasecmp(host, tokval, tmp - host) == 0 &&
+			    tokval[tmp - host] == '\0')
+				goto match;
+			continue;
+		}
+	match:
+		while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
+
+		case LOGIN:
+			if (token())
+				if (*aname == 0) { 
+					*aname = malloc((unsigned) strlen(tokval) + 1);
+					(void) strcpy(*aname, tokval);
+				} else {
+					if (strcmp(*aname, tokval))
+						goto next;
+				}
+			break;
+		case PASSWD:
+			if ((*aname == NULL || strcmp(*aname, "anonymous")) &&
+			    fstat(fileno(cfile), &stb) >= 0 &&
+			    (stb.st_mode & 077) != 0) {
+	warnx("Error: .netrc file is readable by others.");
+	warnx("Remove password or make file unreadable by others.");
+				goto bad;
+			}
+			if (token() && *apass == 0) {
+				*apass = malloc((unsigned) strlen(tokval) + 1);
+				(void) strcpy(*apass, tokval);
+			}
+			break;
+		case ACCOUNT:
+			if (fstat(fileno(cfile), &stb) >= 0
+			    && (stb.st_mode & 077) != 0) {
+	warnx("Error: .netrc file is readable by others.");
+	warnx("Remove account or make file unreadable by others.");
+				goto bad;
+			}
+			if (token() && *aacct == 0) {
+				*aacct = malloc((unsigned) strlen(tokval) + 1);
+				(void) strcpy(*aacct, tokval);
+			}
+			break;
+		case MACDEF:
+			if (proxy) {
+				(void) fclose(cfile);
+				return (0);
+			}
+			while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
+			if (c == EOF || c == '\n') {
+				printf("Missing macdef name argument.\n");
+				goto bad;
+			}
+			if (macnum == 16) {
+				printf("Limit of 16 macros have already been defined\n");
+				goto bad;
+			}
+			tmp = macros[macnum].mac_name;
+			*tmp++ = c;
+			for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
+			    !isspace(c); ++i) {
+				*tmp++ = c;
+			}
+			if (c == EOF) {
+				printf("Macro definition missing null line terminator.\n");
+				goto bad;
+			}
+			*tmp = '\0';
+			if (c != '\n') {
+				while ((c=getc(cfile)) != EOF && c != '\n');
+			}
+			if (c == EOF) {
+				printf("Macro definition missing null line terminator.\n");
+				goto bad;
+			}
+			if (macnum == 0) {
+				macros[macnum].mac_start = macbuf;
+			}
+			else {
+				macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
+			}
+			tmp = macros[macnum].mac_start;
+			while (tmp != macbuf + 4096) {
+				if ((c=getc(cfile)) == EOF) {
+				printf("Macro definition missing null line terminator.\n");
+					goto bad;
+				}
+				*tmp = c;
+				if (*tmp == '\n') {
+					if (*(tmp-1) == '\0') {
+					   macros[macnum++].mac_end = tmp - 1;
+					   break;
+					}
+					*tmp = '\0';
+				}
+				tmp++;
+			}
+			if (tmp == macbuf + 4096) {
+				printf("4K macro buffer exceeded\n");
+				goto bad;
+			}
+			break;
+		default:
+			warnx("Unknown .netrc keyword %s", tokval);
+			break;
+		}
+		goto done;
+	}
+done:
+	(void) fclose(cfile);
+	return (0);
+bad:
+	(void) fclose(cfile);
+	return (-1);
+}
+
+static int
+token()
+{
+	char *cp;
+	int c;
+	struct toktab *t;
+
+	if (feof(cfile) || ferror(cfile))
+		return (0);
+	while ((c = getc(cfile)) != EOF &&
+	    (c == '\n' || c == '\t' || c == ' ' || c == ','))
+		continue;
+	if (c == EOF)
+		return (0);
+	cp = tokval;
+	if (c == '"') {
+		while ((c = getc(cfile)) != EOF && c != '"') {
+			if (c == '\\')
+				c = getc(cfile);
+			*cp++ = c;
+		}
+	} else {
+		*cp++ = c;
+		while ((c = getc(cfile)) != EOF
+		    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
+			if (c == '\\')
+				c = getc(cfile);
+			*cp++ = c;
+		}
+	}
+	*cp = 0;
+	if (tokval[0] == 0)
+		return (0);
+	for (t = toktab; t->tokstr; t++)
+		if (!strcmp(t->tokstr, tokval))
+			return (t->tval);
+	return (ID);
+}
diff --git a/ftpd.tproj/Makefile b/ftpd.tproj/Makefile
new file mode 100644
index 0000000..a1d09f3
--- /dev/null
+++ b/ftpd.tproj/Makefile
@@ -0,0 +1,53 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ftpd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = extern.h pathnames.h
+
+OTHERLINKED = ftpcmd.y
+
+CFILES = ftpd.c logwtmp.c popen.c vers.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble ftpd.8
+
+OTHERLINKEDOFILES = ftpcmd.o
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ftpd.tproj/Makefile.postamble b/ftpd.tproj/Makefile.postamble
new file mode 100644
index 0000000..7ede358
--- /dev/null
+++ b/ftpd.tproj/Makefile.postamble
@@ -0,0 +1,111 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
diff --git a/ftpd.tproj/Makefile.preamble b/ftpd.tproj/Makefile.preamble
new file mode 100644
index 0000000..dcbd1c8
--- /dev/null
+++ b/ftpd.tproj/Makefile.preamble
@@ -0,0 +1,119 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS = 
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR = 
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+-include ../Makefile.include
diff --git a/ftpd.tproj/PB.project b/ftpd.tproj/PB.project
new file mode 100644
index 0000000..b135f93
--- /dev/null
+++ b/ftpd.tproj/PB.project
@@ -0,0 +1,40 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (extern.h, pathnames.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (ftpcmd.y, ftpd.c, logwtmp.c, popen.c, vers.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, ftpd.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ftpd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ftpd.tproj/extern.h b/ftpd.tproj/extern.h
new file mode 100644
index 0000000..1d02d54
--- /dev/null
+++ b/ftpd.tproj/extern.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)extern.h	8.2 (Berkeley) 4/4/94
+ */
+
+void	blkfree __P((char **));
+char  **copyblk __P((char **));
+void	cwd __P((char *));
+void	delete __P((char *));
+void	dologout __P((int));
+void	fatal __P((char *));
+int	ftpd_pclose __P((FILE *));
+FILE   *ftpd_popen __P((char *, char *));
+char   *getline __P((char *, int, FILE *));
+void	logwtmp __P((char *, char *, char *));
+void	lreply __P((int, const char *, ...));
+void	makedir __P((char *));
+void	nack __P((char *));
+void	pass __P((char *));
+void	passive __P((void));
+void	perror_reply __P((int, char *));
+void	pwd __P((void));
+void	removedir __P((char *));
+void	renamecmd __P((char *, char *));
+char   *renamefrom __P((char *));
+void	reply __P((int, const char *, ...));
+void	retrieve __P((char *, char *));
+void	send_file_list __P((char *));
+void	setproctitle __P((const char *, ...));
+void	statcmd __P((void));
+void	statfilecmd __P((char *));
+void	store __P((char *, char *, int));
+void	upper __P((char *));
+void	user __P((char *));
+void	yyerror __P((char *));
diff --git a/ftpd.tproj/ftpcmd.y b/ftpd.tproj/ftpcmd.y
new file mode 100644
index 0000000..aeb59bd
--- /dev/null
+++ b/ftpd.tproj/ftpcmd.y
@@ -0,0 +1,1269 @@
+/*
+ * Copyright (c) 1985, 1988, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ftpcmd.y	8.3 (Berkeley) 4/6/94
+ */
+
+/*
+ * Grammar for FTP commands.
+ * See RFC 959.
+ */
+
+%{
+
+#ifndef lint
+static char sccsid[] = "@(#)ftpcmd.y	8.3 (Berkeley) 4/6/94";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+#include <arpa/ftp.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <glob.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "extern.h"
+
+extern	struct sockaddr_in data_dest;
+extern	int logged_in;
+extern	struct passwd *pw;
+extern	int guest;
+extern	int logging;
+extern	int type;
+extern	int form;
+extern	int debug;
+extern	int timeout;
+extern	int maxtimeout;
+extern  int pdata;
+extern	char hostname[], remotehost[];
+extern	char proctitle[];
+extern	int usedefault;
+extern  int transflag;
+extern  char tmpline[];
+
+off_t	restart_point;
+
+static	int cmd_type;
+static	int cmd_form;
+static	int cmd_bytesz;
+char	cbuf[512];
+char	*fromname;
+
+%}
+
+%union {
+	int	i;
+	char   *s;
+}
+
+%token
+	A	B	C	E	F	I
+	L	N	P	R	S	T
+
+	SP	CRLF	COMMA
+
+	USER	PASS	ACCT	REIN	QUIT	PORT
+	PASV	TYPE	STRU	MODE	RETR	STOR
+	APPE	MLFL	MAIL	MSND	MSOM	MSAM
+	MRSQ	MRCP	ALLO	REST	RNFR	RNTO
+	ABOR	DELE	CWD	LIST	NLST	SITE
+	STAT	HELP	NOOP	MKD	RMD	PWD
+	CDUP	STOU	SMNT	SYST	SIZE	MDTM
+
+	UMASK	IDLE	CHMOD
+
+	LEXERR
+
+%token	<s> STRING
+%token	<i> NUMBER
+
+%type	<i> check_login octal_number byte_size
+%type	<i> struct_code mode_code type_code form_code
+%type	<s> pathstring pathname password username
+
+%start	cmd_list
+
+%%
+
+cmd_list
+	: /* empty */
+	| cmd_list cmd
+		{
+			fromname = (char *) 0;
+			restart_point = (off_t) 0;
+		}
+	| cmd_list rcmd
+	;
+
+cmd
+	: USER SP username CRLF
+		{
+			user($3);
+			free($3);
+		}
+	| PASS SP password CRLF
+		{
+			pass($3);
+			free($3);
+		}
+	| PORT SP host_port CRLF
+		{
+			usedefault = 0;
+			if (pdata >= 0) {
+				(void) close(pdata);
+				pdata = -1;
+			}
+			reply(200, "PORT command successful.");
+		}
+	| PASV CRLF
+		{
+			passive();
+		}
+	| TYPE SP type_code CRLF
+		{
+			switch (cmd_type) {
+
+			case TYPE_A:
+				if (cmd_form == FORM_N) {
+					reply(200, "Type set to A.");
+					type = cmd_type;
+					form = cmd_form;
+				} else
+					reply(504, "Form must be N.");
+				break;
+
+			case TYPE_E:
+				reply(504, "Type E not implemented.");
+				break;
+
+			case TYPE_I:
+				reply(200, "Type set to I.");
+				type = cmd_type;
+				break;
+
+			case TYPE_L:
+#if NBBY == 8
+				if (cmd_bytesz == 8) {
+					reply(200,
+					    "Type set to L (byte size 8).");
+					type = cmd_type;
+				} else
+					reply(504, "Byte size must be 8.");
+#else /* NBBY == 8 */
+				UNIMPLEMENTED for NBBY != 8
+#endif /* NBBY == 8 */
+			}
+		}
+	| STRU SP struct_code CRLF
+		{
+			switch ($3) {
+
+			case STRU_F:
+				reply(200, "STRU F ok.");
+				break;
+
+			default:
+				reply(504, "Unimplemented STRU type.");
+			}
+		}
+	| MODE SP mode_code CRLF
+		{
+			switch ($3) {
+
+			case MODE_S:
+				reply(200, "MODE S ok.");
+				break;
+
+			default:
+				reply(502, "Unimplemented MODE type.");
+			}
+		}
+	| ALLO SP NUMBER CRLF
+		{
+			reply(202, "ALLO command ignored.");
+		}
+	| ALLO SP NUMBER SP R SP NUMBER CRLF
+		{
+			reply(202, "ALLO command ignored.");
+		}
+	| RETR check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				retrieve((char *) 0, $4);
+			if ($4 != NULL)
+				free($4);
+		}
+	| STOR check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				store($4, "w", 0);
+			if ($4 != NULL)
+				free($4);
+		}
+	| APPE check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				store($4, "a", 0);
+			if ($4 != NULL)
+				free($4);
+		}
+	| NLST check_login CRLF
+		{
+			if ($2)
+				send_file_list(".");
+		}
+	| NLST check_login SP STRING CRLF
+		{
+			if ($2 && $4 != NULL)
+				send_file_list($4);
+			if ($4 != NULL)
+				free($4);
+		}
+	| LIST check_login CRLF
+		{
+			if ($2)
+				retrieve("/bin/ls -lgA", "");
+		}
+	| LIST check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				retrieve("/bin/ls -lgA %s", $4);
+			if ($4 != NULL)
+				free($4);
+		}
+	| STAT check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				statfilecmd($4);
+			if ($4 != NULL)
+				free($4);
+		}
+	| STAT CRLF
+		{
+			statcmd();
+		}
+	| DELE check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				delete($4);
+			if ($4 != NULL)
+				free($4);
+		}
+	| RNTO SP pathname CRLF
+		{
+			if (fromname) {
+				renamecmd(fromname, $3);
+				free(fromname);
+				fromname = (char *) 0;
+			} else {
+				reply(503, "Bad sequence of commands.");
+			}
+			free($3);
+		}
+	| ABOR CRLF
+		{
+			reply(225, "ABOR command successful.");
+		}
+	| CWD check_login CRLF
+		{
+			if ($2)
+				cwd(pw->pw_dir);
+		}
+	| CWD check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				cwd($4);
+			if ($4 != NULL)
+				free($4);
+		}
+	| HELP CRLF
+		{
+			help(cmdtab, (char *) 0);
+		}
+	| HELP SP STRING CRLF
+		{
+			char *cp = $3;
+
+			if (strncasecmp(cp, "SITE", 4) == 0) {
+				cp = $3 + 4;
+				if (*cp == ' ')
+					cp++;
+				if (*cp)
+					help(sitetab, cp);
+				else
+					help(sitetab, (char *) 0);
+			} else
+				help(cmdtab, $3);
+		}
+	| NOOP CRLF
+		{
+			reply(200, "NOOP command successful.");
+		}
+	| MKD check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				makedir($4);
+			if ($4 != NULL)
+				free($4);
+		}
+	| RMD check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				removedir($4);
+			if ($4 != NULL)
+				free($4);
+		}
+	| PWD check_login CRLF
+		{
+			if ($2)
+				pwd();
+		}
+	| CDUP check_login CRLF
+		{
+			if ($2)
+				cwd("..");
+		}
+	| SITE SP HELP CRLF
+		{
+			help(sitetab, (char *) 0);
+		}
+	| SITE SP HELP SP STRING CRLF
+		{
+			help(sitetab, $5);
+		}
+	| SITE SP UMASK check_login CRLF
+		{
+			int oldmask;
+
+			if ($4) {
+				oldmask = umask(0);
+				(void) umask(oldmask);
+				reply(200, "Current UMASK is %03o", oldmask);
+			}
+		}
+	| SITE SP UMASK check_login SP octal_number CRLF
+		{
+			int oldmask;
+
+			if ($4) {
+				if (($6 == -1) || ($6 > 0777)) {
+					reply(501, "Bad UMASK value");
+				} else {
+					oldmask = umask($6);
+					reply(200,
+					    "UMASK set to %03o (was %03o)",
+					    $6, oldmask);
+				}
+			}
+		}
+	| SITE SP CHMOD check_login SP octal_number SP pathname CRLF
+		{
+			if ($4 && ($8 != NULL)) {
+				if ($6 > 0777)
+					reply(501,
+				"CHMOD: Mode value must be between 0 and 0777");
+				else if (chmod($8, $6) < 0)
+					perror_reply(550, $8);
+				else
+					reply(200, "CHMOD command successful.");
+			}
+			if ($8 != NULL)
+				free($8);
+		}
+	| SITE SP IDLE CRLF
+		{
+			reply(200,
+			    "Current IDLE time limit is %d seconds; max %d",
+				timeout, maxtimeout);
+		}
+	| SITE SP IDLE SP NUMBER CRLF
+		{
+			if ($5 < 30 || $5 > maxtimeout) {
+				reply(501,
+			"Maximum IDLE time must be between 30 and %d seconds",
+				    maxtimeout);
+			} else {
+				timeout = $5;
+				(void) alarm((unsigned) timeout);
+				reply(200,
+				    "Maximum IDLE time set to %d seconds",
+				    timeout);
+			}
+		}
+	| STOU check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				store($4, "w", 1);
+			if ($4 != NULL)
+				free($4);
+		}
+	| SYST CRLF
+		{
+#ifdef __APPLE__
+			reply(215, "BSD Type: L%d", NBBY);
+#else
+#if defined(unix)
+#ifdef BSD
+			reply(215, "UNIX Type: L%d Version: BSD-%d", NBBY, BSD);
+#else /* BSD */
+			reply(215, "UNIX Type: L%d", NBBY);
+#endif /* BSD */
+#else /* unix */
+			reply(215, "UNKNOWN Type: L%d", NBBY);
+#endif /* unix */
+#endif /* __APPLE__ */
+		}
+
+		/*
+		 * SIZE is not in RFC959, but Postel has blessed it and
+		 * it will be in the updated RFC.
+		 *
+		 * Return size of file in a format suitable for
+		 * using with RESTART (we just count bytes).
+		 */
+	| SIZE check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL)
+				sizecmd($4);
+			if ($4 != NULL)
+				free($4);
+		}
+
+		/*
+		 * MDTM is not in RFC959, but Postel has blessed it and
+		 * it will be in the updated RFC.
+		 *
+		 * Return modification time of file as an ISO 3307
+		 * style time. E.g. YYYYMMDDHHMMSS or YYYYMMDDHHMMSS.xxx
+		 * where xxx is the fractional second (of any precision,
+		 * not necessarily 3 digits)
+		 */
+	| MDTM check_login SP pathname CRLF
+		{
+			if ($2 && $4 != NULL) {
+				struct stat stbuf;
+				if (stat($4, &stbuf) < 0)
+					reply(550, "%s: %s",
+					    $4, strerror(errno));
+				else if (!S_ISREG(stbuf.st_mode)) {
+					reply(550, "%s: not a plain file.", $4);
+				} else {
+					struct tm *t;
+					t = gmtime(&stbuf.st_mtime);
+					reply(213,
+					    "%04d%02d%02d%02d%02d%02d",
+					    1900+t->tm_year, t->tm_mon+1, t->tm_mday,
+					    t->tm_hour, t->tm_min, t->tm_sec);
+				}
+			}
+			if ($4 != NULL)
+				free($4);
+		}
+	| QUIT CRLF
+		{
+			reply(221, "Goodbye.");
+			dologout(0);
+		}
+	| error CRLF
+		{
+			yyerrok;
+		}
+	;
+rcmd
+	: RNFR check_login SP pathname CRLF
+		{
+			char *renamefrom();
+
+			restart_point = (off_t) 0;
+			if ($2 && $4) {
+				fromname = renamefrom($4);
+				if (fromname == (char *) 0 && $4) {
+					free($4);
+				}
+			}
+		}
+	| REST SP byte_size CRLF
+		{
+			fromname = (char *) 0;
+			restart_point = $3;	/* XXX $3 is only "int" */
+			reply(350, "Restarting at %qd. %s", restart_point,
+			    "Send STORE or RETRIEVE to initiate transfer.");
+		}
+	;
+
+username
+	: STRING
+	;
+
+password
+	: /* empty */
+		{
+			$$ = (char *)calloc(1, sizeof(char));
+		}
+	| STRING
+	;
+
+byte_size
+	: NUMBER
+	;
+
+host_port
+	: NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
+		NUMBER COMMA NUMBER
+		{
+			char *a, *p;
+
+			a = (char *)&data_dest.sin_addr;
+			a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
+			p = (char *)&data_dest.sin_port;
+			p[0] = $9; p[1] = $11;
+			data_dest.sin_family = AF_INET;
+		}
+	;
+
+form_code
+	: N
+		{
+			$$ = FORM_N;
+		}
+	| T
+		{
+			$$ = FORM_T;
+		}
+	| C
+		{
+			$$ = FORM_C;
+		}
+	;
+
+type_code
+	: A
+		{
+			cmd_type = TYPE_A;
+			cmd_form = FORM_N;
+		}
+	| A SP form_code
+		{
+			cmd_type = TYPE_A;
+			cmd_form = $3;
+		}
+	| E
+		{
+			cmd_type = TYPE_E;
+			cmd_form = FORM_N;
+		}
+	| E SP form_code
+		{
+			cmd_type = TYPE_E;
+			cmd_form = $3;
+		}
+	| I
+		{
+			cmd_type = TYPE_I;
+		}
+	| L
+		{
+			cmd_type = TYPE_L;
+			cmd_bytesz = NBBY;
+		}
+	| L SP byte_size
+		{
+			cmd_type = TYPE_L;
+			cmd_bytesz = $3;
+		}
+		/* this is for a bug in the BBN ftp */
+	| L byte_size
+		{
+			cmd_type = TYPE_L;
+			cmd_bytesz = $2;
+		}
+	;
+
+struct_code
+	: F
+		{
+			$$ = STRU_F;
+		}
+	| R
+		{
+			$$ = STRU_R;
+		}
+	| P
+		{
+			$$ = STRU_P;
+		}
+	;
+
+mode_code
+	: S
+		{
+			$$ = MODE_S;
+		}
+	| B
+		{
+			$$ = MODE_B;
+		}
+	| C
+		{
+			$$ = MODE_C;
+		}
+	;
+
+pathname
+	: pathstring
+		{
+			/*
+			 * Problem: this production is used for all pathname
+			 * processing, but only gives a 550 error reply.
+			 * This is a valid reply in some cases but not in others.
+			 */
+			if (logged_in && $1 && *$1 == '~') {
+				glob_t gl;
+				int flags =
+				 GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+
+				memset(&gl, 0, sizeof(gl));
+				if (glob($1, flags, NULL, &gl) ||
+				    gl.gl_pathc == 0) {
+					reply(550, "not found");
+					$$ = NULL;
+				} else {
+					$$ = strdup(gl.gl_pathv[0]);
+				}
+				globfree(&gl);
+				free($1);
+			} else
+				$$ = $1;
+		}
+	;
+
+pathstring
+	: STRING
+	;
+
+octal_number
+	: NUMBER
+		{
+			int ret, dec, multby, digit;
+
+			/*
+			 * Convert a number that was read as decimal number
+			 * to what it would be if it had been read as octal.
+			 */
+			dec = $1;
+			multby = 1;
+			ret = 0;
+			while (dec) {
+				digit = dec%10;
+				if (digit > 7) {
+					ret = -1;
+					break;
+				}
+				ret += digit * multby;
+				multby *= 8;
+				dec /= 10;
+			}
+			$$ = ret;
+		}
+	;
+
+
+check_login
+	: /* empty */
+		{
+			if (logged_in)
+				$$ = 1;
+			else {
+				reply(530, "Please login with USER and PASS.");
+				$$ = 0;
+			}
+		}
+	;
+
+%%
+
+extern jmp_buf errcatch;
+
+#define	CMD	0	/* beginning of command */
+#define	ARGS	1	/* expect miscellaneous arguments */
+#define	STR1	2	/* expect SP followed by STRING */
+#define	STR2	3	/* expect STRING */
+#define	OSTR	4	/* optional SP then STRING */
+#define	ZSTR1	5	/* SP then optional STRING */
+#define	ZSTR2	6	/* optional STRING after SP */
+#define	SITECMD	7	/* SITE command */
+#define	NSTR	8	/* Number followed by a string */
+
+struct tab {
+	char	*name;
+	short	token;
+	short	state;
+	short	implemented;	/* 1 if command is implemented */
+	char	*help;
+};
+
+struct tab cmdtab[] = {		/* In order defined in RFC 765 */
+	{ "USER", USER, STR1, 1,	"<sp> username" },
+	{ "PASS", PASS, ZSTR1, 1,	"<sp> password" },
+	{ "ACCT", ACCT, STR1, 0,	"(specify account)" },
+	{ "SMNT", SMNT, ARGS, 0,	"(structure mount)" },
+	{ "REIN", REIN, ARGS, 0,	"(reinitialize server state)" },
+	{ "QUIT", QUIT, ARGS, 1,	"(terminate service)", },
+	{ "PORT", PORT, ARGS, 1,	"<sp> b0, b1, b2, b3, b4" },
+	{ "PASV", PASV, ARGS, 1,	"(set server in passive mode)" },
+	{ "TYPE", TYPE, ARGS, 1,	"<sp> [ A | E | I | L ]" },
+	{ "STRU", STRU, ARGS, 1,	"(specify file structure)" },
+	{ "MODE", MODE, ARGS, 1,	"(specify transfer mode)" },
+	{ "RETR", RETR, STR1, 1,	"<sp> file-name" },
+	{ "STOR", STOR, STR1, 1,	"<sp> file-name" },
+	{ "APPE", APPE, STR1, 1,	"<sp> file-name" },
+	{ "MLFL", MLFL, OSTR, 0,	"(mail file)" },
+	{ "MAIL", MAIL, OSTR, 0,	"(mail to user)" },
+	{ "MSND", MSND, OSTR, 0,	"(mail send to terminal)" },
+	{ "MSOM", MSOM, OSTR, 0,	"(mail send to terminal or mailbox)" },
+	{ "MSAM", MSAM, OSTR, 0,	"(mail send to terminal and mailbox)" },
+	{ "MRSQ", MRSQ, OSTR, 0,	"(mail recipient scheme question)" },
+	{ "MRCP", MRCP, STR1, 0,	"(mail recipient)" },
+	{ "ALLO", ALLO, ARGS, 1,	"allocate storage (vacuously)" },
+	{ "REST", REST, ARGS, 1,	"<sp> offset (restart command)" },
+	{ "RNFR", RNFR, STR1, 1,	"<sp> file-name" },
+	{ "RNTO", RNTO, STR1, 1,	"<sp> file-name" },
+	{ "ABOR", ABOR, ARGS, 1,	"(abort operation)" },
+	{ "DELE", DELE, STR1, 1,	"<sp> file-name" },
+	{ "CWD",  CWD,  OSTR, 1,	"[ <sp> directory-name ]" },
+	{ "XCWD", CWD,	OSTR, 1,	"[ <sp> directory-name ]" },
+	{ "LIST", LIST, OSTR, 1,	"[ <sp> path-name ]" },
+	{ "NLST", NLST, OSTR, 1,	"[ <sp> path-name ]" },
+	{ "SITE", SITE, SITECMD, 1,	"site-cmd [ <sp> arguments ]" },
+	{ "SYST", SYST, ARGS, 1,	"(get type of operating system)" },
+	{ "STAT", STAT, OSTR, 1,	"[ <sp> path-name ]" },
+	{ "HELP", HELP, OSTR, 1,	"[ <sp> <string> ]" },
+	{ "NOOP", NOOP, ARGS, 1,	"" },
+	{ "MKD",  MKD,  STR1, 1,	"<sp> path-name" },
+	{ "XMKD", MKD,  STR1, 1,	"<sp> path-name" },
+	{ "RMD",  RMD,  STR1, 1,	"<sp> path-name" },
+	{ "XRMD", RMD,  STR1, 1,	"<sp> path-name" },
+	{ "PWD",  PWD,  ARGS, 1,	"(return current directory)" },
+	{ "XPWD", PWD,  ARGS, 1,	"(return current directory)" },
+	{ "CDUP", CDUP, ARGS, 1,	"(change to parent directory)" },
+	{ "XCUP", CDUP, ARGS, 1,	"(change to parent directory)" },
+	{ "STOU", STOU, STR1, 1,	"<sp> file-name" },
+	{ "SIZE", SIZE, OSTR, 1,	"<sp> path-name" },
+	{ "MDTM", MDTM, OSTR, 1,	"<sp> path-name" },
+	{ NULL,   0,    0,    0,	0 }
+};
+
+struct tab sitetab[] = {
+	{ "UMASK", UMASK, ARGS, 1,	"[ <sp> umask ]" },
+	{ "IDLE", IDLE, ARGS, 1,	"[ <sp> maximum-idle-time ]" },
+	{ "CHMOD", CHMOD, NSTR, 1,	"<sp> mode <sp> file-name" },
+	{ "HELP", HELP, OSTR, 1,	"[ <sp> <string> ]" },
+	{ NULL,   0,    0,    0,	0 }
+};
+
+static char	*copy __P((char *));
+static void	 help __P((struct tab *, char *));
+static struct tab *
+		 lookup __P((struct tab *, char *));
+static void	 sizecmd __P((char *));
+static void	 toolong __P((int));
+static int	 yylex __P((void));
+
+static struct tab *
+lookup(p, cmd)
+	struct tab *p;
+	char *cmd;
+{
+
+	for (; p->name != NULL; p++)
+		if (strcmp(cmd, p->name) == 0)
+			return (p);
+	return (0);
+}
+
+#include <arpa/telnet.h>
+
+/*
+ * getline - a hacked up version of fgets to ignore TELNET escape codes.
+ */
+char *
+getline(s, n, iop)
+	char *s;
+	int n;
+	FILE *iop;
+{
+	int c;
+	register char *cs;
+
+	cs = s;
+/* tmpline may contain saved command from urgent mode interruption */
+	for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
+		*cs++ = tmpline[c];
+		if (tmpline[c] == '\n') {
+			*cs++ = '\0';
+			if (debug)
+				syslog(LOG_DEBUG, "command: %s", s);
+			tmpline[0] = '\0';
+			return(s);
+		}
+		if (c == 0)
+			tmpline[0] = '\0';
+	}
+	while ((c = getc(iop)) != EOF) {
+		c &= 0377;
+		if (c == IAC) {
+		    if ((c = getc(iop)) != EOF) {
+			c &= 0377;
+			switch (c) {
+			case WILL:
+			case WONT:
+				c = getc(iop);
+				printf("%c%c%c", IAC, DONT, 0377&c);
+				(void) fflush(stdout);
+				continue;
+			case DO:
+			case DONT:
+				c = getc(iop);
+				printf("%c%c%c", IAC, WONT, 0377&c);
+				(void) fflush(stdout);
+				continue;
+			case IAC:
+				break;
+			default:
+				continue;	/* ignore command */
+			}
+		    }
+		}
+		*cs++ = c;
+		if (--n <= 0 || c == '\n')
+			break;
+	}
+	if (c == EOF && cs == s)
+		return (NULL);
+	*cs++ = '\0';
+	if (debug) {
+		if (!guest && strncasecmp("pass ", s, 5) == 0) {
+			/* Don't syslog passwords */
+			syslog(LOG_DEBUG, "command: %.5s ???", s);
+		} else {
+			register char *cp;
+			register int len;
+
+			/* Don't syslog trailing CR-LF */
+			len = strlen(s);
+			cp = s + len - 1;
+			while (cp >= s && (*cp == '\n' || *cp == '\r')) {
+				--cp;
+				--len;
+			}
+			syslog(LOG_DEBUG, "command: %.*s", len, s);
+		}
+	}
+	return (s);
+}
+
+static void
+toolong(signo)
+	int signo;
+{
+
+	reply(421,
+	    "Timeout (%d seconds): closing control connection.", timeout);
+	if (logging)
+		syslog(LOG_INFO, "User %s timed out after %d seconds",
+		    (pw ? pw -> pw_name : "unknown"), timeout);
+	dologout(1);
+}
+
+static int
+yylex()
+{
+	static int cpos, state;
+	char *cp, *cp2;
+	struct tab *p;
+	int n;
+	char c;
+
+	for (;;) {
+		switch (state) {
+
+		case CMD:
+			(void) signal(SIGALRM, toolong);
+			(void) alarm((unsigned) timeout);
+			if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
+				reply(221, "You could at least say goodbye.");
+				dologout(0);
+			}
+			(void) alarm(0);
+#ifdef SETPROCTITLE
+			if (strncasecmp(cbuf, "PASS", 4) != NULL)
+				setproctitle("%s: %s", proctitle, cbuf);
+#endif /* SETPROCTITLE */
+			if ((cp = strchr(cbuf, '\r'))) {
+				*cp++ = '\n';
+				*cp = '\0';
+			}
+			if ((cp = strpbrk(cbuf, " \n")))
+				cpos = cp - cbuf;
+			if (cpos == 0)
+				cpos = 4;
+			c = cbuf[cpos];
+			cbuf[cpos] = '\0';
+			upper(cbuf);
+			p = lookup(cmdtab, cbuf);
+			cbuf[cpos] = c;
+			if (p != 0) {
+				if (p->implemented == 0) {
+					nack(p->name);
+					longjmp(errcatch,0);
+					/* NOTREACHED */
+				}
+				state = p->state;
+				yylval.s = p->name;
+				return (p->token);
+			}
+			break;
+
+		case SITECMD:
+			if (cbuf[cpos] == ' ') {
+				cpos++;
+				return (SP);
+			}
+			cp = &cbuf[cpos];
+			if ((cp2 = strpbrk(cp, " \n")))
+				cpos = cp2 - cbuf;
+			c = cbuf[cpos];
+			cbuf[cpos] = '\0';
+			upper(cp);
+			p = lookup(sitetab, cp);
+			cbuf[cpos] = c;
+			if (p != 0) {
+				if (p->implemented == 0) {
+					state = CMD;
+					nack(p->name);
+					longjmp(errcatch,0);
+					/* NOTREACHED */
+				}
+				state = p->state;
+				yylval.s = p->name;
+				return (p->token);
+			}
+			state = CMD;
+			break;
+
+		case OSTR:
+			if (cbuf[cpos] == '\n') {
+				state = CMD;
+				return (CRLF);
+			}
+			/* FALLTHROUGH */
+
+		case STR1:
+		case ZSTR1:
+		dostr1:
+			if (cbuf[cpos] == ' ') {
+				cpos++;
+				state = state == OSTR ? STR2 : ++state;
+				return (SP);
+			}
+			break;
+
+		case ZSTR2:
+			if (cbuf[cpos] == '\n') {
+				state = CMD;
+				return (CRLF);
+			}
+			/* FALLTHROUGH */
+
+		case STR2:
+			cp = &cbuf[cpos];
+			n = strlen(cp);
+			cpos += n - 1;
+			/*
+			 * Make sure the string is nonempty and \n terminated.
+			 */
+			if (n > 1 && cbuf[cpos] == '\n') {
+				cbuf[cpos] = '\0';
+				yylval.s = copy(cp);
+				cbuf[cpos] = '\n';
+				state = ARGS;
+				return (STRING);
+			}
+			break;
+
+		case NSTR:
+			if (cbuf[cpos] == ' ') {
+				cpos++;
+				return (SP);
+			}
+			if (isdigit(cbuf[cpos])) {
+				cp = &cbuf[cpos];
+				while (isdigit(cbuf[++cpos]))
+					;
+				c = cbuf[cpos];
+				cbuf[cpos] = '\0';
+				yylval.i = atoi(cp);
+				cbuf[cpos] = c;
+				state = STR1;
+				return (NUMBER);
+			}
+			state = STR1;
+			goto dostr1;
+
+		case ARGS:
+			if (isdigit(cbuf[cpos])) {
+				cp = &cbuf[cpos];
+				while (isdigit(cbuf[++cpos]))
+					;
+				c = cbuf[cpos];
+				cbuf[cpos] = '\0';
+				yylval.i = atoi(cp);
+				cbuf[cpos] = c;
+				return (NUMBER);
+			}
+			switch (cbuf[cpos++]) {
+
+			case '\n':
+				state = CMD;
+				return (CRLF);
+
+			case ' ':
+				return (SP);
+
+			case ',':
+				return (COMMA);
+
+			case 'A':
+			case 'a':
+				return (A);
+
+			case 'B':
+			case 'b':
+				return (B);
+
+			case 'C':
+			case 'c':
+				return (C);
+
+			case 'E':
+			case 'e':
+				return (E);
+
+			case 'F':
+			case 'f':
+				return (F);
+
+			case 'I':
+			case 'i':
+				return (I);
+
+			case 'L':
+			case 'l':
+				return (L);
+
+			case 'N':
+			case 'n':
+				return (N);
+
+			case 'P':
+			case 'p':
+				return (P);
+
+			case 'R':
+			case 'r':
+				return (R);
+
+			case 'S':
+			case 's':
+				return (S);
+
+			case 'T':
+			case 't':
+				return (T);
+
+			}
+			break;
+
+		default:
+			fatal("Unknown state in scanner.");
+		}
+		yyerror((char *) 0);
+		state = CMD;
+		longjmp(errcatch,0);
+	}
+}
+
+void
+upper(s)
+	char *s;
+{
+	while (*s != '\0') {
+		if (islower(*s))
+			*s = toupper(*s);
+		s++;
+	}
+}
+
+static char *
+copy(s)
+	char *s;
+{
+	char *p;
+
+	p = malloc((unsigned) strlen(s) + 1);
+	if (p == NULL)
+		fatal("Ran out of memory.");
+	(void) strcpy(p, s);
+	return (p);
+}
+
+static void
+help(ctab, s)
+	struct tab *ctab;
+	char *s;
+{
+	struct tab *c;
+	int width, NCMDS;
+	char *type;
+
+	if (ctab == sitetab)
+		type = "SITE ";
+	else
+		type = "";
+	width = 0, NCMDS = 0;
+	for (c = ctab; c->name != NULL; c++) {
+		int len = strlen(c->name);
+
+		if (len > width)
+			width = len;
+		NCMDS++;
+	}
+	width = (width + 8) &~ 7;
+	if (s == 0) {
+		int i, j, w;
+		int columns, lines;
+
+		lreply(214, "The following %scommands are recognized %s.",
+		    type, "(* =>'s unimplemented)");
+		columns = 76 / width;
+		if (columns == 0)
+			columns = 1;
+		lines = (NCMDS + columns - 1) / columns;
+		for (i = 0; i < lines; i++) {
+			printf("   ");
+			for (j = 0; j < columns; j++) {
+				c = ctab + j * lines + i;
+				printf("%s%c", c->name,
+					c->implemented ? ' ' : '*');
+				if (c + lines >= &ctab[NCMDS])
+					break;
+				w = strlen(c->name) + 1;
+				while (w < width) {
+					putchar(' ');
+					w++;
+				}
+			}
+			printf("\r\n");
+		}
+		(void) fflush(stdout);
+		reply(214, "Direct comments to ftp-bugs@%s.", hostname);
+		return;
+	}
+	upper(s);
+	c = lookup(ctab, s);
+	if (c == (struct tab *)0) {
+		reply(502, "Unknown command %s.", s);
+		return;
+	}
+	if (c->implemented)
+		reply(214, "Syntax: %s%s %s", type, c->name, c->help);
+	else
+		reply(214, "%s%-*s\t%s; unimplemented.", type, width,
+		    c->name, c->help);
+}
+
+static void
+sizecmd(filename)
+	char *filename;
+{
+	switch (type) {
+	case TYPE_L:
+	case TYPE_I: {
+		struct stat stbuf;
+		if (stat(filename, &stbuf) < 0 || !S_ISREG(stbuf.st_mode))
+			reply(550, "%s: not a plain file.", filename);
+		else
+			reply(213, "%qu", stbuf.st_size);
+		break; }
+	case TYPE_A: {
+		FILE *fin;
+		int c;
+		off_t count;
+		struct stat stbuf;
+		fin = fopen(filename, "r");
+		if (fin == NULL) {
+			perror_reply(550, filename);
+			return;
+		}
+		if (fstat(fileno(fin), &stbuf) < 0 || !S_ISREG(stbuf.st_mode)) {
+			reply(550, "%s: not a plain file.", filename);
+			(void) fclose(fin);
+			return;
+		}
+
+		count = 0;
+		while((c=getc(fin)) != EOF) {
+			if (c == '\n')	/* will get expanded to \r\n */
+				count++;
+			count++;
+		}
+		(void) fclose(fin);
+
+		reply(213, "%qd", count);
+		break; }
+	default:
+		reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
+	}
+}
diff --git a/ftpd.tproj/ftpd.8 b/ftpd.tproj/ftpd.8
new file mode 100644
index 0000000..eb93c38
--- /dev/null
+++ b/ftpd.tproj/ftpd.8
@@ -0,0 +1,291 @@
+.\" Copyright (c) 1985, 1988, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)ftpd.8	8.3 (Berkeley) 6/1/94
+.\"
+.Dd June 1, 1994
+.Dt FTPD 8
+.Os BSD 4.2
+.Sh NAME
+.Nm ftpd
+.Nd
+Internet File Transfer Protocol server
+.Sh SYNOPSIS
+.Nm ftpd
+.Op Fl dl
+.Op Fl T Ar maxtimeout
+.Op Fl t Ar timeout
+.Sh DESCRIPTION
+.Nm Ftpd
+is the
+Internet File Transfer Protocol
+server process.  The server uses the
+.Tn TCP
+protocol
+and listens at the port specified in the
+.Dq ftp
+service specification; see
+.Xr services 5 .
+.Pp
+Available options:
+.Bl -tag -width Ds
+.It Fl d
+Debugging information is written to the syslog using LOG_FTP.
+.It Fl l
+Each successful and failed 
+.Xr ftp 1
+session is logged using syslog with a facility of LOG_FTP.
+If this option is specified twice, the retrieve (get), store (put), append,
+delete, make directory, remove directory and rename operations and
+their filename arguments are also logged.
+.It Fl T
+A client may also request a different timeout period;
+the maximum period allowed may be set to
+.Ar timeout
+seconds with the
+.Fl T
+option.
+The default limit is 2 hours.
+.It Fl t
+The inactivity timeout period is set to
+.Ar timeout
+seconds (the default is 15 minutes).
+.El
+.Pp
+The file
+.Pa /etc/nologin
+can be used to disable ftp access.
+If the file exists,
+.Nm
+displays it and exits.
+If the file
+.Pa /etc/ftpwelcome
+exists,
+.Nm
+prints it before issuing the 
+.Dq ready
+message.
+If the file
+.Pa /etc/motd
+exists,
+.Nm
+prints it after a successful login.
+.Pp
+The ftp server currently supports the following ftp requests.
+The case of the requests is ignored.
+.Bl -column "Request" -offset indent
+.It Request Ta "Description"
+.It ABOR Ta "abort previous command"
+.It ACCT Ta "specify account (ignored)"
+.It ALLO Ta "allocate storage (vacuously)"
+.It APPE Ta "append to a file"
+.It CDUP Ta "change to parent of current working directory"
+.It CWD Ta "change working directory"
+.It DELE Ta "delete a file"
+.It HELP Ta "give help information"
+.It LIST Ta "give list files in a directory" Pq Dq Li "ls -lgA"
+.It MKD Ta "make a directory"
+.It MDTM Ta "show last modification time of file"
+.It MODE Ta "specify data transfer" Em mode
+.It NLST Ta "give name list of files in directory"
+.It NOOP Ta "do nothing"
+.It PASS Ta "specify password"
+.It PASV Ta "prepare for server-to-server transfer"
+.It PORT Ta "specify data connection port"
+.It PWD Ta "print the current working directory"
+.It QUIT Ta "terminate session"
+.It REST Ta "restart incomplete transfer"
+.It RETR Ta "retrieve a file"
+.It RMD Ta "remove a directory"
+.It RNFR Ta "specify rename-from file name"
+.It RNTO Ta "specify rename-to file name"
+.It SITE Ta "non-standard commands (see next section)"
+.It SIZE Ta "return size of file"
+.It STAT Ta "return status of server"
+.It STOR Ta "store a file"
+.It STOU Ta "store a file with a unique name"
+.It STRU Ta "specify data transfer" Em structure
+.It SYST Ta "show operating system type of server system"
+.It TYPE Ta "specify data transfer" Em type
+.It USER Ta "specify user name"
+.It XCUP Ta "change to parent of current working directory (deprecated)"
+.It XCWD Ta "change working directory (deprecated)"
+.It XMKD Ta "make a directory (deprecated)"
+.It XPWD Ta "print the current working directory (deprecated)"
+.It XRMD Ta "remove a directory (deprecated)"
+.El
+.Pp
+The following non-standard or
+.Tn UNIX
+specific commands are supported
+by the
+SITE request.
+.Pp
+.Bl -column Request -offset indent
+.It Sy Request Ta Sy Description
+.It UMASK Ta change umask, e.g. ``SITE UMASK 002''
+.It IDLE Ta set idle-timer, e.g. ``SITE IDLE 60''
+.It CHMOD Ta change mode of a file, e.g. ``SITE CHMOD 755 filename''
+.It HELP Ta give help information.
+.El
+.Pp
+The remaining ftp requests specified in Internet RFC 959
+are
+recognized, but not implemented.
+MDTM and SIZE are not specified in RFC 959, but will appear in the
+next updated FTP RFC.
+.Pp
+The ftp server will abort an active file transfer only when the
+ABOR
+command is preceded by a Telnet "Interrupt Process" (IP)
+signal and a Telnet "Synch" signal in the command Telnet stream,
+as described in Internet RFC 959.
+If a
+STAT
+command is received during a data transfer, preceded by a Telnet IP
+and Synch, transfer status will be returned.
+.Pp
+.Nm Ftpd
+interprets file names according to the
+.Dq globbing
+conventions used by
+.Xr csh 1 .
+This allows users to utilize the metacharacters
+.Dq Li \&*?[]{}~ .
+.Pp
+.Nm Ftpd
+authenticates users according to three rules. 
+.Pp
+.Bl -enum -offset indent
+.It
+The login name must be in the password data base,
+.Pa /etc/passwd ,
+and not have a null password.
+In this case a password must be provided by the client before any
+file operations may be performed.
+.It
+The login name must not appear in the file
+.Pa /etc/ftpusers .
+.It
+The user must have a standard shell returned by 
+.Xr getusershell 3 .
+.It
+If the user name is
+.Dq anonymous
+or
+.Dq ftp ,
+an
+anonymous ftp account must be present in the password
+file (user
+.Dq ftp ) .
+In this case the user is allowed
+to log in by specifying any password (by convention an email address for
+the user should be used as the password).
+.El
+.Pp
+In the last case, 
+.Nm ftpd
+takes special measures to restrict the client's access privileges.
+The server performs a 
+.Xr chroot 2
+to the home directory of the
+.Dq ftp
+user.
+In order that system security is not breached, it is recommended
+that the
+.Dq ftp
+subtree be constructed with care, following these rules:
+.Bl -tag -width "~ftp/pub" -offset indent
+.It Pa ~ftp
+Make the home directory owned by
+.Dq root
+and unwritable by anyone.
+.ne 1i
+.It Pa ~ftp/bin
+Make this directory owned by
+.Dq root
+and unwritable by anyone (mode 555).
+The program
+.Xr ls 1
+must be present to support the list command.
+This program should be mode 111.
+.It Pa ~ftp/etc
+Make this directory owned by
+.Dq root
+and unwritable by anyone (mode 555).
+The files
+.Xr passwd 5
+and
+.Xr group 5
+must be present for the 
+.Xr ls
+command to be able to produce owner names rather than numbers.
+The password field in
+.Xr passwd
+is not used, and should not contain real passwords.
+The file
+.Pa motd ,
+if present, will be printed after a successful login.
+These files should be mode 444.
+.It Pa ~ftp/pub
+Make this directory mode 777 and owned by
+.Dq ftp .
+Guests
+can then place files which are to be accessible via the anonymous
+account in this directory.
+.El
+.Sh FILES
+.Bl -tag -width /etc/ftpwelcome -compact
+.It Pa /etc/ftpusers
+List of unwelcome/restricted users.
+.It Pa /etc/ftpwelcome
+Welcome notice.
+.It Pa /etc/motd
+Welcome notice after login.
+.It Pa /etc/nologin
+Displayed and access refused.
+.El
+.Sh SEE ALSO
+.Xr ftp 1 ,
+.Xr getusershell 3 ,
+.Xr syslogd 8
+.Sh BUGS
+The server must run as the super-user
+to create sockets with privileged port numbers.  It maintains
+an effective user id of the logged in user, reverting to
+the super-user only when binding addresses to sockets.  The
+possible security holes have been extensively
+scrutinized, but are possibly incomplete.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/ftpd.tproj/ftpd.c b/ftpd.tproj/ftpd.c
new file mode 100644
index 0000000..4071f02
--- /dev/null
+++ b/ftpd.tproj/ftpd.c
@@ -0,0 +1,1686 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)ftpd.c	8.5 (Berkeley) 4/28/95";
+#endif /* not lint */
+
+/* XXX this is to get around a compiler bug with long long's on ppc */
+#pragma CC_OPT_OFF
+
+/*
+ * FTP server.
+ */
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#define	FTP_NAMES
+#include <arpa/ftp.h>
+#include <arpa/inet.h>
+#include <arpa/telnet.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <glob.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "pathnames.h"
+#include "extern.h"
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+static char version[] = "Version 6.00";
+
+extern	off_t restart_point;
+extern	char cbuf[];
+
+struct	sockaddr_in ctrl_addr;
+struct	sockaddr_in data_source;
+struct	sockaddr_in data_dest;
+struct	sockaddr_in his_addr;
+struct	sockaddr_in pasv_addr;
+
+int	data;
+jmp_buf	errcatch, urgcatch;
+int	logged_in;
+struct	passwd *pw;
+int	debug;
+int	timeout = 900;    /* timeout after 15 minutes of inactivity */
+int	maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
+int	logging;
+int	guest;
+int	type;
+int	form;
+int	stru;			/* avoid C keyword */
+int	mode;
+int	usedefault = 1;		/* for data transfers */
+int	pdata = -1;		/* for passive mode */
+sig_atomic_t transflag;
+off_t	file_size;
+off_t	byte_count;
+#if !defined(CMASK) || CMASK == 0
+#undef CMASK
+#define CMASK 027
+#endif
+int	defumask = CMASK;		/* default umask value */
+char	tmpline[7];
+char	hostname[MAXHOSTNAMELEN];
+char	remotehost[MAXHOSTNAMELEN];
+
+/*
+ * Timeout intervals for retrying connections
+ * to hosts that don't accept PORT cmds.  This
+ * is a kludge, but given the problems with TCP...
+ */
+#define	SWAITMAX	90	/* wait at most 90 seconds */
+#define	SWAITINT	5	/* interval between retries */
+
+int	swaitmax = SWAITMAX;
+int	swaitint = SWAITINT;
+
+#ifdef SETPROCTITLE
+char	**Argv = NULL;		/* pointer to argument vector */
+char	*LastArgv = NULL;	/* end of argv */
+char	proctitle[LINE_MAX];	/* initial part of title */
+#endif /* SETPROCTITLE */
+
+#define LOGCMD(cmd, file) \
+	if (logging > 1) \
+	    syslog(LOG_INFO,"%s %s%s", cmd, \
+		*(file) == '/' ? "" : curdir(), file);
+#define LOGCMD2(cmd, file1, file2) \
+	 if (logging > 1) \
+	    syslog(LOG_INFO,"%s %s%s %s%s", cmd, \
+		*(file1) == '/' ? "" : curdir(), file1, \
+		*(file2) == '/' ? "" : curdir(), file2);
+#define LOGBYTES(cmd, file, cnt) \
+	if (logging > 1) { \
+		if (cnt == (off_t)-1) \
+		    syslog(LOG_INFO,"%s %s%s", cmd, \
+			*(file) == '/' ? "" : curdir(), file); \
+		else \
+		    syslog(LOG_INFO, "%s %s%s = %qd bytes", \
+			cmd, (*(file) == '/') ? "" : curdir(), file, cnt); \
+	}
+
+static void	 ack __P((char *));
+static void	 myoob __P((int));
+static int	 checkuser __P((char *));
+static FILE	*dataconn __P((char *, off_t, char *));
+static void	 dolog __P((struct sockaddr_in *));
+static char	*curdir __P((void));
+static void	 end_login __P((void));
+static FILE	*getdatasock __P((char *));
+static char	*gunique __P((char *));
+static void	 lostconn __P((int));
+static int	 receive_data __P((FILE *, FILE *));
+static void	 send_data __P((FILE *, FILE *, off_t));
+static struct passwd *
+		 sgetpwnam __P((char *));
+static char	*sgetsave __P((char *));
+
+static char *
+curdir()
+{
+	static char path[MAXPATHLEN+1+1];	/* path + '/' + '\0' */
+
+	if (getcwd(path, sizeof(path)-2) == NULL)
+		return ("");
+	if (path[1] != '\0')		/* special case for root dir. */
+		strcat(path, "/");
+	/* For guest account, skip / since it's chrooted */
+	return (guest ? path+1 : path);
+}
+
+int
+main(argc, argv, envp)
+	int argc;
+	char *argv[];
+	char **envp;
+{
+	int addrlen, ch, on = 1, tos;
+	char *cp, line[LINE_MAX];
+	FILE *fd;
+
+	/*
+	 * LOG_NDELAY sets up the logging connection immediately,
+	 * necessary for anonymous ftp's that chroot and can't do it later.
+	 */
+	openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
+	addrlen = sizeof(his_addr);
+	if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
+		syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
+		exit(1);
+	}
+	addrlen = sizeof(ctrl_addr);
+	if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
+		syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
+		exit(1);
+	}
+#ifdef IP_TOS
+	tos = IPTOS_LOWDELAY;
+	if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
+		syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
+#endif
+	data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1);
+	debug = 0;
+#ifdef SETPROCTITLE
+	/*
+	 *  Save start and extent of argv for setproctitle.
+	 */
+	Argv = argv;
+	while (*envp)
+		envp++;
+	LastArgv = envp[-1] + strlen(envp[-1]);
+#endif /* SETPROCTITLE */
+
+	while ((ch = getopt(argc, argv, "dlt:T:u:v")) != -1) {
+		switch (ch) {
+		case 'd':
+			debug = 1;
+			break;
+
+		case 'l':
+			logging++;	/* > 1 == extra logging */
+			break;
+
+		case 't':
+			timeout = atoi(optarg);
+			if (maxtimeout < timeout)
+				maxtimeout = timeout;
+			break;
+
+		case 'T':
+			maxtimeout = atoi(optarg);
+			if (timeout > maxtimeout)
+				timeout = maxtimeout;
+			break;
+
+		case 'u':
+		    {
+			long val = 0;
+
+			val = strtol(optarg, &optarg, 8);
+			if (*optarg != '\0' || val < 0)
+				warnx("bad value for -u");
+			else
+				defumask = val;
+			break;
+		    }
+
+		case 'v':
+			debug = 1;
+			break;
+
+		default:
+			warnx("unknown flag -%c ignored", optopt);
+			break;
+		}
+	}
+	(void) freopen(_PATH_DEVNULL, "w", stderr);
+	(void) signal(SIGPIPE, lostconn);
+	(void) signal(SIGCHLD, SIG_IGN);
+	if ((int)signal(SIGURG, myoob) < 0)
+		syslog(LOG_ERR, "signal: %m");
+
+	/* Try to handle urgent data inline */
+#ifdef SO_OOBINLINE
+	if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0)
+		syslog(LOG_ERR, "setsockopt: %m");
+#endif
+
+#ifdef	F_SETOWN
+	if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
+		syslog(LOG_ERR, "fcntl F_SETOWN: %m");
+#endif
+	dolog(&his_addr);
+	/*
+	 * Set up default state
+	 */
+	data = -1;
+	type = TYPE_A;
+	form = FORM_N;
+	stru = STRU_F;
+	mode = MODE_S;
+	tmpline[0] = '\0';
+
+	/* If logins are disabled, print out the message. */
+	if ((fd = fopen(_PATH_NOLOGIN,"r")) != NULL) {
+		while (fgets(line, sizeof(line), fd) != NULL) {
+			if ((cp = strchr(line, '\n')) != NULL)
+				*cp = '\0';
+			lreply(530, "%s", line);
+		}
+		(void) fflush(stdout);
+		(void) fclose(fd);
+		reply(530, "System not available.");
+		exit(0);
+	}
+	if ((fd = fopen(_PATH_FTPWELCOME, "r")) != NULL) {
+		while (fgets(line, sizeof(line), fd) != NULL) {
+			if ((cp = strchr(line, '\n')) != NULL)
+				*cp = '\0';
+			lreply(220, "%s", line);
+		}
+		(void) fflush(stdout);
+		(void) fclose(fd);
+		/* reply(220,) must follow */
+	}
+	(void) gethostname(hostname, sizeof(hostname));
+	reply(220, "%s FTP server (%s) ready.", hostname, version);
+	(void) setjmp(errcatch);
+	for (;;)
+		(void) yyparse();
+	/* NOTREACHED */
+}
+
+static void
+lostconn(signo)
+	int signo;
+{
+
+	if (debug)
+		syslog(LOG_DEBUG, "lost connection");
+	dologout(-1);
+}
+
+static char ttyline[20];
+
+/*
+ * Helper function for sgetpwnam().
+ */
+static char *
+sgetsave(s)
+	char *s;
+{
+	char *new = malloc((unsigned) strlen(s) + 1);
+
+	if (new == NULL) {
+		perror_reply(421, "Local resource failure: malloc");
+		dologout(1);
+		/* NOTREACHED */
+	}
+	(void) strcpy(new, s);
+	return (new);
+}
+
+/*
+ * Save the result of a getpwnam.  Used for USER command, since
+ * the data returned must not be clobbered by any other command
+ * (e.g., globbing).
+ */
+static struct passwd *
+sgetpwnam(name)
+	char *name;
+{
+	static struct passwd save;
+	struct passwd *p;
+
+	if ((p = getpwnam(name)) == NULL)
+		return (p);
+	if (save.pw_name) {
+		free(save.pw_name);
+		free(save.pw_passwd);
+		free(save.pw_gecos);
+		free(save.pw_dir);
+		free(save.pw_shell);
+	}
+	save = *p;
+	save.pw_name = sgetsave(p->pw_name);
+	save.pw_passwd = sgetsave(p->pw_passwd);
+	save.pw_gecos = sgetsave(p->pw_gecos);
+	save.pw_dir = sgetsave(p->pw_dir);
+	save.pw_shell = sgetsave(p->pw_shell);
+	return (&save);
+}
+
+static int login_attempts;	/* number of failed login attempts */
+static int askpasswd;		/* had user command, ask for passwd */
+static char curname[10];	/* current USER name */
+
+/*
+ * USER command.
+ * Sets global passwd pointer pw if named account exists and is acceptable;
+ * sets askpasswd if a PASS command is expected.  If logged in previously,
+ * need to reset state.  If name is "ftp" or "anonymous", the name is not in
+ * _PATH_FTPUSERS, and ftp account exists, set guest and pw, then just return.
+ * If account doesn't exist, ask for passwd anyway.  Otherwise, check user
+ * requesting login privileges.  Disallow anyone who does not have a standard
+ * shell as returned by getusershell().  Disallow anyone mentioned in the file
+ * _PATH_FTPUSERS to allow people such as root and uucp to be avoided.
+ */
+void
+user(name)
+	char *name;
+{
+	char *cp, *shell;
+
+	if (logged_in) {
+		if (guest) {
+			reply(530, "Can't change user from guest login.");
+			return;
+		}
+		end_login();
+	}
+
+	guest = 0;
+	if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
+		if (checkuser("ftp") || checkuser("anonymous"))
+			reply(530, "User %s access denied.", name);
+		else if ((pw = sgetpwnam("ftp")) != NULL) {
+			guest = 1;
+			askpasswd = 1;
+			reply(331,
+			    "Guest login ok, type your name as password.");
+		} else
+			reply(530, "User %s unknown.", name);
+		if (!askpasswd && logging)
+			syslog(LOG_NOTICE,
+			    "ANONYMOUS FTP LOGIN REFUSED FROM %s", remotehost);
+		return;
+	}
+	if (pw = sgetpwnam(name)) {
+		if ((shell = pw->pw_shell) == NULL || *shell == 0)
+			shell = _PATH_BSHELL;
+		while ((cp = getusershell()) != NULL)
+			if (strcmp(cp, shell) == 0)
+				break;
+		endusershell();
+
+		if (cp == NULL || checkuser(name)) {
+			reply(530, "User %s access denied.", name);
+			if (logging)
+				syslog(LOG_NOTICE,
+				    "FTP LOGIN REFUSED FROM %s, %s",
+				    remotehost, name);
+			pw = (struct passwd *) NULL;
+			return;
+		}
+	}
+	if (logging)
+		strncpy(curname, name, sizeof(curname)-1);
+	reply(331, "Password required for %s.", name);
+	askpasswd = 1;
+	/*
+	 * Delay before reading passwd after first failed
+	 * attempt to slow down passwd-guessing programs.
+	 */
+	if (login_attempts)
+		sleep((unsigned) login_attempts);
+}
+
+/*
+ * Check if a user is in the file _PATH_FTPUSERS
+ */
+static int
+checkuser(name)
+	char *name;
+{
+	FILE *fd;
+	int found = 0;
+	char *p, line[BUFSIZ];
+
+	if ((fd = fopen(_PATH_FTPUSERS, "r")) != NULL) {
+		while (fgets(line, sizeof(line), fd) != NULL)
+			if ((p = strchr(line, '\n')) != NULL) {
+				*p = '\0';
+				if (line[0] == '#')
+					continue;
+				if (strcmp(line, name) == 0) {
+					found = 1;
+					break;
+				}
+			}
+		(void) fclose(fd);
+	}
+	return (found);
+}
+
+/*
+ * Terminate login as previous user, if any, resetting state;
+ * used when USER command is given or login fails.
+ */
+static void
+end_login()
+{
+
+	(void) seteuid((uid_t)0);
+	if (logged_in)
+		logwtmp(ttyline, "", "");
+	pw = NULL;
+	logged_in = 0;
+	guest = 0;
+}
+
+void
+pass(passwd)
+	char *passwd;
+{
+	char *salt, *xpasswd;
+	FILE *fd;
+
+	if (logged_in || askpasswd == 0) {
+		reply(503, "Login with USER first.");
+		return;
+	}
+	askpasswd = 0;
+	if (!guest) {		/* "ftp" is only account allowed no password */
+		if (pw == NULL)
+			salt = "xx";
+		else
+			salt = pw->pw_passwd;
+		xpasswd = crypt(passwd, salt);
+		/* The strcmp does not catch null passwords! */
+		if (pw == NULL || *pw->pw_passwd == '\0' ||
+		    strcmp(xpasswd, pw->pw_passwd)) {
+			reply(530, "Login incorrect.");
+			if (logging)
+				syslog(LOG_NOTICE,
+				    "FTP LOGIN FAILED FROM %s, %s",
+				    remotehost, curname);
+			pw = NULL;
+			if (login_attempts++ >= 5) {
+				syslog(LOG_NOTICE,
+				    "repeated login failures from %s",
+				    remotehost);
+				exit(0);
+			}
+			return;
+		}
+	}
+	login_attempts = 0;		/* this time successful */
+	if (setegid((gid_t)pw->pw_gid) < 0) {
+		reply(550, "Can't set gid.");
+		return;
+	}
+	(void) initgroups(pw->pw_name, pw->pw_gid);
+
+	/* open wtmp before chroot */
+	(void)sprintf(ttyline, "ftp%d", getpid());
+	logwtmp(ttyline, pw->pw_name, remotehost);
+	logged_in = 1;
+
+	if (guest) {
+		/*
+		 * We MUST do a chdir() after the chroot. Otherwise
+		 * the old current directory will be accessible as "."
+		 * outside the new root!
+		 */
+		if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
+			reply(550, "Can't set guest privileges.");
+			goto bad;
+		}
+	} else if (chdir(pw->pw_dir) < 0) {
+		if (chdir("/") < 0) {
+			reply(530, "User %s: can't change directory to %s.",
+			    pw->pw_name, pw->pw_dir);
+			goto bad;
+		} else
+			lreply(230, "No directory! Logging in with home=/");
+	}
+	if (seteuid((uid_t)pw->pw_uid) < 0) {
+		reply(550, "Can't set uid.");
+		goto bad;
+	}
+	/*
+	 * Display a login message, if it exists.
+	 * N.B. reply(230,) must follow the message.
+	 */
+	if ((fd = fopen(_PATH_FTPLOGINMESG, "r")) != NULL) {
+		char *cp, line[LINE_MAX];
+
+		while (fgets(line, sizeof(line), fd) != NULL) {
+			if ((cp = strchr(line, '\n')) != NULL)
+				*cp = '\0';
+			lreply(230, "%s", line);
+		}
+		(void) fflush(stdout);
+		(void) fclose(fd);
+	}
+	if (guest) {
+		reply(230, "Guest login ok, access restrictions apply.");
+#ifdef SETPROCTITLE
+		snprintf(proctitle, sizeof(proctitle),
+		    "%s: anonymous/%.*s", remotehost,
+		    sizeof(proctitle) - sizeof(remotehost) -
+		    sizeof(": anonymous/"), passwd);
+		setproctitle("%s", proctitle);
+#endif /* SETPROCTITLE */
+		if (logging)
+			syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
+			    remotehost, passwd);
+	} else {
+		reply(230, "User %s logged in.", pw->pw_name);
+#ifdef SETPROCTITLE
+		snprintf(proctitle, sizeof(proctitle),
+		    "%s: %s", remotehost, pw->pw_name);
+		setproctitle("%s", proctitle);
+#endif /* SETPROCTITLE */
+		if (logging)
+			syslog(LOG_INFO, "FTP LOGIN FROM %s as %s",
+			    remotehost, pw->pw_name);
+	}
+	(void) umask(defumask);
+	return;
+bad:
+	/* Forget all about it... */
+	end_login();
+}
+
+void
+retrieve(cmd, name)
+	char *cmd, *name;
+{
+	FILE *fin, *dout;
+	struct stat st;
+	int (*closefunc) __P((FILE *));
+
+	if (cmd == 0) {
+		fin = fopen(name, "r"), closefunc = fclose;
+		st.st_size = 0;
+	} else {
+		char line[BUFSIZ];
+
+		(void) sprintf(line, cmd, name), name = line;
+		fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose;
+		st.st_size = -1;
+		st.st_blksize = BUFSIZ;
+	}
+	if (fin == NULL) {
+		if (errno != 0) {
+			perror_reply(550, name);
+			if (cmd == 0) {
+				LOGCMD("get", name);
+			}
+		}
+		return;
+	}
+	byte_count = -1;
+	if (cmd == 0 && (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode))) {
+		reply(550, "%s: not a plain file.", name);
+		goto done;
+	}
+	if (restart_point) {
+		if (type == TYPE_A) {
+			off_t i, n;
+			int c;
+
+			n = restart_point;
+			i = 0;
+			while (i++ < n) {
+				if ((c=getc(fin)) == EOF) {
+					perror_reply(550, name);
+					goto done;
+				}
+				if (c == '\n')
+					i++;
+			}
+		} else if (lseek(fileno(fin), restart_point, L_SET) < 0) {
+			perror_reply(550, name);
+			goto done;
+		}
+	}
+	dout = dataconn(name, st.st_size, "w");
+	if (dout == NULL)
+		goto done;
+	send_data(fin, dout, st.st_blksize);
+	(void) fclose(dout);
+	data = -1;
+	pdata = -1;
+done:
+	if (cmd == 0)
+		LOGBYTES("get", name, byte_count);
+	(*closefunc)(fin);
+}
+
+void
+store(name, mode, unique)
+	char *name, *mode;
+	int unique;
+{
+	FILE *fout, *din;
+	struct stat st;
+	int (*closefunc) __P((FILE *));
+
+	if (unique && stat(name, &st) == 0 &&
+	    (name = gunique(name)) == NULL) {
+		LOGCMD(*mode == 'w' ? "put" : "append", name);
+		return;
+	}
+
+	if (restart_point)
+		mode = "r+";
+	fout = fopen(name, mode);
+	closefunc = fclose;
+	if (fout == NULL) {
+		perror_reply(553, name);
+		LOGCMD(*mode == 'w' ? "put" : "append", name);
+		return;
+	}
+	byte_count = -1;
+	if (restart_point) {
+		if (type == TYPE_A) {
+			off_t i, n;
+			int c;
+
+			n = restart_point;
+			i = 0;
+			while (i++ < n) {
+				if ((c=getc(fout)) == EOF) {
+					perror_reply(550, name);
+					goto done;
+				}
+				if (c == '\n')
+					i++;
+			}
+			/*
+			 * We must do this seek to "current" position
+			 * because we are changing from reading to
+			 * writing.
+			 */
+			if (fseek(fout, 0L, L_INCR) < 0) {
+				perror_reply(550, name);
+				goto done;
+			}
+		} else if (lseek(fileno(fout), restart_point, L_SET) < 0) {
+			perror_reply(550, name);
+			goto done;
+		}
+	}
+	din = dataconn(name, (off_t)-1, "r");
+	if (din == NULL)
+		goto done;
+	if (receive_data(din, fout) == 0) {
+		if (unique)
+			reply(226, "Transfer complete (unique file name:%s).",
+			    name);
+		else
+			reply(226, "Transfer complete.");
+	}
+	(void) fclose(din);
+	data = -1;
+	pdata = -1;
+done:
+	LOGBYTES(*mode == 'w' ? "put" : "append", name, byte_count);
+	(*closefunc)(fout);
+}
+
+static FILE *
+getdatasock(mode)
+	char *mode;
+{
+	int on = 1, s, t, tries;
+
+	if (data >= 0)
+		return (fdopen(data, mode));
+	(void) seteuid((uid_t)0);
+	s = socket(AF_INET, SOCK_STREAM, 0);
+	if (s < 0)
+		goto bad;
+	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+	    (char *) &on, sizeof(on)) < 0)
+		goto bad;
+	/* anchor socket to avoid multi-homing problems */
+	data_source.sin_family = AF_INET;
+	data_source.sin_addr = ctrl_addr.sin_addr;
+	for (tries = 1; ; tries++) {
+		if (bind(s, (struct sockaddr *)&data_source,
+		    sizeof(data_source)) >= 0)
+			break;
+		if (errno != EADDRINUSE || tries > 10)
+			goto bad;
+		sleep(tries);
+	}
+	(void) seteuid((uid_t)pw->pw_uid);
+#ifdef IP_TOS
+	on = IPTOS_THROUGHPUT;
+	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
+		syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
+#endif
+	return (fdopen(s, mode));
+bad:
+	/* Return the real value of errno (close may change it) */
+	t = errno;
+	(void) seteuid((uid_t)pw->pw_uid);
+	(void) close(s);
+	errno = t;
+	return (NULL);
+}
+
+static FILE *
+dataconn(name, size, mode)
+	char *name;
+	off_t size;
+	char *mode;
+{
+	char sizebuf[32];
+	FILE *file;
+	int retry = 0, tos;
+
+	file_size = size;
+	byte_count = 0;
+	if (size != (off_t) -1)
+		(void) sprintf(sizebuf, " (%qd bytes)", size);
+	else
+		(void) strcpy(sizebuf, "");
+	if (pdata >= 0) {
+		struct sockaddr_in from;
+		int s, fromlen = sizeof(from);
+
+		s = accept(pdata, (struct sockaddr *)&from, &fromlen);
+		if (s < 0) {
+			reply(425, "Can't open data connection.");
+			(void) close(pdata);
+			pdata = -1;
+			return (NULL);
+		}
+		(void) close(pdata);
+		pdata = s;
+#ifdef IP_TOS
+		tos = IPTOS_LOWDELAY;
+		(void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos,
+		    sizeof(int));
+#endif
+		reply(150, "Opening %s mode data connection for '%s'%s.",
+		     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+		return (fdopen(pdata, mode));
+	}
+	if (data >= 0) {
+		reply(125, "Using existing data connection for '%s'%s.",
+		    name, sizebuf);
+		usedefault = 1;
+		return (fdopen(data, mode));
+	}
+	if (usedefault)
+		data_dest = his_addr;
+	usedefault = 1;
+	file = getdatasock(mode);
+	if (file == NULL) {
+		reply(425, "Can't create data socket (%s,%d): %s.",
+		    inet_ntoa(data_source.sin_addr),
+		    ntohs(data_source.sin_port), strerror(errno));
+		return (NULL);
+	}
+	data = fileno(file);
+	while (connect(data, (struct sockaddr *)&data_dest,
+	    sizeof(data_dest)) < 0) {
+		if (errno == EADDRINUSE && retry < swaitmax) {
+			sleep((unsigned) swaitint);
+			retry += swaitint;
+			continue;
+		}
+		perror_reply(425, "Can't build data connection");
+		(void) fclose(file);
+		data = -1;
+		return (NULL);
+	}
+	reply(150, "Opening %s mode data connection for '%s'%s.",
+	     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+	return (file);
+}
+
+/*
+ * Tranfer the contents of "instr" to "outstr" peer using the appropriate
+ * encapsulation of the data subject * to Mode, Structure, and Type.
+ *
+ * NB: Form isn't handled.
+ */
+static void
+send_data(instr, outstr, blksize)
+	FILE *instr, *outstr;
+	off_t blksize;
+{
+	int c, cnt, filefd, netfd;
+	char *buf;
+
+	transflag++;
+	if (setjmp(urgcatch)) {
+		transflag = 0;
+		return;
+	}
+	switch (type) {
+
+	case TYPE_A:
+		while ((c = getc(instr)) != EOF) {
+			byte_count++;
+			if (c == '\n') {
+				if (ferror(outstr))
+					goto data_err;
+				(void) putc('\r', outstr);
+			}
+			(void) putc(c, outstr);
+		}
+		fflush(outstr);
+		transflag = 0;
+		if (ferror(instr))
+			goto file_err;
+		if (ferror(outstr))
+			goto data_err;
+		reply(226, "Transfer complete.");
+		return;
+
+	case TYPE_I:
+	case TYPE_L:
+		if ((buf = malloc((u_int)blksize)) == NULL) {
+			transflag = 0;
+			perror_reply(451, "Local resource failure: malloc");
+			return;
+		}
+		netfd = fileno(outstr);
+		filefd = fileno(instr);
+		while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 &&
+		    write(netfd, buf, cnt) == cnt)
+			byte_count += cnt;
+		transflag = 0;
+		(void)free(buf);
+		if (cnt != 0) {
+			if (cnt < 0)
+				goto file_err;
+			goto data_err;
+		}
+		reply(226, "Transfer complete.");
+		return;
+	default:
+		transflag = 0;
+		reply(550, "Unimplemented TYPE %d in send_data", type);
+		return;
+	}
+
+data_err:
+	transflag = 0;
+	perror_reply(426, "Data connection");
+	return;
+
+file_err:
+	transflag = 0;
+	perror_reply(551, "Error on input file");
+}
+
+/*
+ * Transfer data from peer to "outstr" using the appropriate encapulation of
+ * the data subject to Mode, Structure, and Type.
+ *
+ * N.B.: Form isn't handled.
+ */
+static int
+receive_data(instr, outstr)
+	FILE *instr, *outstr;
+{
+	int c;
+	int cnt, bare_lfs = 0;
+	char buf[BUFSIZ];
+
+	transflag++;
+	if (setjmp(urgcatch)) {
+		transflag = 0;
+		return (-1);
+	}
+	switch (type) {
+
+	case TYPE_I:
+	case TYPE_L:
+		while ((cnt = read(fileno(instr), buf, sizeof(buf))) > 0) {
+			if (write(fileno(outstr), buf, cnt) != cnt)
+				goto file_err;
+			byte_count += cnt;
+		}
+		if (cnt < 0)
+			goto data_err;
+		transflag = 0;
+		return (0);
+
+	case TYPE_E:
+		reply(553, "TYPE E not implemented.");
+		transflag = 0;
+		return (-1);
+
+	case TYPE_A:
+		while ((c = getc(instr)) != EOF) {
+			byte_count++;
+			if (c == '\n')
+				bare_lfs++;
+			while (c == '\r') {
+				if (ferror(outstr))
+					goto data_err;
+				if ((c = getc(instr)) != '\n') {
+					(void) putc ('\r', outstr);
+					if (c == '\0' || c == EOF)
+						goto contin2;
+				}
+			}
+			(void) putc(c, outstr);
+	contin2:	;
+		}
+		fflush(outstr);
+		if (ferror(instr))
+			goto data_err;
+		if (ferror(outstr))
+			goto file_err;
+		transflag = 0;
+		if (bare_lfs) {
+			lreply(226,
+		"WARNING! %d bare linefeeds received in ASCII mode",
+			    bare_lfs);
+		(void)printf("   File may not have transferred correctly.\r\n");
+		}
+		return (0);
+	default:
+		reply(550, "Unimplemented TYPE %d in receive_data", type);
+		transflag = 0;
+		return (-1);
+	}
+
+data_err:
+	transflag = 0;
+	perror_reply(426, "Data Connection");
+	return (-1);
+
+file_err:
+	transflag = 0;
+	perror_reply(452, "Error writing file");
+	return (-1);
+}
+
+void
+statfilecmd(filename)
+	char *filename;
+{
+	FILE *fin;
+	int c;
+	char line[LINE_MAX];
+
+	(void)snprintf(line, sizeof(line), "/bin/ls -lgA %s", filename);
+	fin = ftpd_popen(line, "r");
+	lreply(211, "status of %s:", filename);
+	while ((c = getc(fin)) != EOF) {
+		if (c == '\n') {
+			if (ferror(stdout)){
+				perror_reply(421, "control connection");
+				(void) ftpd_pclose(fin);
+				dologout(1);
+				/* NOTREACHED */
+			}
+			if (ferror(fin)) {
+				perror_reply(551, filename);
+				(void) ftpd_pclose(fin);
+				return;
+			}
+			(void) putc('\r', stdout);
+		}
+		(void) putc(c, stdout);
+	}
+	(void) ftpd_pclose(fin);
+	reply(211, "End of Status");
+}
+
+void
+statcmd()
+{
+	struct sockaddr_in *sin;
+	u_char *a, *p;
+
+	lreply(211, "%s FTP server status:", hostname, version);
+	printf("     %s\r\n", version);
+	printf("     Connected to %s", remotehost);
+	if (!isdigit(remotehost[0]))
+		printf(" (%s)", inet_ntoa(his_addr.sin_addr));
+	printf("\r\n");
+	if (logged_in) {
+		if (guest)
+			printf("     Logged in anonymously\r\n");
+		else
+			printf("     Logged in as %s\r\n", pw->pw_name);
+	} else if (askpasswd)
+		printf("     Waiting for password\r\n");
+	else
+		printf("     Waiting for user name\r\n");
+	printf("     TYPE: %s", typenames[type]);
+	if (type == TYPE_A || type == TYPE_E)
+		printf(", FORM: %s", formnames[form]);
+	if (type == TYPE_L)
+#if NBBY == 8
+		printf(" %d", NBBY);
+#else
+		printf(" %d", bytesize);	/* need definition! */
+#endif
+	printf("; STRUcture: %s; transfer MODE: %s\r\n",
+	    strunames[stru], modenames[mode]);
+	if (data != -1)
+		printf("     Data connection open\r\n");
+	else if (pdata != -1) {
+		printf("     in Passive mode");
+		sin = &pasv_addr;
+		goto printaddr;
+	} else if (usedefault == 0) {
+		printf("     PORT");
+		sin = &data_dest;
+printaddr:
+		a = (u_char *) &sin->sin_addr;
+		p = (u_char *) &sin->sin_port;
+#define UC(b) (((int) b) & 0xff)
+		printf(" (%d,%d,%d,%d,%d,%d)\r\n", UC(a[0]),
+			UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
+#undef UC
+	} else
+		printf("     No data connection\r\n");
+	reply(211, "End of status");
+}
+
+void
+fatal(s)
+	char *s;
+{
+
+	reply(451, "Error in server: %s\n", s);
+	reply(221, "Closing connection due to server error.");
+	dologout(0);
+	/* NOTREACHED */
+}
+
+void
+#if __STDC__
+reply(int n, const char *fmt, ...)
+#else
+reply(n, fmt, va_alist)
+	int n;
+	char *fmt;
+        va_dcl
+#endif
+{
+	va_list ap;
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	(void)printf("%d ", n);
+	(void)vprintf(fmt, ap);
+	(void)printf("\r\n");
+	(void)fflush(stdout);
+	if (debug) {
+		syslog(LOG_DEBUG, "<--- %d ", n);
+		vsyslog(LOG_DEBUG, fmt, ap);
+	}
+}
+
+void
+#if __STDC__
+lreply(int n, const char *fmt, ...)
+#else
+lreply(n, fmt, va_alist)
+	int n;
+	char *fmt;
+        va_dcl
+#endif
+{
+	va_list ap;
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	(void)printf("%d- ", n);
+	(void)vprintf(fmt, ap);
+	(void)printf("\r\n");
+	(void)fflush(stdout);
+	if (debug) {
+		syslog(LOG_DEBUG, "<--- %d- ", n);
+		vsyslog(LOG_DEBUG, fmt, ap);
+	}
+}
+
+static void
+ack(s)
+	char *s;
+{
+
+	reply(250, "%s command successful.", s);
+}
+
+void
+nack(s)
+	char *s;
+{
+
+	reply(502, "%s command not implemented.", s);
+}
+
+/* ARGSUSED */
+void
+yyerror(s)
+	char *s;
+{
+	char *cp;
+
+	if (cp = strchr(cbuf,'\n'))
+		*cp = '\0';
+	reply(500, "'%s': command not understood.", cbuf);
+}
+
+void
+delete(name)
+	char *name;
+{
+	struct stat st;
+
+	LOGCMD("delete", name);
+	if (stat(name, &st) < 0) {
+		perror_reply(550, name);
+		return;
+	}
+	if ((st.st_mode&S_IFMT) == S_IFDIR) {
+		if (rmdir(name) < 0) {
+			perror_reply(550, name);
+			return;
+		}
+		goto done;
+	}
+	if (unlink(name) < 0) {
+		perror_reply(550, name);
+		return;
+	}
+done:
+	ack("DELE");
+}
+
+void
+cwd(path)
+	char *path;
+{
+
+	if (chdir(path) < 0)
+		perror_reply(550, path);
+	else
+		ack("CWD");
+}
+
+void
+makedir(name)
+	char *name;
+{
+
+	LOGCMD("mkdir", name);
+	if (mkdir(name, 0777) < 0)
+		perror_reply(550, name);
+	else
+		reply(257, "MKD command successful.");
+}
+
+void
+removedir(name)
+	char *name;
+{
+
+	LOGCMD("rmdir", name);
+	if (rmdir(name) < 0)
+		perror_reply(550, name);
+	else
+		ack("RMD");
+}
+
+void
+pwd()
+{
+	char path[MAXPATHLEN];
+
+	if (getcwd(path, sizeof(path)) == (char *)NULL)
+		reply(550, "%s.", path);
+	else
+		reply(257, "\"%s\" is current directory.", path);
+}
+
+char *
+renamefrom(name)
+	char *name;
+{
+	struct stat st;
+
+	if (stat(name, &st) < 0) {
+		perror_reply(550, name);
+		return ((char *)0);
+	}
+	reply(350, "File exists, ready for destination name");
+	return (name);
+}
+
+void
+renamecmd(from, to)
+	char *from, *to;
+{
+
+	LOGCMD2("rename", from, to);
+	if (rename(from, to) < 0)
+		perror_reply(550, "rename");
+	else
+		ack("RNTO");
+}
+
+static void
+dolog(sin)
+	struct sockaddr_in *sin;
+{
+	struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr,
+		sizeof(struct in_addr), AF_INET);
+
+	if (hp)
+		(void) strncpy(remotehost, hp->h_name, sizeof(remotehost));
+	else
+		(void) strncpy(remotehost, inet_ntoa(sin->sin_addr),
+		    sizeof(remotehost));
+#ifdef SETPROCTITLE
+	snprintf(proctitle, sizeof(proctitle), "%s: connected", remotehost);
+	setproctitle("%s", proctitle);
+#endif /* SETPROCTITLE */
+
+	if (logging)
+		syslog(LOG_INFO, "connection from %s", remotehost);
+}
+
+/*
+ * Record logout in wtmp file
+ * and exit with supplied status.
+ */
+void
+dologout(status)
+	int status;
+{
+ 	/*
+ 	* Prevent reception of SIGURG from resulting in a resumption
+ 	* back to the main program loop.
+ 	*/
+ 	transflag = 0;
+
+	if (logged_in) {
+		(void) seteuid((uid_t)0);
+		logwtmp(ttyline, "", "");
+	}
+	/* beware of flushing buffers after a SIGPIPE */
+	_exit(status);
+}
+
+static void
+myoob(signo)
+	int signo;
+{
+	char *cp;
+
+	/* only process if transfer occurring */
+	if (!transflag)
+		return;
+	cp = tmpline;
+	if (getline(cp, 7, stdin) == NULL) {
+		reply(221, "You could at least say goodbye.");
+		dologout(0);
+	}
+	upper(cp);
+	if (strcmp(cp, "ABOR\r\n") == 0) {
+		tmpline[0] = '\0';
+		reply(426, "Transfer aborted. Data connection closed.");
+		reply(226, "Abort successful");
+		longjmp(urgcatch, 1);
+	}
+	if (strcmp(cp, "STAT\r\n") == 0) {
+		if (file_size != (off_t) -1)
+			reply(213, "Status: %qd of %qd bytes transferred",
+			    byte_count, file_size);
+		else
+			reply(213, "Status: %qd bytes transferred", byte_count);
+	}
+}
+
+/*
+ * Note: a response of 425 is not mentioned as a possible response to
+ *	the PASV command in RFC959. However, it has been blessed as
+ *	a legitimate response by Jon Postel in a telephone conversation
+ *	with Rick Adams on 25 Jan 89.
+ */
+void
+passive()
+{
+	int len;
+	char *p, *a;
+
+	pdata = socket(AF_INET, SOCK_STREAM, 0);
+	if (pdata < 0) {
+		perror_reply(425, "Can't open passive connection");
+		return;
+	}
+	pasv_addr = ctrl_addr;
+	pasv_addr.sin_port = 0;
+	(void) seteuid((uid_t)0);
+	if (bind(pdata, (struct sockaddr *)&pasv_addr, sizeof(pasv_addr)) < 0) {
+		(void) seteuid((uid_t)pw->pw_uid);
+		goto pasv_error;
+	}
+	(void) seteuid((uid_t)pw->pw_uid);
+	len = sizeof(pasv_addr);
+	if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
+		goto pasv_error;
+	if (listen(pdata, 1) < 0)
+		goto pasv_error;
+	a = (char *) &pasv_addr.sin_addr;
+	p = (char *) &pasv_addr.sin_port;
+
+#define UC(b) (((int) b) & 0xff)
+
+	reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
+		UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
+	return;
+
+pasv_error:
+	(void) close(pdata);
+	pdata = -1;
+	perror_reply(425, "Can't open passive connection");
+	return;
+}
+
+/*
+ * Generate unique name for file with basename "local".
+ * The file named "local" is already known to exist.
+ * Generates failure reply on error.
+ */
+static char *
+gunique(local)
+	char *local;
+{
+	static char new[MAXPATHLEN];
+	struct stat st;
+	int count;
+	char *cp;
+
+	cp = strrchr(local, '/');
+	if (cp)
+		*cp = '\0';
+	if (stat(cp ? local : ".", &st) < 0) {
+		perror_reply(553, cp ? local : ".");
+		return ((char *) 0);
+	}
+	if (cp)
+		*cp = '/';
+	(void) strcpy(new, local);
+	cp = new + strlen(new);
+	*cp++ = '.';
+	for (count = 1; count < 100; count++) {
+		(void)sprintf(cp, "%d", count);
+		if (stat(new, &st) < 0)
+			return (new);
+	}
+	reply(452, "Unique file name cannot be created.");
+	return (NULL);
+}
+
+/*
+ * Format and send reply containing system error number.
+ */
+void
+perror_reply(code, string)
+	int code;
+	char *string;
+{
+
+	reply(code, "%s: %s.", string, strerror(errno));
+}
+
+static char *onefile[] = {
+	"",
+	0
+};
+
+void
+send_file_list(whichf)
+	char *whichf;
+{
+	struct stat st;
+	DIR *dirp = NULL;
+	struct dirent *dir;
+	FILE *dout = NULL;
+	char **dirlist, *dirname;
+	int simple = 0;
+	int freeglob = 0;
+	glob_t gl;
+
+	if (strpbrk(whichf, "~{[*?") != NULL) {
+		int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+
+		memset(&gl, 0, sizeof(gl));
+		freeglob = 1;
+		if (glob(whichf, flags, 0, &gl)) {
+			reply(550, "not found");
+			goto out;
+		} else if (gl.gl_pathc == 0) {
+			errno = ENOENT;
+			perror_reply(550, whichf);
+			goto out;
+		}
+		dirlist = gl.gl_pathv;
+	} else {
+		onefile[0] = whichf;
+		dirlist = onefile;
+		simple = 1;
+	}
+
+	if (setjmp(urgcatch)) {
+		transflag = 0;
+		goto out;
+	}
+	while (dirname = *dirlist++) {
+		if (stat(dirname, &st) < 0) {
+			/*
+			 * If user typed "ls -l", etc, and the client
+			 * used NLST, do what the user meant.
+			 */
+			if (dirname[0] == '-' && *dirlist == NULL &&
+			    transflag == 0) {
+				retrieve("/bin/ls %s", dirname);
+				goto out;
+			}
+			perror_reply(550, whichf);
+			if (dout != NULL) {
+				(void) fclose(dout);
+				transflag = 0;
+				data = -1;
+				pdata = -1;
+			}
+			goto out;
+		}
+
+		if (S_ISREG(st.st_mode)) {
+			if (dout == NULL) {
+				dout = dataconn("file list", (off_t)-1, "w");
+				if (dout == NULL)
+					goto out;
+				transflag++;
+			}
+			fprintf(dout, "%s%s\n", dirname,
+				type == TYPE_A ? "\r" : "");
+			byte_count += strlen(dirname) + 1;
+			continue;
+		} else if (!S_ISDIR(st.st_mode))
+			continue;
+
+		if ((dirp = opendir(dirname)) == NULL)
+			continue;
+
+		while ((dir = readdir(dirp)) != NULL) {
+			char nbuf[MAXPATHLEN];
+
+			if (dir->d_name[0] == '.' && dir->d_namlen == 1)
+				continue;
+			if (dir->d_name[0] == '.' && dir->d_name[1] == '.' &&
+			    dir->d_namlen == 2)
+				continue;
+
+			sprintf(nbuf, "%s/%s", dirname, dir->d_name);
+
+			/*
+			 * We have to do a stat to insure it's
+			 * not a directory or special file.
+			 */
+			if (simple || (stat(nbuf, &st) == 0 &&
+			    S_ISREG(st.st_mode))) {
+				if (dout == NULL) {
+					dout = dataconn("file list", (off_t)-1,
+						"w");
+					if (dout == NULL)
+						goto out;
+					transflag++;
+				}
+				if (nbuf[0] == '.' && nbuf[1] == '/')
+					fprintf(dout, "%s%s\n", &nbuf[2],
+						type == TYPE_A ? "\r" : "");
+				else
+					fprintf(dout, "%s%s\n", nbuf,
+						type == TYPE_A ? "\r" : "");
+				byte_count += strlen(nbuf) + 1;
+			}
+		}
+		(void) closedir(dirp);
+	}
+
+	if (dout == NULL)
+		reply(550, "No files found.");
+	else if (ferror(dout) != 0)
+		perror_reply(550, "Data connection");
+	else
+		reply(226, "Transfer complete.");
+
+	transflag = 0;
+	if (dout != NULL)
+		(void) fclose(dout);
+	data = -1;
+	pdata = -1;
+out:
+	if (freeglob) {
+		freeglob = 0;
+		globfree(&gl);
+	}
+}
+
+#ifdef SETPROCTITLE
+/*
+ * Clobber argv so ps will show what we're doing.  (Stolen from sendmail.)
+ * Warning, since this is usually started from inetd.conf, it often doesn't
+ * have much of an environment or arglist to overwrite.
+ */
+void
+#if __STDC__
+setproctitle(const char *fmt, ...)
+#else
+setproctitle(fmt, va_alist)
+	char *fmt;
+        va_dcl
+#endif
+{
+	int i;
+	va_list ap;
+	char *p, *bp, ch;
+	char buf[LINE_MAX];
+
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
+
+	/* make ps print our process name */
+	p = Argv[0];
+	*p++ = '-';
+
+	i = strlen(buf);
+	if (i > LastArgv - p - 2) {
+		i = LastArgv - p - 2;
+		buf[i] = '\0';
+	}
+	bp = buf;
+	while (ch = *bp++)
+		if (ch != '\n' && ch != '\r')
+			*p++ = ch;
+	while (p < LastArgv)
+		*p++ = ' ';
+}
+#endif /* SETPROCTITLE */
+#pragma CC_OPT_RESTORE
diff --git a/ftpd.tproj/logwtmp.c b/ftpd.tproj/logwtmp.c
new file mode 100644
index 0000000..cca4d26
--- /dev/null
+++ b/ftpd.tproj/logwtmp.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)logwtmp.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <utmp.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include "extern.h"
+
+static int fd = -1;
+
+/*
+ * Modified version of logwtmp that holds wtmp file open
+ * after first call, for use with ftp (which may chroot
+ * after login, but before logout).
+ */
+void
+logwtmp(line, name, host)
+	char *line, *name, *host;
+{
+	struct utmp ut;
+	struct stat buf;
+
+	if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
+		return;
+	if (fstat(fd, &buf) == 0) {
+		(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+		(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+		(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
+		(void)time(&ut.ut_time);
+		if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
+		    sizeof(struct utmp))
+			(void)ftruncate(fd, buf.st_size);
+	}
+}
diff --git a/ftpd.tproj/pathnames.h b/ftpd.tproj/pathnames.h
new file mode 100644
index 0000000..56868c4
--- /dev/null
+++ b/ftpd.tproj/pathnames.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/4/93
+ */
+
+#include <paths.h>
+
+#define	_PATH_FTPUSERS		"/etc/ftpusers"
+#define	_PATH_FTPWELCOME	"/etc/ftpwelcome"
+#define	_PATH_FTPLOGINMESG	"/etc/motd"
diff --git a/ftpd.tproj/popen.c b/ftpd.tproj/popen.c
new file mode 100644
index 0000000..dab3d3f
--- /dev/null
+++ b/ftpd.tproj/popen.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software written by Ken Arnold and
+ * published in UNIX Review, Vol. 6, No. 8.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)popen.c	8.3 (Berkeley) 4/6/94";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <glob.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "extern.h"
+
+/*
+ * Special version of popen which avoids call to shell.  This ensures noone
+ * may create a pipe to a hidden program as a side effect of a list or dir
+ * command.
+ */
+static int *pids;
+static int fds;
+
+FILE *
+ftpd_popen(program, type)
+	char *program, *type;
+{
+	char *cp;
+	FILE *iop;
+	int argc, gargc, pdes[2], pid;
+	char **pop, *argv[100], *gargv[1000];
+
+	if (*type != 'r' && *type != 'w' || type[1])
+		return (NULL);
+
+	if (!pids) {
+		if ((fds = getdtablesize()) <= 0)
+			return (NULL);
+		if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
+			return (NULL);
+		memset(pids, 0, fds * sizeof(int));
+	}
+	if (pipe(pdes) < 0)
+		return (NULL);
+
+	/* break up string into pieces */
+	for (argc = 0, cp = program;; cp = NULL)
+		if (!(argv[argc++] = strtok(cp, " \t\n")))
+			break;
+
+	/* glob each piece */
+	gargv[0] = argv[0];
+	for (gargc = argc = 1; argv[argc]; argc++) {
+		glob_t gl;
+		int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+
+		memset(&gl, 0, sizeof(gl));
+		if (glob(argv[argc], flags, NULL, &gl))
+			gargv[gargc++] = strdup(argv[argc]);
+		else
+			for (pop = gl.gl_pathv; *pop; pop++)
+				gargv[gargc++] = strdup(*pop);
+		globfree(&gl);
+	}
+	gargv[gargc] = NULL;
+
+	iop = NULL;
+	switch(pid = vfork()) {
+	case -1:			/* error */
+		(void)close(pdes[0]);
+		(void)close(pdes[1]);
+		goto pfree;
+		/* NOTREACHED */
+	case 0:				/* child */
+		if (*type == 'r') {
+			if (pdes[1] != STDOUT_FILENO) {
+				dup2(pdes[1], STDOUT_FILENO);
+				(void)close(pdes[1]);
+			}
+			dup2(STDOUT_FILENO, STDERR_FILENO); /* stderr too! */
+			(void)close(pdes[0]);
+		} else {
+			if (pdes[0] != STDIN_FILENO) {
+				dup2(pdes[0], STDIN_FILENO);
+				(void)close(pdes[0]);
+			}
+			(void)close(pdes[1]);
+		}
+		execv(gargv[0], gargv);
+		_exit(1);
+	}
+	/* parent; assume fdopen can't fail...  */
+	if (*type == 'r') {
+		iop = fdopen(pdes[0], type);
+		(void)close(pdes[1]);
+	} else {
+		iop = fdopen(pdes[1], type);
+		(void)close(pdes[0]);
+	}
+	pids[fileno(iop)] = pid;
+
+pfree:	for (argc = 1; gargv[argc] != NULL; argc++)
+		free(gargv[argc]);
+
+	return (iop);
+}
+
+int
+ftpd_pclose(iop)
+	FILE *iop;
+{
+	int fdes, omask, status;
+	pid_t pid;
+
+	/*
+	 * pclose returns -1 if stream is not associated with a
+	 * `popened' command, or, if already `pclosed'.
+	 */
+	if (pids == 0 || pids[fdes = fileno(iop)] == 0)
+		return (-1);
+	(void)fclose(iop);
+	omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
+	while ((pid = waitpid(pids[fdes], &status, 0)) < 0 && errno == EINTR)
+		continue;
+	(void)sigsetmask(omask);
+	pids[fdes] = 0;
+	if (pid < 0)
+		return (pid);
+	if (WIFEXITED(status))
+		return (WEXITSTATUS(status));
+	return (1);
+}
diff --git a/ftpd.tproj/vers.c b/ftpd.tproj/vers.c
new file mode 100644
index 0000000..ee00fa9
--- /dev/null
+++ b/ftpd.tproj/vers.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)vers.c	5.1 (Berkeley) 6/24/90";*/
+static char rcsid[] = "$Id: vers.c,v 1.1.1.1 1999/05/02 03:57:40 wsanchez Exp $";
+#endif /* not lint */
+
+char version[] = "Version 5.60";
diff --git a/identd.tproj/CREDITS b/identd.tproj/CREDITS
new file mode 100644
index 0000000..c117a03
--- /dev/null
+++ b/identd.tproj/CREDITS
@@ -0,0 +1,52 @@
+Credits go to (I've probably forgot someone - please don't hesitate
+to tell me!) for helping making Pidentd what it is:
+
+Casper Dik <casper@fwi.uva.nl>, Math & CS Faculty, U. of Amsterdam, NL
+	(Added support for SunOS 5 (Solaris 2))
+
+Dave Shield <D.T.Shield@compsci.liverpool.ac.uk>, CS Dept. Liverpool U., UK
+	(Added support for HP9K HPUX 8.*)
+
+Jan L. Peterson <jlp@phred.math.byu.edu>, Math Dept. BYU, USA
+	(Added support for MIPS RISC/os and fixed a few other things)
+
+Fletcher Mattox <fletcher@cs.utexas.edu>, University of Texas, USA
+	(Added support for HP9K HP-UX 7.*)
+
+Mark Monnin <mgrmem@nextwork.rose-hulman.edu>, Rose-Hulman Inst. of Tech, USA
+	(Added support for DEC Ultrix 4.*)
+
+Simon Leinen <simon@lia.di.epfl.ch>, Switzerland
+	(Added support for Silicon Graphics IRIX 4.*)
+
+Frank Maas <maas@dutiws.tudelft.nl>, Delft Univ. of Technology, The Netherlands
+	(Added support for Sequent Dynix 3.*)
+
+Andrew Herbert <andrewh@molly.cs.monash.edu.au>, Monash University, Australia
+	(Added support for System V/Release 4)
+
+David Bennet <ddt@gu.uwa.edu.au>, Australia
+	(Added support for 386BSD)
+
+Fishman M. Shmuel <fms@ccgr.technion.ac.il>, Technion Inst. of Tech., Israel
+	(Added support for Convex & 4.3BSDtahoe (then heavily hacked by me))
+
+Bradley E. Smith <brad@bradley.bradley.edu>, Bradley University, USA
+	(Added support for AT&T's own version of SVR4)
+
+RenE J.V. Bertin <bertin@neuretD.biol.ruu.nl>, Uni. of Utrecht, The Netherlands
+	(Added support for Apple A/UX 2.*)
+
+Douglas Lee Schales <Doug.Schales@sc.tamu.edu>, Texas A&M University, USA
+	(Added support for Cray UNICOS 6.*)
+
+Don Hazlewood <haz@dali.math.swt.edu>, SW Texas State U., USA
+	(Added support for A/UX 3.*)
+
+ Nigel Metheringham <nigelm@ohm.york.ac.uk>, University of York, UK
+ 	(Added support for NeXT, SunOS 3.*, corrections for MIPS)
+
+----------------------------------------------------------------------------
+Peter Eriksson <pen@lysator.liu.se>, Lysator, Linkoping University, Sweden.
+	(Original code for Sun SunOS 4.* and Sequent Dynix 2.*)
+
diff --git a/identd.tproj/Makefile b/identd.tproj/Makefile
new file mode 100644
index 0000000..b8d220f
--- /dev/null
+++ b/identd.tproj/Makefile
@@ -0,0 +1,50 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = identd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = error.h identd.h xpaths.h
+
+CFILES = config.c identd.c netbsd.c parse.c proxy.c version.c
+
+OTHERSRCS = CREDITS Makefile.dist README identd.8 Makefile.preamble
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/identd.tproj/Makefile.dist b/identd.tproj/Makefile.dist
new file mode 100644
index 0000000..fad1caa
--- /dev/null
+++ b/identd.tproj/Makefile.dist
@@ -0,0 +1,10 @@
+#	$Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:57:40 wsanchez Exp $
+
+PROG=	identd
+SRCS=	config.c identd.c netbsd.c parse.c proxy.c version.c
+MAN8=	identd.0
+
+LDADD=	-lkvm
+DPADD=	${LIBKVM}
+
+.include <bsd.prog.mk>
diff --git a/identd.tproj/Makefile.preamble b/identd.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/identd.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/identd.tproj/PB.project b/identd.tproj/PB.project
new file mode 100644
index 0000000..b6dd3a8
--- /dev/null
+++ b/identd.tproj/PB.project
@@ -0,0 +1,40 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (error.h, identd.h, xpaths.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (config.c, identd.c, netbsd.c, parse.c, proxy.c, version.c); 
+        OTHER_SOURCES = (CREDITS, Makefile.dist, README, identd.8, Makefile.preamble); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = identd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/identd.tproj/README b/identd.tproj/README
new file mode 100644
index 0000000..f1e1d3b
--- /dev/null
+++ b/identd.tproj/README
@@ -0,0 +1,129 @@
+                            pidentd
+
+     ("Peter's Ident Daemon" or is it "Portable Ident Daemon"?)
+
+		Peter Eriksson <pen@lysator.liu.se>
+
+
+This program is released into the public domain and can be used by
+anyone who wants to. Vendors may include it into their distributions
+if they want to without any restrictions. (Although it would be nice
+to be notified by email if someone decides to do that, and/or a note
+somewhere about who wrote this program. Like in the man-page or so.. :-)
+
+This is a program that implements the RFC1413 identification server. It
+was very much inspired by Dan Bernstein's original 'authd' (but unlike
+that program doesn't use 'netstat' to get some of the information) It
+uses the kernel information directly.  (And is due to that fact a lot
+faster). Dan has now written another version of the 'authd' daemon that
+uses his 'kstuff' to read the kernel information. Unlike that daemon,
+this will use only normally available kernel access functions (and is due
+to that more limited in the different machines it support). Please note
+that this daemon used to be called pauthd but has changed name to better
+reflect what it does (and to conform to the new RFC).
+
+This daemon has been tested on the following machines/OS (please report
+to me if you've tested a newer version, or if your machine/OS isn't among
+the ones below):
+
+Machine			Operating System	Pidentd version
+----------------------  ----------------------  --------------------------
+  Sequent Balance	  Dynix 3.0.14		  2.1beta.12
+  Sequent Symmetry        Dynix 3.1.2		  2.1beta.3
+  Sun 3/50                SunOS 3.5               2.1beta.8.1           (3)
+  Sun 386i	          SunOS 4.0.2		  1.9beta
+  Sun 2/120	          SunOS 4.0.3		  2.1beta.10
+  Sun 3/280		  SunOS 4.1.1		  2.1beta.12
+  Sun 4/380		  SunOS 4.1.3		  2.1beta.12
+  Sun SS1/41		  SunOS 5.1		  2.1beta.11
+  HP 9000/375             HP-UX 7.0		  2.1beta.10.1		(1)
+  HP 9000/300		  HP-UX 8.0		  2.1beta.12
+  HP 9000/340		  HP-UX 8.0		  2.1beta.10.1
+  HP 9000/360		  HP-UX 8.0		  2.1beta.10.1
+  HP 9000/710             HP-UX 8.07              2.1beta.10.1
+  HP 9000/720             HP-UX 8.07		  2.1beta.10.1
+  HP 9000/715             HP-UX 9.0               2.1beta.9.1
+  HP 9000/827             HP-UX 8.02              2.1beta.8.1
+  HP 9000/834 	          HP-UX 7.0		  2.0beta.4
+  HP 9000/835 	          HP-UX 8.00		  2.1beta.10.1
+  MIPS		          RISC/OS 4.5x            2.1beta.8.1
+  DECstation 2100         Ultrix 4.2-96           2.1beta.2		(2)
+  DECstation 5000/133     Ultrix 4.2              2.1beta.9.1           (2) [?]
+  DEC VAXstation 2000	  Ultrix-32 3.1		  2.1beta.12		(2) [?]
+  DEC VAX vs3520          Ultrix 3.0              2.1beta.9.1           (2) [?]
+  DEC VAX 11/780	  4.3BSD Reno		  2.1beta.12		(2)
+  i486-PC		  UHC SVR4 2.0		  2.0beta.4		(2)
+  i486-PC		  Dell SVR4 2.2		  2.0beta.4		(2)
+  i486-PC		  ESIX SVR4 4.0.4	  2.1beta.2		(2)
+  i486-PC		  386BSD 0.1		  2.1beta.3		(2)
+  Cray			  UNICOS 6.0.12	 	  2.1beta.7
+  NeXT                    NeXTSTEP 2.1            2.1beta.9.1		(3)
+  NeXT                    NeXTSTEP 3.0            2.1beta.9.1		(3)
+  Pyramid 90x		  dualPort OSx 4.1	  2.1beta.12
+  Silicon Graphics	  IRIX 4		  2.1beta.10
+
+Notes:
+	1) HP-UX 7.0 doesn't support running streams based services from
+	   Inetd with the "wait" option (and the "-w" flag to Pidentd).
+
+	   It also has problems with starting stuff as user "sys" from Inetd.
+	   (It doesn't correctly set the group id to "sys") so I suggest you
+           either starts it as user "root" and use the "-u" and "-g" flags
+           to setuid and setgid itself to user "sys", group "sys", or do a
+	   'chgrp sys in.identd' and then a 'chmod g+s in.identd' and start
+	   it as user "sys" from Inetd.
+
+	2) These systems also doesn't support running streams based
+	   services from Inetd with the "wait" option. 
+	   
+	3) See notes in the READMEs/README.<machine-type> specific files.
+	   
+
+Please let me know if you find any bugs, or have ported it to other
+machines (and care to share the changes with me and the world!).
+
+See the manual page for information about the various command line
+options that are available.
+
+NOTE: One should NOT use the -d option when using it for normal use!
+
+If you intend to create or modify daemons that use the IDENT protocol
+then you may wish to get the "libident" library that contains some
+functions to implement the client side of this protocol. It is available
+as "libident-*.tar.Z" in "pub/ident/libs" at "ftp.lysator.liu.se".
+
+There is a mailing list for users of the IDENT(RFC1413)/TAP protocol called
+'ident-users@lysator.liu.se' that you may want to consider joining.
+Send mail to the address 'ident-users-request@lysator.liu.se' to 
+join it. This list is intended for generic discussions on using this
+protocol and it's associated tools.
+
+If you only want to receive news about new (non-alpha/beta) releases of
+Pidentd then you can join the 'ident-announce@lysator.liu.se' mailing
+list. Send mail to the address 'ident-announce-request@lysator.liu.se' to 
+join it. No discussions will take place on this list.
+
+I also run a small mailing list for people who wants to act as testers
+of new alpha/beta-versions of Pidentd. If you wish to join, please send
+mail to the address 'pidentd-testers-request@lysator.liu.se'. (I can always
+use more testers, so don't hesitate :-)
+
+It's a human (namely me :-) that reads the letters sent to *-request.
+Please include the full email address to which to wish to have the
+letters sent.
+
+I'm grateful for success/failure stories about installing/compiling this
+daemon...
+
+Information of interrest:
+
+  1. Machine and operating system type and version.
+  2. Command line flags.
+  3. Inetd.conf configuration.
+  4. Did it work, or not. And if not - what did it report to the
+     syslog file? (You'll have to add the "-l" option and probably
+     reconfigure your Syslogd). If you use the "-d" option then
+     you can see a verbose error if you Telnet into it directly and
+     send it a query manually. (See the INSTALL file for more information).
+
+/Peter Eriksson <pen@lysator.liu.se>, 5 April 1993
diff --git a/identd.tproj/config.c b/identd.tproj/config.c
new file mode 100644
index 0000000..19eec4c
--- /dev/null
+++ b/identd.tproj/config.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+**	$Id: config.c,v 1.1.1.1 1999/05/02 03:57:41 wsanchez Exp $
+**
+** config.c                         This file handles the config file
+**
+** This program is in the public domain and may be used freely by anyone
+** who wants to. 
+**
+** Last update: 6 Dec 1992
+**
+** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "error.h"
+#include "identd.h"
+#include "xpaths.h"
+
+
+int parse_config(path, silent_flag)
+  char *path;
+  int silent_flag;
+{
+  FILE *fp;
+
+  if (!path)
+    path = PATH_CONFIG;
+  
+  fp = fopen(path, "r");
+  if (!fp)
+  {
+    if (silent_flag)
+      return 0;
+
+    ERROR1("error opening %s", path);
+  }
+
+  /*
+  ** Code should go here to parse the config file data.
+  ** For now we just ignore the contents...
+  */
+  
+  
+  fclose(fp);
+  return 0;
+}
diff --git a/identd.tproj/error.h b/identd.tproj/error.h
new file mode 100644
index 0000000..d5f1990
--- /dev/null
+++ b/identd.tproj/error.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+**	$Id: error.h,v 1.1.1.1 1999/05/02 03:57:41 wsanchez Exp $
+**
+** error.h                                               Error handling macros
+**
+** This program is in the public domain and may be used freely by anyone
+** who wants to. 
+**
+** Last update: 19 Aug 1992
+**
+** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#ifndef __ERROR_H__
+#define __ERROR_H__
+
+#include <syslog.h>
+
+#define ERROR(fmt) \
+    ((syslog_flag ? (syslog(LOG_ERR, fmt),0) : 0), \
+     (debug_flag ? (fprintf(stderr, "%d , %d : ERROR : X-DBG : ", \
+			    lport, fport), \
+		    fprintf(stderr, fmt), perror(": "), 0) : \
+      (printf("%d , %d : ERROR : UNKNOWN-ERROR\r\n", lport, fport), 0)), \
+     fflush(stdout), fflush(stderr), exit(1), 0)
+
+
+#define ERROR1(fmt,v1) \
+    ((syslog_flag ? (syslog(LOG_ERR, fmt, v1),0) : 0), \
+     (debug_flag ? (fprintf(stderr, "%d , %d : ERROR : X-DBG : ", \
+			    lport, fport), \
+		    fprintf(stderr, fmt, v1), perror(": "), 0) : \
+      (printf("%d , %d : ERROR : UNKNOWN-ERROR\r\n", lport, fport), 0)), \
+     fflush(stdout), fflush(stderr), exit(1), 0)
+
+#define ERROR2(fmt,v1,v2) \
+    ((syslog_flag ? (syslog(LOG_ERR, fmt, v1, v2),0) : 0), \
+     (debug_flag ? (fprintf(stderr, "%d , %d : ERROR : X-DBG : ", \
+			    lport, fport), \
+		    fprintf(stderr, fmt, v1, v2), perror(": "), 0) : \
+      (printf("%d , %d : ERROR : UNKNOWN-ERROR\r\n", lport, fport), 0)), \
+     fflush(stdout), fflush(stderr), exit(1), 0)
+
+#endif
diff --git a/identd.tproj/identd.8 b/identd.tproj/identd.8
new file mode 100644
index 0000000..4bf839c
--- /dev/null
+++ b/identd.tproj/identd.8
@@ -0,0 +1,238 @@
+.\" @(#)identd.8 1.9 92/02/11 Lysator
+.\" Copyright (c) 1992 Peter Eriksson, Lysator, Linkoping University.
+.\" This software has been released into the public domain.
+.\"
+.\"	$Id: identd.8,v 1.1.1.1 1999/05/02 03:57:41 wsanchez Exp $
+.\"
+.TH IDENTD 8 "27 May 1992"
+.SH NAME
+identd \- TCP/IP IDENT protocol server
+.SH SYNOPSIS
+.B identd
+.RB [ \-i | \-w | \-b ]
+.RB [ \-t<seconds> ]
+.RB [ \-u<uid> ]
+.RB [ \-g<gid> ]
+.RB [ \-p<port> ]
+.RB [ \-a<address> ]
+.RB [ \-c<charset> ]
+.RB [ \-n ]
+.RB [ \-o ]
+.RB [ \-e ]
+.RB [ \-l ]
+.RB [ \-V ]
+.RB [ \-v ]
+.RB [ \-m ]
+.RB [ \-N ]
+.RB [ \-d ]
+.RB [ kernelfile [ kmemfile ] ]
+.SH DESCRIPTION
+.IX "identd daemon" "" \fLidentd\fP daemon"
+.B identd
+is a server which implements the
+.SM TCP/IP
+proposed standard
+.SM IDENT
+user identification protocol as specified in the
+.SM RFC\s0 1413
+document.
+.PP
+.B identd
+operates by looking up specific
+.SM TCP/IP
+connections and returning the user name of the
+process owning the connection.
+.SH ARGUMENTS
+The
+.B -i
+flag, which is the default mode, should be used when starting the
+daemon from
+.B inetd
+with the "nowait" option in the
+.B /etc/inetd.conf
+file. Use of this mode will make
+.B inetd
+start one
+.B identd
+daemon for each connection request.
+.PP
+The
+.B -w
+flag should be used when starting the daemon from
+.B inetd
+with the "wait" option in the
+.B /etc/inetd.conf
+file . This is the prefered mode of
+operation since that will start a copy of
+.B identd
+at the first connection request and then
+.B identd
+will handle subsequent requests
+without having to do the nlist lookup in the kernel file for
+every request as in the
+.B -i
+mode above. The
+.B identd
+daemon will run either forever, until a bug
+makes it crash or a timeout, as specified by the
+.B -t
+flag, occurs.
+.PP
+The
+.B -b
+flag can be used to make the daemon run in standalone mode without
+the assistance from
+.B inetd.
+This mode is the least prefered mode since
+a bug or any other fatal condition in the server will make it terminate
+and it will then have to be restarted manually. Other than that is has the
+same advantage as the
+.B -w
+mode in that it parses the nlist only once.
+.PP
+The
+.B -t<seconds>
+option is used to specify the timeout limit. This is the number
+of seconds a server started with the
+.B -w
+flag will wait for new connections before terminating. The server is
+automatically restarted by
+.B inetd
+whenever a new connection is requested
+if it has terminated. A suitable value for this is 120 (2 minutes), if
+used. It defaults to no timeout (ie, will wait forever, or until a
+fatal condition occurs in the server).
+.PP
+The
+.B -u<uid>
+option is used to specify a user id number which the
+.B ident
+server should
+switch to after binding itself to the
+.SM TCP/IP
+port if using the
+.B -b
+mode of operation.
+.PP
+The
+.B -g<gid>
+option is used to specify a group id number which the
+.B ident
+server should
+switch to after binding itself to the
+.SM TCP/IP
+port if using the
+.B -b
+mode of operation.
+.PP
+The
+.B -p<port>
+option is used to specify an alternative port number to bind to if using
+the
+.B -b
+mode of operation. It can be specified by name or by number. Defaults to the
+.SM IDENT
+port (113).
+.PP
+The
+.B -a<address>
+option is used to specify the local address to bind the socket to if using
+the
+.B -b
+mode of operation. Can only be specified by IP address and not by domain
+name. Defaults to the 
+.SM INADDR_ANY
+address which normally means all local addresses.
+.PP
+The 
+.B -V
+flag makes
+.B identd
+display the version number and the exit.
+.PP
+The
+.B -l
+flag tells
+.B identd
+to use the System logging daemon
+.B syslogd
+for logging purposes.
+.PP
+The 
+.B -v
+flag causes
+.B identd
+to log every request made, if the use of
+.B syslogd
+is enabled.
+.PP
+The
+.B -o
+flag tells
+.B identd
+to not reveal the operating system type it is run on and to instead
+always return "OTHER".
+.PP
+The
+.B -e
+flag tells
+.B identd
+to always return "UNKNOWN-ERROR" instead of the "NO-USER" or
+"INVALID-PORT" errors.
+.PP
+The
+.B -c<charset>
+flags tells
+.B identd
+to add the optional (according to the IDENT protocol) character set
+designator to the reply generated. <charset> should be a valid character
+set as described in the MIME RFC in upper case characters.
+.PP
+The
+.B -n
+flags tells
+.B identd
+to always return user numbers instead of user names if you wish to
+keep the user names a secret.
+.PP
+The
+.B -N
+flag makes
+.B identd
+check for a file ".noident" in each homedirectory for a user which the
+daemon is about to return the user name for. It that file exists then the
+daemon will give the error
+.B HIDDEN-USER
+instead of the normal USERID response. 
+.PP
+.B -m
+flag makes
+.B identd
+use a mode of operation that will allow multiple requests to be
+processed per session. Each request is specified one per line and
+the responses will be returned one per line. The connection will not
+be closed until the connecting part closes it's end of the line.
+PLEASE NOTE THAT THIS MODE VIOLATES THE PROTOCOL SPECIFICATION AS
+IT CURRENTLY STANDS.
+.PP
+The
+.B -d
+flag enables some debugging code that normally should NOT
+be enabled since that breaks the protocol and may reveal information
+that should not be available to outsiders.
+.PP
+.B kernelfile
+defaults to the normally running kernel file.
+.PP
+.B kmemfile
+defaults to the memory space of the normally running kernel.
+.SH SEE ALSO
+.BR inetd.conf (5)
+.SH BUGS
+The handling of fatal errors could be better.
+.PP
+If the
+.B -N
+flag is specified and a user's ".noident" file is not accessible,
+then ident information regarding that user will be returned
+if requested.
diff --git a/identd.tproj/identd.c b/identd.tproj/identd.c
new file mode 100644
index 0000000..7380de1
--- /dev/null
+++ b/identd.tproj/identd.c
@@ -0,0 +1,643 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+**	$Id: identd.c,v 1.1.1.2 2000/01/11 01:48:48 wsanchez Exp $
+**
+** identd.c                       A TCP/IP link identification protocol server
+**
+** This program is in the public domain and may be used freely by anyone
+** who wants to. 
+**
+** Last update: 22 April 1993
+**
+** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#if defined(IRIX) || defined(SVR4) || defined(__APPLE__) || defined(__NetBSD__)
+#  define SIGRETURN_TYPE void
+#  define SIGRETURN_TYPE_IS_VOID
+#else
+#  define SIGRETURN_TYPE int
+#endif
+
+#ifdef SVR4
+#  define STRNET
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifndef _AUX_SOURCE
+#  include <sys/file.h>
+#endif
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <pwd.h>
+#include <grp.h>
+
+#include <netinet/in.h>
+
+#ifndef HPUX7
+#  include <arpa/inet.h>
+#endif
+
+#if defined(MIPS) || defined(BSD43)
+extern int errno;
+#endif
+
+#include "identd.h"
+#include "error.h"
+
+/* Antique unixes do not have these things defined... */
+#ifndef FD_SETSIZE
+#  define FD_SETSIZE 256
+#endif
+
+#ifndef FD_SET
+#  ifndef NFDBITS
+#    define NFDBITS   	(sizeof(int) * NBBY)  /* bits per mask */
+#  endif
+#  define FD_SET(n, p)  ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#endif
+
+#ifndef FD_ZERO
+#  define FD_ZERO(p)        bzero((char *)(p), sizeof(*(p)))
+#endif
+
+extern char *version;
+
+extern void *calloc();
+extern void *malloc();
+
+
+char *path_unix = NULL;
+char *path_kmem = NULL;
+
+int verbose_flag = 0;
+int debug_flag   = 0;
+int syslog_flag  = 0;
+int multi_flag   = 0;
+int other_flag   = 0;
+int unknown_flag = 0;
+int number_flag  = 0;
+int noident_flag = 0;
+
+int lport = 0;
+int fport = 0;
+
+char *charset_name = NULL;
+char *indirect_host = NULL;
+char *indirect_password = NULL;
+
+static int child_pid;
+
+#ifdef LOG_DAEMON
+static int syslog_facility = LOG_DAEMON;
+#endif
+
+/*
+** The structure passing convention for GCC is incompatible with
+** Suns own C compiler, so we define our own inet_ntoa() function.
+** (This should only affect GCC version 1 I think, a well, this works
+** for version 2 also so why bother.. :-)
+*/
+#if defined(__GNUC__) && defined(__sparc__)
+
+#ifdef inet_ntoa
+#undef inet_ntoa
+#endif
+
+char *inet_ntoa(ad)
+  struct in_addr ad;
+{
+  unsigned long int s_ad;
+  int a, b, c, d;
+  static char addr[20];
+  
+  s_ad = ad.s_addr;
+  d = s_ad % 256;
+  s_ad /= 256;
+  c = s_ad % 256;
+  s_ad /= 256;
+  b = s_ad % 256;
+  a = s_ad / 256;
+  sprintf(addr, "%d.%d.%d.%d", a, b, c, d);
+  
+  return addr;
+}
+#endif
+
+
+/*
+** Return the name of the connecting host, or the IP number as a string.
+*/
+char *gethost(addr)
+  struct in_addr *addr;
+{
+  struct hostent *hp;
+
+  
+  hp = gethostbyaddr((char *) addr, sizeof(struct in_addr), AF_INET);
+  if (hp)
+    return hp->h_name;
+  else
+    return inet_ntoa(*addr);
+}
+
+/*
+** Exit cleanly after our time's up.
+*/
+static SIGRETURN_TYPE
+alarm_handler()
+{
+  if (syslog_flag)
+    syslog(LOG_DEBUG, "SIGALRM triggered, exiting");
+  
+  exit(0);
+}
+
+#if !defined(hpux) && !defined(__hpux) && !defined(SVR4) || defined(_CRAY)
+/*
+** This is used to clean up zombie child processes
+** if the -w or -b options are used.
+*/
+static SIGRETURN_TYPE
+child_handler()
+{
+#if defined(IRIX) || defined(__APPLE__)
+  union wait status;
+#else
+  int status;
+#endif
+
+  while (wait3(&status, WNOHANG, NULL) > 0)
+    ;
+  
+#ifndef SIGRETURN_TYPE_IS_VOID
+  return 0;
+#endif
+}
+#endif
+
+
+char *clearmem(bp, len)
+  char *bp;
+  int len;
+{
+  char *cp;
+
+  cp = bp;
+  while (len-- > 0)
+    *cp++ = 0;
+
+  return bp;
+}
+
+
+/*
+** Main entry point into this daemon
+*/
+int main(argc,argv)
+  int argc;
+  char *argv[];
+{
+  int i, len;
+  struct sockaddr_in sin;
+  struct in_addr laddr, faddr;
+  struct timeval tv;
+
+  int background_flag = 0;
+  int timeout = 0;
+  char *portno = "113";
+  char *bind_address = NULL;
+  int set_uid = 0;
+  int set_gid = 0;
+  int inhibit_default_config = 0;
+  int opt_count = 0;		/* Count of option flags */
+  
+#ifdef __convex__
+  argc--;    /* get rid of extra argument passed by inetd */
+#endif
+
+  /*
+  ** Prescan the arguments for "-f<config-file>" switches
+  */
+  inhibit_default_config = 0;
+  for (i = 1; i < argc && argv[i][0] == '-'; i++)
+    if (argv[i][1] == 'f')
+      inhibit_default_config = 1;
+
+  /*
+  ** Parse the default config file - if it exists
+  */
+  if (!inhibit_default_config)
+    parse_config(NULL, 1);
+  
+  /*
+  ** Parse the command line arguments
+  */
+  for (i = 1; i < argc && argv[i][0] == '-'; i++) {
+    opt_count++;
+    switch (argv[i][1])
+    {
+      case 'b':    /* Start as standalone daemon */
+        background_flag = 1;
+	break;
+
+      case 'w':    /* Start from Inetd, wait mode */
+	background_flag = 2;
+	break;
+
+      case 'i':    /* Start from Inetd, nowait mode */
+	background_flag = 0;
+	break;
+
+      case 't':
+	timeout = atoi(argv[i]+2);
+	break;
+
+      case 'p':
+	portno = argv[i]+2;
+	break;
+
+      case 'a':
+	bind_address = argv[i]+2;
+	break;
+	  
+      case 'u':
+	if (isdigit(argv[i][2]))
+	  set_uid = atoi(argv[i]+2);
+	else
+ 	{
+	  struct passwd *pwd;
+
+	  pwd = getpwnam(argv[i]+2);
+	  if (!pwd)
+	    ERROR1("no such user (%s) for -u option", argv[i]+2);
+	  else
+	  {
+	    set_uid = pwd->pw_uid;
+	    set_gid = pwd->pw_gid;
+	  }
+	}
+	break;
+	
+      case 'g':
+	if (isdigit(argv[i][2]))
+	  set_gid = atoi(argv[i]+2);
+	else
+ 	{
+	  struct group *grp;
+
+	  grp = getgrnam(argv[i]+2);
+	  if (!grp)
+	    ERROR1("no such group (%s) for -g option", argv[i]+2);
+	  else
+	    set_gid = grp->gr_gid;
+	}
+	break;
+
+      case 'c':
+	charset_name = argv[i]+2;
+	break;
+
+      case 'r':
+	indirect_host = argv[i]+2;
+	break;
+
+      case 'l':    /* Use the Syslog daemon for logging */
+	syslog_flag++;
+	break;
+
+      case 'o':
+	other_flag = 1;
+	break;
+
+      case 'e':
+	unknown_flag = 1;
+	break;
+
+      case 'n':
+	number_flag = 1;
+	break;
+       
+      case 'V':    /* Give version of this daemon */
+	printf("[in.identd, version %s]\r\n", version);
+	exit(0);
+	break;
+
+      case 'v':    /* Be verbose */
+	verbose_flag++;
+	break;
+	  
+      case 'd':    /* Enable debugging */
+	debug_flag++;
+	break;
+
+      case 'm':    /* Enable multiline queries */
+	multi_flag++;
+	break;
+
+      case 'N':    /* Enable users ".noident" files */
+	noident_flag++;
+	break;
+    }
+  }
+  
+#if defined(_AUX_SOURCE) || defined (SUNOS35)
+  /* A/UX 2.0* & SunOS 3.5 calls us with an argument XXXXXXXX.YYYY
+  ** where XXXXXXXXX is the hexadecimal version of the callers
+  ** IP number, and YYYY is the port/socket or something.
+  ** It seems to be impossible to pass arguments to a daemon started
+  ** by inetd.
+  **
+  ** Just in case it is started from something else, then we only
+  ** skip the argument if no option flags have been seen.
+  */
+  if (opt_count == 0)
+    argc--;
+#endif
+
+  /*
+  ** Path to kernel namelist file specified on command line
+  */
+  if (i < argc)
+    path_unix = argv[i++];
+
+  /*
+  ** Path to kernel memory device specified on command line
+  */
+  if (i < argc)
+    path_kmem = argv[i++];
+
+
+  /*
+  ** Open the kernel memory device and read the nlist table
+  */
+  if (k_open() < 0)
+      ERROR("main: k_open");
+
+  /*
+  ** Do the special handling needed for the "-b" flag
+  */
+  if (background_flag == 1)
+  {
+    struct sockaddr_in addr;
+    struct servent *sp;
+    int fd;
+
+    
+    if (fork())
+      exit(0);
+
+    close(0);
+    close(1);
+    close(2);
+
+    if (fork())
+      exit(0);
+    
+    fd = socket(AF_INET, SOCK_STREAM, 0);
+    if (fd == -1)
+      ERROR("main: socket");
+    
+    if (fd != 0)
+      dup2(fd, 0);
+
+    clearmem(&addr, sizeof(addr));
+    
+    addr.sin_family = AF_INET;
+    if (bind_address == NULL)
+      addr.sin_addr.s_addr = htonl(INADDR_ANY);
+    else
+    {
+      if (isdigit(bind_address[0]))
+	addr.sin_addr.s_addr = inet_addr(bind_address);
+      else
+      {
+	struct hostent *hp;
+
+	hp = gethostbyname(bind_address);
+	if (!hp)
+	  ERROR1("no such address (%s) for -a switch", bind_address);
+
+	/* This is ugly, should use memcpy() or bcopy() but... */
+	addr.sin_addr.s_addr = * (unsigned long *) (hp->h_addr);
+      }
+    }
+
+    if (isdigit(portno[0]))
+      addr.sin_port = htons(atoi(portno));
+    else
+    {
+      sp = getservbyname(portno, "tcp");
+      if (sp == NULL)
+	ERROR1("main: getservbyname: %s", portno);
+      addr.sin_port = sp->s_port;
+    }
+    
+    if (bind(0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
+      ERROR("main: bind");
+
+    if (listen(0, 3) < 0)
+      ERROR("main: listen");
+  }
+  
+  if (set_gid)
+    if (setgid(set_gid) == -1)
+      ERROR("main: setgid");
+  
+  if (set_uid)
+    if (setuid(set_uid) == -1)
+      ERROR("main: setuid");
+
+  /*
+  ** Do some special handling if the "-b" or "-w" flags are used
+  */
+  if (background_flag)
+  {
+    int nfds, fd;
+    fd_set read_set;
+
+
+    /*
+    ** Set up the SIGCHLD signal child termination handler so
+    ** that we can avoid zombie processes hanging around and
+    ** handle childs terminating before being able to complete the
+    ** handshake.
+    */
+#if (defined(SVR4) || defined(hpux) || defined(__hpux) || \
+     defined(_CRAY) || defined(_AUX_SOURCE))
+    signal(SIGCHLD, SIG_IGN);
+#else
+    signal(SIGCHLD, (SIGRETURN_TYPE (*)()) child_handler);
+#endif
+    
+    /*
+    ** Loop and dispatch client handling processes
+    */
+    do
+    {
+      /*
+      ** Terminate if we've been idle for 'timeout' seconds
+      */
+      if (background_flag == 2 && timeout)
+      {
+	signal(SIGALRM, alarm_handler);
+	alarm(timeout);
+      }
+      
+      /*
+      ** Wait for a connection request to occur.
+      ** Ignore EINTR (Interrupted System Call).
+      */
+      do
+      {
+	FD_ZERO(&read_set);
+	FD_SET(0, &read_set);
+
+	if (timeout)
+	{
+	  tv.tv_sec = timeout;
+	  tv.tv_usec = 0;
+	  nfds = select(FD_SETSIZE, &read_set, NULL, NULL, &tv);
+	}
+	else
+
+	nfds = select(FD_SETSIZE, &read_set, NULL, NULL, NULL);
+      } while (nfds < 0  && errno == EINTR);
+
+      /*
+      ** An error occured in select? Just die
+      */
+      if (nfds < 0)
+	ERROR("main: select");
+
+      /*
+      ** Timeout limit reached. Exit nicely
+      */
+      if (nfds == 0)
+	exit(0);
+      
+      /*
+      ** Disable the alarm timeout
+      */
+      alarm(0);
+      
+      /*
+      ** Accept the new client
+      */
+      fd = accept(0, NULL, NULL);
+      if (fd == -1)
+	ERROR1("main: accept. errno = %d", errno);
+      
+      /*
+      ** And fork, then close the fd if we are the parent.
+      */
+      child_pid = fork();
+    } while (child_pid && (close(fd), 1));
+
+    /*
+    ** We are now in child, the parent has returned to "do" above.
+    */
+    if (dup2(fd, 0) == -1)
+      ERROR("main: dup2: failed fd 0");
+    
+    if (dup2(fd, 1) == -1)
+      ERROR("main: dup2: failed fd 1");
+    
+    if (dup2(fd, 2) == -1)
+      ERROR("main: dup2: failed fd 2");
+  }
+
+  /*
+  ** Get foreign internet address
+  */
+  len = sizeof(sin);
+  if (getpeername(0, (struct sockaddr *) &sin, &len) == -1)
+  {
+    /*
+    ** A user has tried to start us from the command line or
+    ** the network link died, in which case this message won't
+    ** reach to other end anyway, so lets give the poor user some
+    ** errors.
+    */
+    perror("in.identd: getpeername()");
+    exit(1);
+  }
+  
+  faddr = sin.sin_addr;
+
+
+  /*
+  ** Open the connection to the Syslog daemon if requested
+  */
+  if (syslog_flag)
+  {
+#ifdef LOG_DAEMON
+    openlog("identd", LOG_PID, syslog_facility);
+#else
+    openlog("identd", LOG_PID);
+#endif
+    
+    syslog(LOG_INFO, "Connection from %s", gethost(&faddr));
+  }
+  
+
+  /*
+  ** Get local internet address
+  */
+  len = sizeof(sin);
+#ifdef ATTSVR4
+  if (t_getsockname(0, (struct sockaddr *) &sin, &len) == -1)
+#else
+  if (getsockname(0, (struct sockaddr *) &sin, &len) == -1)
+#endif
+  {
+    /*
+    ** We can just die here, because if this fails then the
+    ** network has died and we haven't got anyone to return
+    ** errors to.
+    */
+    exit(1);
+  }
+  laddr = sin.sin_addr;
+
+
+  /*
+  ** Get the local/foreign port pair from the luser
+  */
+  parse(stdin, &laddr, &faddr);
+
+  exit(0);
+}
diff --git a/identd.tproj/identd.h b/identd.tproj/identd.h
new file mode 100644
index 0000000..61ece7c
--- /dev/null
+++ b/identd.tproj/identd.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+**	$Id: identd.h,v 1.1.1.1 1999/05/02 03:57:41 wsanchez Exp $
+**
+** identd.h                 Common variables for the Pidentd daemon
+**
+** This program is in the public domain and may be used freely by anyone
+** who wants to. 
+**
+** Last update: 6 Dec 1992
+**
+** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#ifndef __IDENTD_H__
+#define __IDENTD_H__
+
+extern char *version;
+
+extern char *path_unix;
+extern char *path_kmem;
+
+extern int verbose_flag;
+extern int debug_flag;
+extern int syslog_flag;
+extern int multi_flag;
+extern int other_flag;
+extern int unknown_flag;
+extern int number_flag;
+extern int noident_flag;
+
+extern char *charset_name;
+extern char *indirect_host;
+extern char *indirect_password;
+
+extern int lport;
+extern int fport;
+
+extern char *gethost();
+
+extern int k_open();
+extern int k_getuid();
+extern int parse();
+extern int parse_config();
+
+#endif
diff --git a/identd.tproj/netbsd.c b/identd.tproj/netbsd.c
new file mode 100644
index 0000000..83626a4
--- /dev/null
+++ b/identd.tproj/netbsd.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+**	$Id: netbsd.c,v 1.1.1.2 2000/01/11 01:48:48 wsanchez Exp $
+**
+** netbsd.c		Low level kernel access functions for NetBSD
+**
+** This program is in the public domain and may be used freely by anyone
+** who wants to. 
+**
+** Last update: 17 March 1993
+**
+** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#include <nlist.h>
+#include <pwd.h>
+#include <signal.h>
+#include <syslog.h>
+
+#include "kvm.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <sys/socketvar.h>
+
+#define KERNEL
+
+#include <sys/file.h>
+
+#undef KERNEL
+#include <sys/sysctl.h>
+
+#include <fcntl.h>
+
+#include <sys/user.h>
+
+#include <sys/wait.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <netinet/in_pcb.h>
+
+#include <netinet/tcp.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+
+#include <arpa/inet.h>
+
+#include "identd.h"
+#include "error.h"
+
+
+extern void *calloc();
+extern void *malloc();
+
+
+struct nlist nl[] =
+{
+#define N_FILE 0
+#define N_NFILE 1
+#define N_TCB 2
+      
+  { "_filehead" },
+  { "_nfiles" },
+  { "_tcb" },
+  { "" }
+};
+
+static kvm_t *kd;
+
+static struct file *xfile;
+static int nfile;
+
+static struct inpcbhead tcb;
+  
+
+int k_open()
+{
+  /*
+  ** Open the kernel memory device
+  */
+  if ((kd = kvm_openfiles(path_unix, path_kmem, NULL, O_RDONLY, "identd")) ==
+      NULL)
+    ERROR("main: kvm_open");
+  
+  /*
+  ** Extract offsets to the needed variables in the kernel
+  */
+  if (kvm_nlist(kd, nl) < 0)
+    ERROR("main: kvm_nlist");
+
+  return 0;
+}
+
+
+/*
+** Get a piece of kernel memory with error handling.
+** Returns 1 if call succeeded, else 0 (zero).
+*/
+static int getbuf(addr, buf, len, what)
+  long addr;
+  char *buf;
+  int len;
+  char *what;
+{
+  if (kvm_read(kd, addr, buf, len) < 0)
+  {
+    if (syslog_flag)
+      syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
+	     addr, len, what);
+
+    return 0;
+  }
+  
+  return 1;
+}
+
+
+
+/*
+** Traverse the inpcb list until a match is found.
+** Returns NULL if no match.
+*/
+static struct socket *
+    getlist(pcbp_head, faddr, fport, laddr, lport)
+  struct inpcbhead *pcbp_head;
+  struct in_addr *faddr;
+  int fport;
+  struct in_addr *laddr;
+  int lport;
+{
+  struct inpcb *pcbp;
+  struct inpcb pcb;
+
+  pcbp = pcbp_head->lh_first;
+  while (pcbp &&
+	   getbuf((long) pcbp,
+		  &pcb,
+		  sizeof(struct inpcb),
+		  "tcblist"))
+   {
+      if ( pcb.inp_faddr.s_addr == faddr->s_addr &&
+	   pcb.inp_laddr.s_addr == laddr->s_addr &&
+	   pcb.inp_fport        == fport &&
+	   pcb.inp_lport        == lport )
+	  return pcb.inp_socket;
+
+      pcbp = pcb.inp_list.le_next;
+  } 
+
+  return NULL;
+}
+
+
+
+/*
+** Return the user number for the connection owner
+*/
+int k_getuid(faddr, fport, laddr, lport, uid)
+  struct in_addr *faddr;
+  int fport;
+  struct in_addr *laddr;
+  int lport;
+  int *uid;
+{
+  long addr;
+  struct socket *sockp;
+  int i, mib[2];
+  struct ucred ucb;
+  
+  /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
+  if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
+    return -1;
+  
+  if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
+    return -1;
+
+  {
+    int siz, rv;
+
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_FILE;
+    if ((rv = sysctl(mib, 2, NULL, &siz, NULL, 0)) == -1)
+    {
+      ERROR1("k_getuid: sysctl 1 (%d)", rv);
+      return -1;
+    }
+    xfile = malloc(siz);
+    if (!xfile)
+      ERROR1("k_getuid: malloc(%d)", siz);
+    if ((rv = sysctl(mib, 2, xfile, &siz, NULL, 0)) == -1)
+    {
+      ERROR1("k_getuid: sysctl 2 (%d)", rv);
+      return -1;
+    }
+    xfile = (struct file *)((char *)xfile + sizeof(filehead));
+  }
+  
+  /* -------------------- TCP PCB LIST -------------------- */
+  if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
+    return -1;
+  
+  sockp = getlist(&tcb, faddr, fport, laddr, lport);
+  
+  if (!sockp)
+    return -1;
+
+  /*
+  ** Locate the file descriptor that has the socket in question
+  ** open so that we can get the 'ucred' information
+  */
+  for (i = 0; i < nfile; i++)
+  {
+    if (xfile[i].f_count == 0)
+      continue;
+    
+    if (xfile[i].f_type == DTYPE_SOCKET &&
+	(struct socket *) xfile[i].f_data == sockp)
+    {
+      if (!getbuf(xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
+	return -1;
+
+      *uid = ucb.cr_uid;
+      return 0;
+    }
+  }
+
+  return -1;
+}
+
diff --git a/identd.tproj/parse.c b/identd.tproj/parse.c
new file mode 100644
index 0000000..2d978ad
--- /dev/null
+++ b/identd.tproj/parse.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+**	$Id: parse.c,v 1.2 2000/10/03 02:38:32 lindak Exp $
+**
+** parse.c                         This file contains the protocol parser
+**
+** This program is in the public domain and may be used freely by anyone
+** who wants to. 
+**
+** Last update: 6 Dec 1992
+**
+** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#include <pwd.h>
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#ifndef HPUX7
+#  include <arpa/inet.h>
+#endif
+
+#include <nlist.h>
+#include <kvm.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(MIPS) || defined(BSD43)
+extern int errno;
+#endif
+
+#include "identd.h"
+#include "error.h"
+
+extern void *malloc();
+
+/*
+** This function will eat whitespace characters until
+** either a non-whitespace character is read, or EOF
+** occurs. This function is only used if the "-m" option
+** is enabled.
+*/
+static int eat_whitespace()
+{
+  int c;
+
+  
+  while ((c = getchar()) != EOF &&
+	 !(c == '\r' || c == '\n'))
+    ;
+
+  if (c != EOF)
+    while ((c = getchar()) != EOF &&
+	   (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
+      ;
+
+  if (c != EOF)
+    ungetc(c, stdin);
+  
+  return (c != EOF);
+}
+
+
+#ifdef INCLUDE_EXTENSIONS
+/*
+** Validate an indirect request
+*/
+static int valid_fhost(faddr, password)
+  struct in_addr *faddr;
+  char *password;
+{
+  if (indirect_host == NULL)
+    return 0;
+
+  if (strcmp(indirect_host, "*") != 0)
+  {
+    if (isdigit(indirect_host[0]))
+    {
+      if (strcmp(inet_ntoa(*faddr), indirect_host))
+      {
+	syslog(LOG_NOTICE, "valid_fhost: access denied for: %s",
+	       gethost(faddr));
+	return 0;
+      }
+    }
+    else
+    {
+      if (strcmp(gethost(faddr), indirect_host))
+      {
+	syslog(LOG_NOTICE, "valid_fhost: access denied for: %s",
+	       gethost(faddr));
+	return 0;
+      }
+    }
+  }
+      
+  if (indirect_password == NULL)
+    return 1;
+  
+  if (strcmp(password, indirect_password))
+  {
+    syslog(LOG_NOTICE, "valid_fhost: invalid password from: %s",
+	   gethost(faddr));
+    return 0;
+  }
+
+  return 1;
+}
+#endif
+
+/*
+** A small routine to check for the existance of the ".noident"
+** file in a users home directory.
+*/
+static int check_noident(homedir)
+  char *homedir;
+{
+  char *tmp_path;
+  struct stat sbuf;
+  int rcode;
+  
+
+  if (!homedir)
+    return 0;
+  
+  tmp_path = (char *) malloc(strlen(homedir) + sizeof("/.noident") + 1);
+  if (!tmp_path)
+    return 0;
+
+  strcpy(tmp_path, homedir);
+  strcat(tmp_path, "/.noident");
+
+  rcode = stat(tmp_path, &sbuf);
+  free(tmp_path);
+
+  return (rcode == 0);
+}
+
+
+int parse(fp, laddr, faddr)
+  FILE *fp;
+  struct in_addr *laddr, *faddr;
+{
+  int uid, try, rcode;
+  struct passwd *pwp;
+  char lhostaddr[16];
+  char fhostaddr[16];
+  char password[33];
+#ifdef INCLUDE_EXTENSIONS  
+  char arg[33];
+  int c;
+#endif
+  struct in_addr laddr2;
+  struct in_addr faddr2;
+  
+  
+  if (debug_flag && syslog_flag)
+    syslog(LOG_DEBUG, "In function parse()");
+  
+  /*
+  ** Get the local/foreign port pair from the luser
+  */
+  do
+  {
+    if (debug_flag && syslog_flag)
+      syslog(LOG_DEBUG, "  Before fscanf()");
+    
+    faddr2 = *faddr;
+    laddr2 = *laddr;
+    lport = fport = 0;
+    lhostaddr[0] = fhostaddr[0] = password[0] = '\0';
+
+    /* Read query from client */
+    rcode = fscanf(fp, " %d , %d", &lport, &fport);
+
+#ifdef INCLUDE_EXTENSIONS
+    /*
+    ** Do additional parsing in case of extended request
+    */
+    if (rcode == 0)
+    {
+      rcode = fscanf(fp, "%32[^ \t\n\r:]", arg);
+
+      /* Skip leading space up to EOF, EOL or non-space char */
+      while ((c = getc(fp)) == ' ' || c == '\t')
+	;
+      
+      if (rcode <= 0)
+      {
+	printf("%d , %d : ERROR : %s\r\n",
+	       lport, fport,
+	       unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
+	continue;
+      }
+
+      /*
+      ** Non-standard extended request, returns with Pidentd
+      ** version information
+      */
+      if (strcmp(arg, "VERSION") == 0)
+      {
+	printf("%d , %d : ERROR : X-VERSION : %s\r\n", lport, fport,
+	       version);
+	continue;
+      }
+
+      /*
+      ** Non-standard extended proxy request
+      */
+      else if (strcmp(arg, "PROXY") == 0 && c == ':')
+      {
+	/* We have a colon char, check for port numbers */
+	rcode = fscanf(fp, " %d , %d : %15[0-9.] , %15[0-9.]",
+		       &lport, &fport, fhostaddr, lhostaddr);
+
+	if (!(rcode == 3 || rcode == 4))
+	{
+	  printf("%d , %d : ERROR : %s\r\n",
+		 lport, fport,
+		 unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
+	  continue;
+	}
+
+	if (rcode == 4)
+	  laddr2.s_addr = inet_addr(lhostaddr);
+	
+	faddr2.s_addr = inet_addr(fhostaddr);
+
+	proxy(&laddr2, &faddr2, lport, fport, NULL);
+	continue;
+      }
+      
+      /*
+      ** Non-standard extended remote indirect request
+      */
+      else if (strcmp(arg, "REMOTE") == 0 && c == ':')
+      {
+	/* We have a colon char, check for port numbers */
+	rcode = fscanf(fp, " %d , %d", &lport, &fport);
+	
+	/* Skip leading space up to EOF, EOL or non-space char */
+	while ((c = getc(fp)) == ' ' || c == '\t')
+	  ;
+
+	if (rcode != 2 || c != ':')
+	{
+	  printf("%d , %d : ERROR : %s\r\n",
+		 lport, fport,
+		 unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
+	  continue;
+	}
+	    
+	/* We have a colon char, check for addr and password */
+	rcode = fscanf(fp, " %15[0-9.] , %32[^ \t\r\n]",
+		       fhostaddr, password);
+	if (rcode > 0)
+	  rcode += 2;
+	else
+	{
+	  printf("%d , %d : ERROR : %s\r\n",
+		 lport, fport,
+		 unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
+	  continue;
+	}
+	
+	/*
+	** Verify that the host originating the indirect request
+	** is allowed to do that
+	*/
+	if (!valid_fhost(faddr, password))
+	{
+	  printf("%d , %d : ERROR : %s\r\n",
+		 lport, fport,
+		 unknown_flag ? "UNKNOWN-ERROR" : "X-ACCESS-DENIED");
+	  continue;
+	}
+	
+	faddr2.s_addr = inet_addr(fhostaddr);
+      }
+      
+      else
+      {
+	printf("%d , %d : ERROR : %s\r\n",
+	       lport, fport,
+	       unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
+	continue;
+      }
+    }
+#endif /* EXTENSIONS */
+    
+    if (rcode < 2 || lport < 1 || lport > 65535 || fport < 1 || fport > 65535)
+    {
+      if (syslog_flag && rcode > 0)
+	syslog(LOG_NOTICE, "scanf: invalid-port(s): %d , %d from %s",
+	       lport, fport, gethost(faddr));
+      
+      printf("%d , %d : ERROR : %s\r\n",
+	     lport, fport,
+	     unknown_flag ? "UNKNOWN-ERROR" : "INVALID-PORT");
+      continue;
+    }
+
+    if (syslog_flag && verbose_flag)
+	syslog(LOG_NOTICE, "request for (%d,%d) from %s",
+	       lport, fport, gethost(faddr));
+
+    if (debug_flag && syslog_flag)
+      syslog(LOG_DEBUG, "  After fscanf(), before k_getuid()");
+    
+    /*
+    ** Next - get the specific TCP connection and return the
+    ** uid - user number.
+    **
+    ** Try to fetch the information 5 times incase the
+    ** kernel changed beneath us and we missed or took
+    ** a fault.
+    */
+    for (try = 0;
+	 (try < 5 &&
+	   k_getuid(&faddr2, htons(fport), laddr, htons(lport), &uid) == -1);
+	 try++)
+      ;
+
+    if (try >= 5)
+    {
+      if (syslog_flag)
+	syslog(LOG_DEBUG, "Returned: %d , %d : NO-USER", lport, fport);
+      
+      printf("%d , %d : ERROR : %s\r\n",
+	     lport, fport,
+	     unknown_flag ? "UNKNOWN-ERROR" : "NO-USER");
+      continue;
+    }
+
+    if (try > 0 && syslog_flag)
+      syslog(LOG_NOTICE, "k_getuid retries: %d", try);
+    
+    if (debug_flag && syslog_flag)
+      syslog(LOG_DEBUG, "  After k_getuid(), before getpwuid()");
+
+    /*
+    ** Then we should try to get the username. If that fails we
+    ** return it as an OTHER identifier
+    */
+    pwp = getpwuid(uid);
+    
+    if (!pwp)
+    {
+      if (syslog_flag)
+	syslog(LOG_WARNING, "getpwuid() could not map uid (%d) to name",
+	       uid);
+
+      printf("%d , %d : USERID : OTHER%s%s : %d\r\n",
+	     lport, fport,
+	     charset_name ? " , " : "",
+	     charset_name ? charset_name : "",
+	     uid);
+      continue;
+    }
+
+    /*
+    ** Hey! We finally made it!!!
+    */
+    if (syslog_flag)
+      syslog(LOG_DEBUG, "Successful lookup: %d , %d : %s",
+	     lport, fport, pwp->pw_name);
+
+    if (noident_flag && check_noident(pwp->pw_dir))
+    {
+      if (syslog_flag && verbose_flag)
+	syslog(LOG_NOTICE, "user %s requested HIDDEN-USER for host %s: %d, %d",
+	       pwp->pw_name,
+	       gethost(faddr),
+	       lport, fport);
+      
+      printf("%d , %d : ERROR : HIDDEN-USER\r\n",
+	   lport, fport);
+      continue;
+    }
+
+    if (number_flag)
+      printf("%d , %d : USERID : OTHER%s%s : %d\r\n",
+	     lport, fport,
+	     charset_name ? " , " : "",
+	     charset_name ? charset_name : "",
+	     uid);
+    else
+      printf("%d , %d : USERID : %s%s%s : %s\r\n",
+	     lport, fport,
+	     other_flag ? "OTHER" : "UNIX",
+	     charset_name ? " , " : "",
+	     charset_name ? charset_name : "",
+	     pwp->pw_name);
+    
+  } while(fflush(stdout), fflush(stderr), multi_flag && eat_whitespace());
+
+  return 0;
+}
diff --git a/identd.tproj/proxy.c b/identd.tproj/proxy.c
new file mode 100644
index 0000000..a64c581
--- /dev/null
+++ b/identd.tproj/proxy.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+**	$Id: proxy.c,v 1.1.1.1 1999/05/02 03:57:41 wsanchez Exp $
+**
+** proxy.c                         This file implements the proxy() call.
+**
+** This program is in the public domain and may be used freely by anyone
+** who wants to. 
+**
+** Last update: 12 Dec 1992
+**
+** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "identd.h"
+
+
+#ifdef INCLUDE_PROXY
+#include <sys/types.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+
+#include <ident.h>
+#endif
+
+
+/*
+** This function should establish a connection to a remote IDENT
+** server and query it for the information associated with the
+** specified connection and the return that to the caller.
+**
+** Should there be three different timeouts (Connection Establishment,
+** Query Transmit and Query Receive)?
+*/
+int proxy(laddr, faddr, lport, fport, timeout)
+  struct in_addr *laddr;
+  struct in_addr *faddr;
+  int lport;
+  int fport;
+  struct timeval *timeout;
+{
+#ifndef INCLUDE_PROXY
+  printf("%d , %d : ERROR : %s\r\n",
+	 lport, fport,
+	 unknown_flag ? "UNKNOWN-ERROR" : "X-NOT-YET-IMPLEMENTED");
+  
+  return -1;
+#else
+  id_t *idp;
+  char *answer;
+  char *opsys;
+  char *charset;
+  
+  idp = id_open(laddr, faddr, timeout);
+  if (!idp)
+  {
+    printf("%d , %d : ERROR : %s\r\n",
+	   lport, fport,
+	   unknown_flag ? "UNKNOWN-ERROR" : "X-CONNECTION-REFUSED");
+    return -1;
+  }
+
+  if (id_query(idp, lport, fport, timeout) < 0)
+  {
+    printf("%d , %d : ERROR : %s\r\n",
+	   lport, fport,
+	   unknown_flag ? "UNKNOWN-ERROR" : "X-TRANSMIT-QUERY-ERROR");
+    id_close(idp);
+    return -1;
+  }
+
+  switch (id_parse(idp, timeout, &lport, &fport, &answer, &opsys, &charset))
+  {
+    case 1:
+      printf("%d , %d : USERID : %s %s%s : %s\r\n",
+	     lport, fport,
+	     opsys,
+	     charset ? "," : "",
+	     charset ? charset : "",
+	     answer);
+      break;
+      
+    case 2:
+      printf("%d , %d : ERROR : %s\r\n",
+	     lport, fport, answer);
+      break;
+      
+    case 0:  /* More to parse - fix this later! */
+    case -1: /* Internal error */
+    default:
+      printf("%d , %d : ERROR : %s\r\n",
+	     lport, fport,
+	     unknown_flag ? "UNKNOWN-ERROR" : "X-PARSE-REPLY-ERROR");
+  }
+
+  id_close(idp);
+#endif  
+}
diff --git a/identd.tproj/version.c b/identd.tproj/version.c
new file mode 100644
index 0000000..dbeeab2
--- /dev/null
+++ b/identd.tproj/version.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $Id: version.c,v 1.1.1.1 1999/05/02 03:57:41 wsanchez Exp $ */
+char *version = "2.1.2";
diff --git a/identd.tproj/xpaths.h b/identd.tproj/xpaths.h
new file mode 100644
index 0000000..df55f1a
--- /dev/null
+++ b/identd.tproj/xpaths.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+**	$Id: xpaths.h,v 1.1.1.2 2000/01/11 01:48:48 wsanchez Exp $
+**
+** paths.h		Common path definitions for the in.identd daemon
+**
+** Last update: 11 Dec 1992
+**
+** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#include <paths.h>
+
+#ifdef SEQUENT
+#  define _PATH_UNIX "/dynix"
+#endif
+
+#if defined(MIPS) || defined(IRIX)
+#  define _PATH_UNIX "/unix"
+#endif
+
+#if defined(hpux) || defined(__hpux)
+#  define _PATH_UNIX "/hp-ux"
+#endif
+
+#ifdef SOLARIS
+#  define _PATH_UNIX "/dev/ksyms"
+#else
+#  ifdef SVR4
+#    define _PATH_UNIX "/stand/unix"
+#  endif
+#endif
+
+#ifdef BSD43
+#  define _PATH_SWAP "/dev/drum"
+#  define _PATH_MEM  "/dev/mem"
+#endif
+
+#ifdef _AUX_SOURCE
+#  define _PATH_UNIX "/unix"
+#endif
+
+#ifdef _CRAY
+#  define _PATH_UNIX "/unicos"
+#  define _PATH_MEM  "/dev/mem"
+#endif
+
+#ifdef __APPLE__
+#  define _PATH_UNIX "/mach"
+#endif
+
+
+/*
+ * Some defaults...
+ */
+#ifndef _PATH_KMEM
+#  define _PATH_KMEM "/dev/kmem"
+#endif
+
+#ifndef _PATH_UNIX
+#  define _PATH_UNIX "/vmunix"
+#endif
+
+
+#ifndef PATH_CONFIG
+#  define PATH_CONFIG "/etc/identd.conf"
+#endif
diff --git a/ifconfig.tproj/Makefile b/ifconfig.tproj/Makefile
new file mode 100644
index 0000000..2ae172d
--- /dev/null
+++ b/ifconfig.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the Apple Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ifconfig
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = ifconfig.h
+
+CFILES = ifconfig.c ifmedia.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.dist ifconfig.8\
+            Makefile.postamble
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /sbin
+WINDOWS_INSTALLDIR = /sbin
+PDO_UNIX_INSTALLDIR = /sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ifconfig.tproj/Makefile.dist b/ifconfig.tproj/Makefile.dist
new file mode 100644
index 0000000..8be2193
--- /dev/null
+++ b/ifconfig.tproj/Makefile.dist
@@ -0,0 +1,6 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/5/93
+
+PROG=	ifconfig
+MAN8=	ifconfig.0
+
+.include <bsd.prog.mk>
diff --git a/ifconfig.tproj/Makefile.postamble b/ifconfig.tproj/Makefile.postamble
new file mode 100644
index 0000000..c188e2f
--- /dev/null
+++ b/ifconfig.tproj/Makefile.postamble
@@ -0,0 +1,3 @@
+after_install:
+	install -d $(DSTROOT)/usr/share/man/man8
+	install -c -m 444 ifconfig.8 $(DSTROOT)/usr/share/man/man8
diff --git a/ifconfig.tproj/Makefile.preamble b/ifconfig.tproj/Makefile.preamble
new file mode 100644
index 0000000..5a6d897
--- /dev/null
+++ b/ifconfig.tproj/Makefile.preamble
@@ -0,0 +1,3 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
+OTHER_CFLAGS += -DUSE_IF_MEDIA
diff --git a/ifconfig.tproj/PB.project b/ifconfig.tproj/PB.project
new file mode 100644
index 0000000..e699c93
--- /dev/null
+++ b/ifconfig.tproj/PB.project
@@ -0,0 +1,32 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (ifconfig.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (ifconfig.c, ifmedia.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.dist, ifconfig.8, Makefile.postamble); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_INSTALLDIR = /sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = ifconfig; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_INSTALLDIR = /sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_MAINNIB = ifconfig; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ifconfig; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_INSTALLDIR = /sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_MAINNIB = ifconfig; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ifconfig.tproj/ifconfig.8 b/ifconfig.tproj/ifconfig.8
new file mode 100644
index 0000000..216d66a
--- /dev/null
+++ b/ifconfig.tproj/ifconfig.8
@@ -0,0 +1,320 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)ifconfig.8	8.4 (Berkeley) 6/1/94
+.\"
+.Dd June 1, 1994
+.Dt IFCONFIG 8
+.Os BSD 4.2
+.Sh NAME
+.Nm ifconfig
+.Nd configure network interface parameters
+.Sh SYNOPSIS
+.Nm ifconfig
+.Ar interface address_family
+.Oo
+.Ar address
+.Op Ar dest_address
+.Oc
+.Op Ar parameters
+.Nm ifconfig
+.Ar interface
+.Op Ar protocol_family
+.Nm ifconfig
+.Fl a
+.Op Fl d
+.Op Fl u
+.Op Ar address_family
+.Nm ifconfig
+.Fl l
+.Op Fl d
+.Op Fl u
+.Op Ar address_family
+.Sh DESCRIPTION
+.Nm Ifconfig
+is used to assign an address
+to a network interface and/or configure
+network interface parameters.
+.Nm Ifconfig
+must be used at boot time to define the network address
+of each interface present on a machine; it may also be used at
+a later time to redefine an interface's address
+or other operating parameters.
+.Pp
+Available operands for
+.Nm ifconfig:
+.Bl -tag -width Ds
+.It Ar Address
+For the
+.Tn DARPA-Internet
+family,
+the address is either a host name present in the host name data
+base, 
+.Xr hosts 5 ,
+or a
+.Tn DARPA
+Internet address expressed in the Internet standard
+.Dq dot notation .
+For the Xerox Network Systems(tm) family,
+addresses are 
+.Ar net:a.b.c.d.e.f ,
+where
+.Ar net
+is the assigned network number (in decimal),
+and each of the six bytes of the host number,
+.Ar a
+through
+.Ar f ,
+are specified in hexadecimal.
+The host number may be omitted on 10Mb/s Ethernet interfaces,
+which use the hardware physical address,
+and on interfaces other than the first.
+For the
+.Tn ISO
+family, addresses are specified as a long hexadecimal string,
+as in the Xerox family.  However, two consecutive dots imply a zero
+byte, and the dots are optional, if the user wishes to (carefully)
+count out long strings of digits in network byte order.
+.It Ar address_family
+Specifies the
+.Ar address family
+which affects interpretation of the remaining parameters.
+Since an interface can receive transmissions in differing protocols
+with different naming schemes, specifying the address family is recommeded.
+The address or protocol families currently
+supported are
+.Dq inet ,
+.Dq iso ,
+and
+.Dq ns .
+.It Ar Interface
+The
+.Ar interface
+parameter is a string of the form
+.Dq name unit ,
+for example,
+.Dq en0 
+.El
+.Pp
+The following parameters may be set with 
+.Nm ifconfig :
+.Bl -tag -width dest_addressxx
+.It Cm alias
+Establish an additional network address for this interface.  This is
+sometimes useful when changing network numbers, and one wishes to
+accept packets addressed to the old interface. 
+A
+.Ar netmask
+should be used with this parameter.
+If the new (
+.Ar alias
+) address is on the same subnet as an existing address assigned to
+this interface, the netmask must be "255.255.255.255".  If a netmask
+is not supplied, the command will use the one implied by the address
+itself (e.g, Class A).  If the 'all ones' netmask is used, the system
+will handle route installation.  If another netmask is used, a route
+to that address must be installed by hand, e.g., "route add -host
+XX.XX.XX.XX -interface 127.0.0.1", where "XX.XX.XX.XX" is the new
+alias (c.f.
+.Ar route
+(8)).  In either case, the administrator may have to remove a route
+by hand when the alias is removed (
+.Ar -alias
+or 
+.Ar delete
+)
+.It Cm arp
+Enable the use of the Address Resolution Protocol in mapping
+between network level addresses and link level addresses (default).
+This is currently implemented for mapping between
+.Tn DARPA
+Internet
+addresses and 10Mb/s Ethernet addresses.
+.It Fl arp
+Disable the use of the Address Resolution Protocol.
+.It Cm broadcast
+(Inet only)
+Specify the address to use to represent broadcasts to the
+network.
+The default broadcast address is the address with a host part of all 1's.
+.It Cm debug
+Enable driver dependent debugging code; usually, this turns on
+extra console error logging.
+.It Fl debug
+Disable driver dependent debugging code.
+.ne 1i
+.It Cm delete
+Remove the network address specified.
+This would be used if you incorrectly specified an alias, or it
+was no longer needed.
+If you have incorrectly set an NS address having the side effect
+of specifying the host portion, removing all NS addresses will
+allow you to respecify the host portion.
+.It Cm dest_address
+Specify the address of the correspondent on the other end
+of a point to point link.
+.It Cm down
+Mark an interface ``down''.  When an interface is
+marked ``down'', the system will not attempt to
+transmit messages through that interface. 
+If possible, the interface will be reset to disable reception as well.
+This action does not automatically disable routes using the interface.
+.It Cm ipdst
+This is used to specify an Internet host who is willing to receive
+ip packets encapsulating NS packets bound for a remote network.
+An apparent point to point link is constructed, and
+the address specified will be taken as the NS address and network
+of the destination.
+IP encapsulation of
+.Tn CLNP
+packets is done differently.
+.It Cm metric Ar n
+Set the routing metric of the interface to
+.Ar n ,
+default 0.
+The routing metric is used by the routing protocol
+.Pq Xr routed 8 .
+Higher metrics have the effect of making a route
+less favorable; metrics are counted as addition hops
+to the destination network or host.
+.It Cm netmask Ar mask
+(Inet and ISO)
+Specify how much of the address to reserve for subdividing
+networks into sub-networks.
+The mask includes the network part of the local address
+and the subnet part, which is taken from the host field of the address.
+The mask can be specified as a single hexadecimal number
+with a leading 0x, with a dot-notation Internet address,
+or with a pseudo-network name listed in the network table
+.Xr networks 5 .
+The mask contains 1's for the bit positions in the 32-bit address
+which are to be used for the network and subnet parts,
+and 0's for the host part.
+The mask should contain at least the standard network portion,
+and the subnet field should be contiguous with the network
+portion.
+.\" see 
+.\" Xr eon 5 .
+.It Cm nsellength Ar n
+.Pf ( Tn ISO
+only)
+This specifies a trailing number of bytes for a received
+.Tn NSAP
+used for local identification, the remaining leading part of which is
+taken to be the
+.Tn NET
+(Network Entity Title).
+The default value is 1, which is conformant to US
+.Tn GOSIP .
+When an ISO address is set in an ifconfig command,
+it is really the
+.Tn NSAP
+which is being specified.
+For example, in
+.Tn US GOSIP ,
+20 hex digits should be
+specified in the
+.Tn ISO NSAP
+to be assigned to the interface.
+There is some evidence that a number different from 1 may be useful
+for
+.Tn AFI
+37 type addresses.
+.It Cm trailers
+Request the use of a ``trailer'' link level encapsulation when
+sending (default).
+If a network interface supports
+.Cm trailers ,
+the system will, when possible, encapsulate outgoing
+messages in a manner which minimizes the number of
+memory to memory copy operations performed by the receiver.
+On networks that support the Address Resolution Protocol (see
+.Xr arp 4 ;
+currently, only 10 Mb/s Ethernet),
+this flag indicates that the system should request that other
+systems use trailers when sending to this host.
+Similarly, trailer encapsulations will be sent to other
+hosts that have made such requests.
+Currently used by Internet protocols only.
+.It Fl trailers
+Disable the use of a ``trailer'' link level encapsulation.
+.It Cm link[0-2]
+Enable special processing of the link level of the interface.
+These three options are interface specific in actual effect, however,
+they are in general used to select special modes of operation. An example
+of this is to enable SLIP compression. Currently, only used by SLIP.
+.ne 1i
+.It Fl link[0-2]
+Disable special processing at the link level with the specified interface.
+.It Cm up
+Mark an interface ``up''. 
+This may be used to enable an interface after an ``ifconfig down.''
+It happens automatically when setting the first address on an interface.
+If the interface was reset when previously marked down,
+the hardware will be re-initialized.
+.El
+.Pp
+Special flags for 
+.Nm ifconfig:
+.Bl -tag -width Ds
+.It -a
+Produce a full listing for all available interfaces.
+.It -l
+Produce a name-only listing for all available interfaces.
+.It -d
+limit the listing to those interfaces that are down.
+.It -u
+limit the listing to those interfaces that are up.
+.El
+.Pp
+.Pp
+.Nm Ifconfig
+displays the current configuration for a network interface
+when no optional parameters are supplied.
+If a protocol family is specified,
+Ifconfig will report only the details specific to that protocol family.
+.Pp
+Only the super-user may modify the configuration of a network interface.
+.Sh DIAGNOSTICS
+Messages indicating the specified interface does not exit, the
+requested address is unknown, or the user is not privileged and
+tried to alter an interface's configuration.
+.Sh SEE ALSO
+.Xr netstat 1 ,
+.Xr netintro 4 ,
+.Xr rc 8 ,
+.Xr routed 8 ,
+.\" .Xr eon 5
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/ifconfig.tproj/ifconfig.c b/ifconfig.tproj/ifconfig.c
new file mode 100644
index 0000000..0165a69
--- /dev/null
+++ b/ifconfig.tproj/ifconfig.c
@@ -0,0 +1,870 @@
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ifconfig.c	8.2 (Berkeley) 2/16/94";
+#endif
+static const char rcsid[] =
+	"$Id: ifconfig.c,v 1.1.1.2 2000/01/11 01:48:49 wsanchez Exp $";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/route.h>
+
+/* IP */
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+/* OSI */
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ifconfig.h"
+
+struct	ifreq		ifr, ridreq;
+struct	ifaliasreq	addreq;
+struct	sockaddr_in	netmask;
+
+
+char	name[32];
+int	flags;
+int	metric;
+int	mtu;
+int	setaddr;
+int	setipdst;
+int	doalias;
+int	clearaddr;
+int	newaddr = 1;
+
+struct	afswtch;
+
+void	Perror __P((const char *cmd));
+
+int	ifconfig __P((int argc, char *const *argv, const struct afswtch *afp));
+void	notealias __P((const char *, int, int, const struct afswtch *afp));
+void	printb __P((const char *s, unsigned value, const char *bits));
+void	rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
+void	status __P((const struct afswtch *afp, int addrcount,
+		    struct sockaddr_dl *sdl, struct if_msghdr *ifm,
+		    struct ifa_msghdr *ifam));
+void	usage __P((void));
+
+typedef	void c_func __P((const char *cmd, int arg, int s, const struct afswtch *afp));
+
+c_func	setifaddr, setifbroadaddr, setifdstaddr, setifnetmask;
+c_func	setifipdst;
+c_func	setifflags, setifmetric, setifmtu;
+
+
+#define	NEXTARG		0xffffff
+
+const
+struct	cmd {
+	const	char *c_name;
+	int	c_parameter;		/* NEXTARG means next argv */
+	void	(*c_func) __P((const char *, int, int, const struct afswtch *afp));
+} cmds[] = {
+	{ "up",		IFF_UP,		setifflags } ,
+	{ "down",	-IFF_UP,	setifflags },
+	{ "arp",	-IFF_NOARP,	setifflags },
+	{ "-arp",	IFF_NOARP,	setifflags },
+	{ "debug",	IFF_DEBUG,	setifflags },
+	{ "-debug",	-IFF_DEBUG,	setifflags },
+	{ "alias",	IFF_UP,		notealias },
+	{ "-alias",	-IFF_UP,	notealias },
+	{ "delete",	-IFF_UP,	notealias },
+#ifdef notdef
+#define	EN_SWABIPS	0x1000
+	{ "swabips",	EN_SWABIPS,	setifflags },
+	{ "-swabips",	-EN_SWABIPS,	setifflags },
+#endif
+	{ "netmask",	NEXTARG,	setifnetmask },
+	{ "range",	NEXTARG,	0 },
+	{ "phase",	NEXTARG,	0 },
+	{ "metric",	NEXTARG,	setifmetric },
+	{ "broadcast",	NEXTARG,	setifbroadaddr },
+	{ "ipdst",	NEXTARG,	setifipdst },
+	{ "link0",	IFF_LINK0,	setifflags },
+	{ "-link0",	-IFF_LINK0,	setifflags },
+	{ "link1",	IFF_LINK1,	setifflags },
+	{ "-link1",	-IFF_LINK1,	setifflags },
+	{ "link2",	IFF_LINK2,	setifflags },
+	{ "-link2",	-IFF_LINK2,	setifflags },
+#if USE_IF_MEDIA
+	{ "media",	NEXTARG,	setmedia },
+	{ "mediaopt",	NEXTARG,	setmediaopt },
+	{ "-mediaopt",	NEXTARG,	unsetmediaopt },
+#endif
+	{ "normal",	-IFF_LINK0,	setifflags },
+	{ "compress",	IFF_LINK0,	setifflags },
+	{ "noicmp",	IFF_LINK1,	setifflags },
+	{ "mtu",	NEXTARG,	setifmtu },
+	{ 0,		0,		setifaddr },
+	{ 0,		0,		setifdstaddr },
+};
+
+/*
+ * XNS support liberally adapted from code written at the University of
+ * Maryland principally by James O'Toole and Chris Torek.
+ */
+typedef	void af_status __P((int, struct rt_addrinfo *));
+typedef	void af_getaddr __P((const char *, int));
+
+af_status	in_status, ipx_status, at_status, ether_status;
+af_getaddr	in_getaddr, ipx_getaddr, at_getaddr;
+
+/* Known address families */
+const
+struct	afswtch {
+	const char *af_name;
+	short af_af;
+	af_status *af_status;
+	af_getaddr *af_getaddr;
+	u_long af_difaddr;
+	u_long af_aifaddr;
+	caddr_t af_ridreq;
+	caddr_t af_addreq;
+} afs[] = {
+#define C(x) ((caddr_t) &x)
+	{ "inet", AF_INET, in_status, in_getaddr,
+	     SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
+	{ "ether", AF_INET, ether_status, NULL },	/* XXX not real!! */
+#if 0	/* XXX conflicts with the media command */
+#if USE_IF_MEDIA
+	{ "media", AF_INET, media_status, NULL },	/* XXX not real!! */
+#endif
+#endif
+	{ 0,	0,	    0,		0 }
+};
+
+/*
+ * Expand the compacted form of addresses as returned via the
+ * configuration read via sysctl().
+ */
+
+#define ROUNDUP(a) \
+	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+void
+rt_xaddrs(cp, cplim, rtinfo)
+	caddr_t cp, cplim;
+	struct rt_addrinfo *rtinfo;
+{
+	struct sockaddr *sa;
+	int i;
+
+	memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
+	for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
+		if ((rtinfo->rti_addrs & (1 << i)) == 0)
+			continue;
+		rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
+		ADVANCE(cp, sa);
+	}
+}
+
+
+void
+usage()
+{
+	fprintf(stderr, "%s\n%s\n%s\n%s\n",
+	"usage: ifconfig interface address_family [address [dest_address]]",
+	"                [parameters]",
+	"       ifconfig -a [-d] [-u] [address_family]",
+	"       ifconfig -l [-d] [-u] [address_family]");
+	exit(1);
+}
+
+int
+main(argc, argv)
+	int argc;
+	char *const *argv;
+{
+	int c;
+	int all, namesonly, downonly, uponly;
+	int foundit = 0, need_nl = 0;
+	const struct afswtch *afp = 0;
+	int addrcount;
+	struct	if_msghdr *ifm, *nextifm;
+	struct	ifa_msghdr *ifam;
+	struct	sockaddr_dl *sdl;
+	char	*buf, *lim, *next;
+
+
+	size_t needed;
+	int mib[6];
+
+	/* Parse leading line options */
+	all = downonly = uponly = namesonly = 0;
+	while ((c = getopt(argc, argv, "adlmu")) != -1) {
+		switch (c) {
+		case 'a':	/* scan all interfaces */
+			all++;
+			break;
+		case 'l':	/* scan interface names only */
+			namesonly++;
+			break;
+		case 'd':	/* restrict scan to "down" interfaces */
+			downonly++;
+			break;
+		case 'u':	/* restrict scan to "up" interfaces */
+			uponly++;
+			break;
+		case 'm':	/* show media choices in status */
+			/* ignored for compatibility */
+			break;
+		default:
+			usage();
+			break;
+		}
+	}
+	argc -= optind;
+	argv += optind;
+
+	/* -l cannot be used with -a or -m */
+	if (namesonly && all)
+		usage();
+
+	/* nonsense.. */
+	if (uponly && downonly)
+		usage();
+
+	/* -a and -l allow an address family arg to limit the output */
+	if (all || namesonly) {
+		if (argc > 1)
+			usage();
+
+		if (argc == 1) {
+			for (afp = afs; afp->af_name; afp++)
+				if (strcmp(afp->af_name, *argv) == 0) {
+					argc--, argv++;
+					break;
+				}
+			if (afp->af_name == NULL)
+				usage();
+			/* leave with afp non-zero */
+		}
+	} else {
+		/* not listing, need an argument */
+		if (argc < 1)
+			usage();
+
+		strncpy(name, *argv, sizeof(name));
+		argc--, argv++;
+	}
+
+	/* Check for address family */
+	if (argc > 0) {
+		for (afp = afs; afp->af_name; afp++)
+			if (strcmp(afp->af_name, *argv) == 0) {
+				argc--, argv++;
+				break;
+			}
+		if (afp->af_name == NULL)
+			afp = NULL;	/* not a family, NULL */
+	}
+
+	mib[0] = CTL_NET;
+	mib[1] = PF_ROUTE;
+	mib[2] = 0;
+	mib[3] = 0;	/* address family */
+	mib[4] = NET_RT_IFLIST;
+	mib[5] = 0;
+
+	/* if particular family specified, only ask about it */
+	if (afp)
+		mib[3] = afp->af_af;
+
+	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+		errx(1, "iflist-sysctl-estimate");
+	if ((buf = malloc(needed)) == NULL)
+		errx(1, "malloc");
+	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+		errx(1, "actual retrieval of interface table");
+	lim = buf + needed;
+
+	next = buf;
+	while (next < lim) {
+
+		ifm = (struct if_msghdr *)next;
+		
+		if (ifm->ifm_type == RTM_IFINFO) {
+			sdl = (struct sockaddr_dl *)(ifm + 1);
+			flags = ifm->ifm_flags;
+		} else {
+			fprintf(stderr, "out of sync parsing NET_RT_IFLIST\n");
+			fprintf(stderr, "expected %d, got %d\n", RTM_IFINFO,
+				ifm->ifm_type);
+			fprintf(stderr, "msglen = %d\n", ifm->ifm_msglen);
+			fprintf(stderr, "buf:%p, next:%p, lim:%p\n", buf, next,
+				lim);
+			exit (1);
+		}
+
+		next += ifm->ifm_msglen;
+		ifam = NULL;
+		addrcount = 0;
+		while (next < lim) {
+
+			nextifm = (struct if_msghdr *)next;
+
+			if (nextifm->ifm_type != RTM_NEWADDR)
+				break;
+
+			if (ifam == NULL)
+				ifam = (struct ifa_msghdr *)nextifm;
+
+			addrcount++;
+			next += nextifm->ifm_msglen;
+		}
+
+		if (all || namesonly) {
+			if (uponly)
+				if ((flags & IFF_UP) == 0)
+					continue; /* not up */
+			if (downonly)
+				if (flags & IFF_UP)
+					continue; /* not down */
+			strncpy(name, sdl->sdl_data, sdl->sdl_nlen);
+			name[sdl->sdl_nlen] = '\0';
+			if (namesonly) {
+				if (afp == NULL ||
+					afp->af_status != ether_status ||
+					sdl->sdl_type == IFT_ETHER) {
+					if (need_nl)
+						putchar(' ');
+					fputs(name, stdout);
+					need_nl++;
+				}
+				continue;
+			}
+		} else {
+			if (strlen(name) != sdl->sdl_nlen)
+				continue; /* not same len */
+			if (strncmp(name, sdl->sdl_data, sdl->sdl_nlen) != 0)
+				continue; /* not same name */
+		}
+
+		if (argc > 0)
+			ifconfig(argc, argv, afp);
+		else
+			status(afp, addrcount, sdl, ifm, ifam);
+
+		if (all == 0 && namesonly == 0) {
+			foundit++; /* flag it as 'done' */
+			break;
+		}
+	}
+	free(buf);
+
+	if (namesonly && need_nl > 0)
+		putchar('\n');
+
+	if (all == 0 && namesonly == 0 && foundit == 0)
+		errx(1, "interface %s does not exist", name);
+
+
+	exit (0);
+}
+
+
+int
+ifconfig(argc, argv, afp)
+	int argc;
+	char *const *argv;
+	const struct afswtch *afp;
+{
+	int s;
+
+	if (afp == NULL)
+		afp = &afs[0];
+	ifr.ifr_addr.sa_family = afp->af_af;
+	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
+
+	if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
+		err(1, "socket");
+
+	while (argc > 0) {
+		register const struct cmd *p;
+
+		for (p = cmds; p->c_name; p++)
+			if (strcmp(*argv, p->c_name) == 0)
+				break;
+		if (p->c_name == 0 && setaddr)
+			p++;	/* got src, do dst */
+		if (p->c_func) {
+			if (p->c_parameter == NEXTARG) {
+				if (argv[1] == NULL)
+					errx(1, "'%s' requires argument",
+					    p->c_name);
+				(*p->c_func)(argv[1], 0, s, afp);
+				argc--, argv++;
+			} else
+				(*p->c_func)(*argv, p->c_parameter, s, afp);
+		}
+		argc--, argv++;
+	}
+
+	if (clearaddr) {
+		if (afp->af_ridreq == NULL || afp->af_difaddr == 0) {
+			warnx("interface %s cannot change %s addresses!",
+			      name, afp->af_name);
+			clearaddr = NULL;
+		}
+	}
+	if (clearaddr) {
+		int ret;
+		strncpy(afp->af_ridreq, name, sizeof ifr.ifr_name);
+		if ((ret = ioctl(s, afp->af_difaddr, afp->af_ridreq)) < 0) {
+			if (errno == EADDRNOTAVAIL && (doalias >= 0)) {
+				/* means no previous address for interface */
+			} else
+				Perror("ioctl (SIOCDIFADDR)");
+		}
+	}
+	if (newaddr) {
+		if (afp->af_ridreq == NULL || afp->af_difaddr == 0) {
+			warnx("interface %s cannot change %s addresses!",
+			      name, afp->af_name);
+			newaddr = NULL;
+		}
+	}
+	if (newaddr) {
+		strncpy(afp->af_addreq, name, sizeof ifr.ifr_name);
+		if (ioctl(s, afp->af_aifaddr, afp->af_addreq) < 0)
+			Perror("ioctl (SIOCAIFADDR)");
+	}
+	close(s);
+	return(0);
+}
+#define RIDADDR 0
+#define ADDR	1
+#define MASK	2
+#define DSTADDR	3
+
+/*ARGSUSED*/
+void
+setifaddr(addr, param, s, afp)
+	const char *addr;
+	int param;
+	int s;
+	const struct afswtch *afp;
+{
+	/*
+	 * Delay the ioctl to set the interface addr until flags are all set.
+	 * The address interpretation may depend on the flags,
+	 * and the flags may change when the address is set.
+	 */
+	setaddr++;
+	if (doalias == 0)
+		clearaddr = 1;
+	(*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR));
+}
+
+void
+setifnetmask(addr, dummy, s, afp)
+	const char *addr;
+	int dummy ;
+	int s;
+	const struct afswtch *afp;
+{
+	(*afp->af_getaddr)(addr, MASK);
+}
+
+void
+setifbroadaddr(addr, dummy, s, afp)
+	const char *addr;
+	int dummy ;
+	int s;
+	const struct afswtch *afp;
+{
+	(*afp->af_getaddr)(addr, DSTADDR);
+}
+
+void
+setifipdst(addr, dummy, s, afp)
+	const char *addr;
+	int dummy ;
+	int s;
+	const struct afswtch *afp;
+{
+	in_getaddr(addr, DSTADDR);
+	setipdst++;
+	clearaddr = 0;
+	newaddr = 0;
+}
+#define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
+
+void
+notealias(addr, param, s, afp)
+	const char *addr;
+	int param;
+	int s;
+	const struct afswtch *afp;
+{
+	if (setaddr && doalias == 0 && param < 0)
+		bcopy((caddr_t)rqtosa(af_addreq),
+		      (caddr_t)rqtosa(af_ridreq),
+		      rqtosa(af_addreq)->sa_len);
+	doalias = param;
+	if (param < 0) {
+		clearaddr = 1;
+		newaddr = 0;
+	} else
+		clearaddr = 0;
+}
+
+/*ARGSUSED*/
+void
+setifdstaddr(addr, param, s, afp)
+	const char *addr;
+	int param ;
+	int s;
+	const struct afswtch *afp;
+{
+	(*afp->af_getaddr)(addr, DSTADDR);
+}
+
+void
+setifflags(vname, value, s, afp)
+	const char *vname;
+	int value;
+	int s;
+	const struct afswtch *afp;
+{
+ 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
+ 		Perror("ioctl (SIOCGIFFLAGS)");
+ 		exit(1);
+ 	}
+	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+ 	flags = ifr.ifr_flags;
+
+	if (value < 0) {
+		value = -value;
+		flags &= ~value;
+	} else
+		flags |= value;
+	ifr.ifr_flags = flags;
+	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
+		Perror(vname);
+}
+
+void
+setifmetric(val, dummy, s, afp)
+	const char *val;
+	int dummy ;
+	int s;
+	const struct afswtch *afp;
+{
+	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+	ifr.ifr_metric = atoi(val);
+	if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
+		warn("ioctl (set metric)");
+}
+
+void
+setifmtu(val, dummy, s, afp)
+	const char *val;
+	int dummy ;
+	int s;
+	const struct afswtch *afp;
+{
+	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+	ifr.ifr_mtu = atoi(val);
+	if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) < 0)
+		warn("ioctl (set mtu)");
+}
+
+
+#define	IFFBITS \
+"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6b6\7RUNNING" \
+"\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \
+"\20MULTICAST"
+
+/*
+ * Print the status of the interface.  If an address family was
+ * specified, show it and it only; otherwise, show them all.
+ */
+void
+status(afp, addrcount, sdl, ifm, ifam)
+	const struct afswtch *afp;
+	int addrcount;
+	struct	sockaddr_dl *sdl;
+	struct if_msghdr *ifm;
+	struct ifa_msghdr *ifam;
+{
+	const struct afswtch *p = NULL;
+	struct	rt_addrinfo info;
+	int allfamilies, s;
+
+	if (afp == NULL) {
+		allfamilies = 1;
+		afp = &afs[0];
+	} else
+		allfamilies = 0;
+
+	ifr.ifr_addr.sa_family = afp->af_af;
+	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
+
+	if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
+		err(1, "socket");
+
+	/*
+	 * XXX is it we are doing a SIOCGIFMETRIC etc for one family.
+	 * is it possible that the metric and mtu can be different for
+	 * each family?  If so, we have a format problem, because the
+	 * metric and mtu is printed on the global the flags line.
+	 */
+	if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0)
+		warn("ioctl (SIOCGIFMETRIC)");
+	else
+		metric = ifr.ifr_metric;
+
+	if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) < 0)
+		warn("ioctl (SIOCGIFMTU)");
+	else
+		mtu = ifr.ifr_mtu;
+
+	printf("%s: ", name);
+	printb("flags", flags, IFFBITS);
+	if (metric)
+		printf(" metric %d", metric);
+	if (mtu)
+		printf(" mtu %d", mtu);
+	putchar('\n');
+
+	while (addrcount > 0) {
+		
+		info.rti_addrs = ifam->ifam_addrs;
+
+		/* Expand the compacted addresses */
+		rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam,
+			  &info);
+
+		if (!allfamilies) {
+			if (afp->af_af == info.rti_info[RTAX_IFA]->sa_family &&
+#if USE_IF_MEDIA
+			    afp->af_status != media_status &&
+#endif
+			    afp->af_status != ether_status) {
+				p = afp;
+				(*p->af_status)(s, &info);
+			}
+		} else for (p = afs; p->af_name; p++) {
+			if (p->af_af == info.rti_info[RTAX_IFA]->sa_family &&
+#if USE_IF_MEDIA
+			    p->af_status != media_status &&
+#endif
+			    p->af_status != ether_status) 
+				(*p->af_status)(s, &info);
+		}
+		addrcount--;
+		ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
+	}
+	if (allfamilies || afp->af_status == ether_status)
+		ether_status(s, (struct rt_addrinfo *)sdl);
+#if USE_IF_MEDIA
+	if (allfamilies || afp->af_status == media_status)
+		media_status(s, NULL);
+#endif
+	if (!allfamilies && !p && 
+	    afp->af_status != ether_status)
+		warnx("%s has no %s interface address!", name, afp->af_name);
+
+	close(s);
+	return;
+}
+
+void
+in_status(s, info)
+	int s ;
+	struct rt_addrinfo * info;
+{
+	struct sockaddr_in *sin, null_sin;
+	
+	memset(&null_sin, 0, sizeof(null_sin));
+
+	sin = (struct sockaddr_in *)info->rti_info[RTAX_IFA];
+	printf("\tinet %s ", inet_ntoa(sin->sin_addr));
+
+	if (flags & IFF_POINTOPOINT) {
+		/* note RTAX_BRD overlap with IFF_BROADCAST */
+		sin = (struct sockaddr_in *)info->rti_info[RTAX_BRD];
+		if (!sin)
+			sin = &null_sin;
+		printf("--> %s ", inet_ntoa(sin->sin_addr));
+	}
+
+	sin = (struct sockaddr_in *)info->rti_info[RTAX_NETMASK];
+	if (!sin)
+		sin = &null_sin;
+	printf("netmask 0x%lx ", (unsigned long)ntohl(sin->sin_addr.s_addr));
+
+	if (flags & IFF_BROADCAST) {
+		/* note RTAX_BRD overlap with IFF_POINTOPOINT */
+		sin = (struct sockaddr_in *)info->rti_info[RTAX_BRD];
+		if (sin && sin->sin_addr.s_addr != 0)
+			printf("broadcast %s", inet_ntoa(sin->sin_addr));
+	}
+	putchar('\n');
+}
+
+void
+ether_status(s, info)
+	int s ;
+	struct rt_addrinfo *info;
+{
+	char *cp;
+	int n;
+	struct sockaddr_dl *sdl = (struct sockaddr_dl *)info;
+
+	cp = (char *)LLADDR(sdl);
+	if ((n = sdl->sdl_alen) > 0) {
+		if (sdl->sdl_type == IFT_ETHER)
+			printf ("\tether ");
+		else
+			printf ("\tlladdr ");
+             	while (--n >= 0)
+			printf("%02x%c",*cp++ & 0xff, n>0? ':' : ' ');
+		putchar('\n');
+	}
+}
+
+void
+Perror(cmd)
+	const char *cmd;
+{
+	switch (errno) {
+
+	case ENXIO:
+		errx(1, "%s: no such interface", cmd);
+		break;
+
+	case EPERM:
+		errx(1, "%s: permission denied", cmd);
+		break;
+
+	default:
+		err(1, "%s", cmd);
+	}
+}
+
+#define SIN(x) ((struct sockaddr_in *) &(x))
+struct sockaddr_in *sintab[] = {
+SIN(ridreq.ifr_addr), SIN(addreq.ifra_addr),
+SIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)};
+
+void
+in_getaddr(s, which)
+	const char *s;
+	int which;
+{
+	register struct sockaddr_in *sin = sintab[which];
+	struct hostent *hp;
+	struct netent *np;
+
+	sin->sin_len = sizeof(*sin);
+	if (which != MASK)
+		sin->sin_family = AF_INET;
+
+	if (inet_aton(s, &sin->sin_addr))
+		return;
+	if ((hp = gethostbyname(s)) != 0)
+		bcopy(hp->h_addr, (char *)&sin->sin_addr, 
+		    MIN(hp->h_length, sizeof(sin->sin_addr)));
+	else if ((np = getnetbyname(s)) != 0)
+		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
+	else
+		errx(1, "%s: bad value", s);
+}
+
+/*
+ * Print a value a la the %b format of the kernel's printf
+ */
+void
+printb(s, v, bits)
+	const char *s;
+	register unsigned v;
+	register const char *bits;
+{
+	register int i, any = 0;
+	register char c;
+
+	if (bits && *bits == 8)
+		printf("%s=%o", s, v);
+	else
+		printf("%s=%x", s, v);
+	bits++;
+	if (bits) {
+		putchar('<');
+		while ((i = *bits++) != '\0') {
+			if (v & (1 << (i-1))) {
+				if (any)
+					putchar(',');
+				any = 1;
+				for (; (c = *bits) > 32; bits++)
+					putchar(c);
+			} else
+				for (; *bits > 32; bits++)
+					;
+		}
+		putchar('>');
+	}
+}
+
+
diff --git a/ifconfig.tproj/ifconfig.h b/ifconfig.tproj/ifconfig.h
new file mode 100644
index 0000000..a088b7a
--- /dev/null
+++ b/ifconfig.tproj/ifconfig.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997 Peter Wemm.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the FreeBSD Project
+ *	by Peter Wemm.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * so there!
+ *
+ * $Id: ifconfig.h,v 1.1.1.1 2000/01/11 01:48:49 wsanchez Exp $
+ */
+
+extern struct ifreq ifr;
+
+extern char name[32];	/* name of interface */
+extern int allmedia;
+struct afswtch;
+
+extern void setmedia(const char *, int, int, const struct afswtch *rafp);
+extern void setmediaopt(const char *, int, int, const struct afswtch *rafp);
+extern void unsetmediaopt(const char *, int, int, const struct afswtch *rafp);
+extern void media_status(int s, struct rt_addrinfo *);
diff --git a/ifconfig.tproj/ifmedia.c b/ifconfig.tproj/ifmedia.c
new file mode 100644
index 0000000..1657c21
--- /dev/null
+++ b/ifconfig.tproj/ifmedia.c
@@ -0,0 +1,554 @@
+/*	$NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $	*/
+/* $FreeBSD: src/sbin/ifconfig/ifmedia.c,v 1.6 1999/08/28 00:13:08 peter Exp $ */
+
+/*
+ * Copyright (c) 1997 Jason R. Thorpe.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project
+ *	by Jason R. Thorpe.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/if_media.h>
+#include <net/route.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ifconfig.h"
+
+static void	domediaopt __P((const char *, int, int));
+static int	get_media_subtype __P((int, const char *));
+static int	get_media_options __P((int, const char *));
+static int	lookup_media_word __P((struct ifmedia_description *, const char *));
+static void	print_media_word __P((int));
+
+void
+media_status(s, info)
+	int s;
+	struct rt_addrinfo *info;
+{
+	struct ifmediareq ifmr;
+	int *media_list, i;
+
+	(void) memset(&ifmr, 0, sizeof(ifmr));
+	(void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+
+	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
+		/*
+		 * Interface doesn't support SIOC{G,S}IFMEDIA.
+		 */
+		return;
+	}
+
+	if (ifmr.ifm_count == 0) {
+	    	//warnx("%s: no media types?", name);
+	    	return;
+	}
+
+	media_list = (int *)malloc(ifmr.ifm_count * sizeof(int));
+	if (media_list == NULL)
+		err(1, "malloc");
+	ifmr.ifm_ulist = media_list;
+
+	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
+		err(1, "SIOCGIFMEDIA");
+
+	printf("\tmedia: ");
+	print_media_word(ifmr.ifm_current);
+	if (ifmr.ifm_active != ifmr.ifm_current) {
+		putchar(' ');
+		putchar('(');
+		print_media_word(ifmr.ifm_active);
+		putchar(')');
+	}
+
+	if (ifmr.ifm_status & IFM_AVALID) {
+		printf(" status: ");
+#if 0
+		switch (IFM_TYPE(ifmr.ifm_active)) {
+		case IFM_ETHER:
+			if (ifmr.ifm_status & IFM_ACTIVE)
+				printf("active");
+			else
+				printf("no carrier");
+			break;
+
+		case IFM_FDDI:
+		case IFM_TOKEN:
+			if (ifmr.ifm_status & IFM_ACTIVE)
+				printf("inserted");
+			else
+				printf("no ring");
+			break;
+		}
+#endif 0
+		if (ifmr.ifm_status & IFM_ACTIVE)
+		    printf("active");
+		else
+		    printf("inactive");
+	}
+
+	putchar('\n');
+
+	if (ifmr.ifm_count > 0) {
+		printf("\tsupported media:");
+		for (i = 0; i < ifmr.ifm_count; i++) {
+			putchar(' ');
+			print_media_word(media_list[i]);
+		}
+		putchar('\n');
+	}
+
+	free(media_list);
+}
+
+void
+setmedia(val, d, s, afp)
+	const char *val;
+	int d;
+	int s;
+	const struct afswtch *afp;
+{
+	struct ifmediareq ifmr;
+	int first_type, subtype;
+
+	(void) memset(&ifmr, 0, sizeof(ifmr));
+	(void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+
+	ifmr.ifm_count = 1;
+	ifmr.ifm_ulist = &first_type;
+	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
+		/*
+		 * If we get E2BIG, the kernel is telling us
+		 * that there are more, so we can ignore it.
+		 */
+		if (errno != E2BIG)
+			err(1, "SIOCGIFMEDIA");
+	}
+
+	if (ifmr.ifm_count == 0)
+		errx(1, "%s: no media types?", name);
+
+	/*
+	 * We are primarily concerned with the top-level type.
+	 * However, "current" may be only IFM_NONE, so we just look
+	 * for the top-level type in the first "supported type"
+	 * entry.
+	 *
+	 * (I'm assuming that all supported media types for a given
+	 * interface will be the same top-level type..)
+	 */
+	subtype = get_media_subtype(IFM_TYPE(first_type), val);
+
+	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+	ifr.ifr_media = (ifmr.ifm_current & ~(IFM_NMASK|IFM_TMASK)) |
+	    IFM_TYPE(first_type) | subtype;
+
+	if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
+		err(1, "SIOCSIFMEDIA");
+}
+
+void
+setmediaopt(val, d, s, afp)
+	const char *val;
+	int d;
+	int s;
+	const struct afswtch *afp;
+{
+
+	domediaopt(val, 0, s);
+}
+
+void
+unsetmediaopt(val, d, s, afp)
+	const char *val;
+	int d;
+	int s;
+	const struct afswtch *afp;
+{
+
+	domediaopt(val, 1, s);
+}
+
+static void
+domediaopt(val, clear, s)
+	const char *val;
+	int clear;
+	int s;
+{
+	struct ifmediareq ifmr;
+	int *mwords, options;
+
+	(void) memset(&ifmr, 0, sizeof(ifmr));
+	(void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+
+	/*
+	 * We must go through the motions of reading all
+	 * supported media because we need to know both
+	 * the current media type and the top-level type.
+	 */
+
+	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
+		err(1, "SIOCGIFMEDIA");
+
+	if (ifmr.ifm_count == 0)
+		errx(1, "%s: no media types?", name);
+
+	mwords = (int *)malloc(ifmr.ifm_count * sizeof(int));
+	if (mwords == NULL)
+		err(1, "malloc");
+
+	ifmr.ifm_ulist = mwords;
+	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
+		err(1, "SIOCGIFMEDIA");
+
+	options = get_media_options(IFM_TYPE(mwords[0]), val);
+
+	free(mwords);
+
+	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+	ifr.ifr_media = ifmr.ifm_current;
+	if (clear)
+		ifr.ifr_media &= ~options;
+	else
+		ifr.ifr_media |= options;
+
+	if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
+		err(1, "SIOCSIFMEDIA");
+}
+
+/**********************************************************************
+ * A good chunk of this is duplicated from sys/net/ifmedia.c
+ **********************************************************************/
+
+static struct ifmedia_description ifm_type_descriptions[] =
+    IFM_TYPE_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_ethernet_descriptions[] =
+    IFM_SUBTYPE_ETHERNET_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_ethernet_aliases[] =
+    IFM_SUBTYPE_ETHERNET_ALIASES;
+
+static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] =
+    IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_tokenring_descriptions[] =
+    IFM_SUBTYPE_TOKENRING_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_tokenring_aliases[] =
+    IFM_SUBTYPE_TOKENRING_ALIASES;
+
+static struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] =
+    IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_fddi_descriptions[] =
+    IFM_SUBTYPE_FDDI_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_fddi_aliases[] =
+    IFM_SUBTYPE_FDDI_ALIASES;
+
+static struct ifmedia_description ifm_subtype_fddi_option_descriptions[] =
+    IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
+    IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] =
+    IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_shared_descriptions[] =
+    IFM_SUBTYPE_SHARED_DESCRIPTIONS;
+
+static struct ifmedia_description ifm_subtype_shared_aliases[] =
+    IFM_SUBTYPE_SHARED_ALIASES;
+
+static struct ifmedia_description ifm_shared_option_descriptions[] =
+    IFM_SHARED_OPTION_DESCRIPTIONS;
+
+struct ifmedia_type_to_subtype {
+	struct {
+		struct ifmedia_description *desc;
+		int alias;
+	} subtypes[5];
+	struct {
+		struct ifmedia_description *desc;
+		int alias;
+	} options[3];
+};
+
+/* must be in the same order as IFM_TYPE_DESCRIPTIONS */
+static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = {
+	{
+		{
+			{ &ifm_subtype_shared_descriptions[0], 0 },
+			{ &ifm_subtype_shared_aliases[0], 1 },
+			{ &ifm_subtype_ethernet_descriptions[0], 0 },
+			{ &ifm_subtype_ethernet_aliases[0], 1 },
+			{ NULL, 0 },
+		},
+		{
+			{ &ifm_shared_option_descriptions[0], 0 },
+			{ &ifm_subtype_ethernet_option_descriptions[0], 1 },
+			{ NULL, 0 },
+		},
+	},
+	{
+		{
+			{ &ifm_subtype_shared_descriptions[0], 0 },
+			{ &ifm_subtype_shared_aliases[0], 1 },
+			{ &ifm_subtype_tokenring_descriptions[0], 0 },
+			{ &ifm_subtype_tokenring_aliases[0], 1 },
+			{ NULL, 0 },
+		},
+		{
+			{ &ifm_shared_option_descriptions[0], 0 },
+			{ &ifm_subtype_tokenring_option_descriptions[0], 1 },
+			{ NULL, 0 },
+		},
+	},
+	{
+		{
+			{ &ifm_subtype_shared_descriptions[0], 0 },
+			{ &ifm_subtype_shared_aliases[0], 1 },
+			{ &ifm_subtype_fddi_descriptions[0], 0 },
+			{ &ifm_subtype_fddi_aliases[0], 1 },
+			{ NULL, 0 },
+		},
+		{
+			{ &ifm_shared_option_descriptions[0], 0 },
+			{ &ifm_subtype_fddi_option_descriptions[0], 1 },
+			{ NULL, 0 },
+		},
+	},
+	{
+		{
+			{ &ifm_subtype_shared_descriptions[0], 0 },
+			{ &ifm_subtype_shared_aliases[0], 1 },
+			{ &ifm_subtype_ieee80211_descriptions[0], 0 },
+			{ NULL, 0 },
+		},
+		{
+			{ &ifm_shared_option_descriptions[0], 0 },
+			{ &ifm_subtype_ieee80211_option_descriptions[0], 1 },
+			{ NULL, 0 },
+		},
+	},
+};
+
+static int
+get_media_subtype(type, val)
+	int type;
+	const char *val;
+{
+	struct ifmedia_description *desc;
+	struct ifmedia_type_to_subtype *ttos;
+	int rval, i;
+
+	/* Find the top-level interface type. */
+	for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
+	    desc->ifmt_string != NULL; desc++, ttos++)
+		if (type == desc->ifmt_word)
+			break;
+	if (desc->ifmt_string == NULL)
+		errx(1, "unknown media type 0x%x", type);
+
+	for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
+		rval = lookup_media_word(ttos->subtypes[i].desc, val);
+		if (rval != -1)
+			return (rval);
+	}
+	errx(1, "unknown media subtype: %s", val);
+	/* NOTREACHED */
+}
+
+static int
+get_media_options(type, val)
+	int type;
+	const char *val;
+{
+	struct ifmedia_description *desc;
+	struct ifmedia_type_to_subtype *ttos;
+	char *optlist, *optptr;
+	int option = 0, i, rval = 0;
+
+	/* We muck with the string, so copy it. */
+	optlist = strdup(val);
+	if (optlist == NULL)
+		err(1, "strdup");
+
+	/* Find the top-level interface type. */
+	for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
+	    desc->ifmt_string != NULL; desc++, ttos++)
+		if (type == desc->ifmt_word)
+			break;
+	if (desc->ifmt_string == NULL)
+		errx(1, "unknown media type 0x%x", type);
+
+	/*
+	 * Look up the options in the user-provided comma-separated
+	 * list.
+	 */
+	optptr = optlist;
+	for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) {
+		for (i = 0; ttos->options[i].desc != NULL; i++) {
+			option = lookup_media_word(ttos->options[i].desc, optptr);
+			if (option != -1)
+				break;
+		}
+		if (option == 0)
+			errx(1, "unknown option: %s", optptr);
+		rval |= option;
+	}
+
+	free(optlist);
+	return (rval);
+}
+
+static int
+lookup_media_word(desc, val)
+	struct ifmedia_description *desc;
+	const char *val;
+{
+
+	for (; desc->ifmt_string != NULL; desc++)
+		if (strcasecmp(desc->ifmt_string, val) == 0)
+			return (desc->ifmt_word);
+
+	return (-1);
+}
+
+static void
+print_media_word(ifmw)
+	int ifmw;
+{
+	struct ifmedia_description *desc;
+	struct ifmedia_type_to_subtype *ttos;
+	int seen_option = 0, i;
+
+	/* Find the top-level interface type. */
+	for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
+	    desc->ifmt_string != NULL; desc++, ttos++)
+		if (IFM_TYPE(ifmw) == desc->ifmt_word)
+			break;
+	if (desc->ifmt_string == NULL) {
+		printf("<unknown type>");
+		return;
+	}
+
+	/*
+	 * Don't print the top-level type; it's not like we can
+	 * change it, or anything.
+	 */
+
+	/* Find subtype. */
+	for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
+		if (ttos->subtypes[i].alias)
+			continue;
+		for (desc = ttos->subtypes[i].desc;
+		    desc->ifmt_string != NULL; desc++) {
+			if (IFM_SUBTYPE(ifmw) == desc->ifmt_word)
+				goto got_subtype;
+		}
+	}
+
+	/* Falling to here means unknown subtype. */
+	printf("<unknown subtype>");
+	return;
+
+ got_subtype:
+	printf("%s", desc->ifmt_string);
+
+	/* Find options. */
+	for (i = 0; ttos->options[i].desc != NULL; i++) {
+		if (ttos->options[i].alias)
+			continue;
+		for (desc = ttos->options[i].desc;
+		    desc->ifmt_string != NULL; desc++) {
+			if (ifmw & desc->ifmt_word) {
+				if (seen_option == 0)
+					printf(" <");
+				printf("%s%s", seen_option++ ? "," : "",
+				    desc->ifmt_string);
+			}
+		}
+	}
+	printf("%s", seen_option ? ">" : "");
+}
+
+/**********************************************************************
+ * ...until here.
+ **********************************************************************/
diff --git a/inetd.tproj/Makefile b/inetd.tproj/Makefile
new file mode 100644
index 0000000..bd27a46
--- /dev/null
+++ b/inetd.tproj/Makefile
@@ -0,0 +1,50 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = inetd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = pathnames.h
+
+CFILES = inetd.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble inetd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/inetd.tproj/Makefile.postamble b/inetd.tproj/Makefile.postamble
new file mode 100644
index 0000000..f5c79e2
--- /dev/null
+++ b/inetd.tproj/Makefile.postamble
@@ -0,0 +1,110 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app)
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+
+
+# Change defaults assumed by the standard app makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if
+# you would like changes to them to invalidate previous builds.  The project
+# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build.
+#MAKEFILES = Makefile 
+
+# Optimization flag passed to compiler:
+#OPTIMIZATION_CFLAG = -O
+
+# Flags always passed to compiler:
+#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall  
+
+# Flags passed to compiler in normal 'app' compiles:
+#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG)
+
+# Flags passed to compiler in 'debug' compiles:
+#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG
+
+# Flags passed to compiler in 'profile' compiles
+#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User to chown app to
+#INSTALL_AS_GROUP = wheel      # Group to chgrp app to 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for bundles, apps with bundles, and apps without bundles, 
+# respectively.
+#RELOCATABLE_STRIP_OPTS = -x -u
+#DYLD_APP_STRIP_OPTS = -A -n
+#APP_STRIP_OPTS = 
+#TOOL_STRIP_OPTS = 
+#LIBRARY_STRIP_OPTS = -x -S   # Note: -S strips debugging symbols
+# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but
+#  developers doing their own dynamic loading should set this to 
+#  $(DYLD_APP_STRIP_OPTS)).
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Typical 
+# user-defined rules are before_install and after_install (please don't 
+# redefine things like install or app, as they are owned by the top-level 
+# Makefile API), which are rules that get invoked before and after the install 
+# target runs.  Such rules should be specified with the '::' syntax rather than 
+# a single colon.
diff --git a/inetd.tproj/Makefile.preamble b/inetd.tproj/Makefile.preamble
new file mode 100644
index 0000000..2c9003c
--- /dev/null
+++ b/inetd.tproj/Makefile.preamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags here.  To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+
+BUNDLELDFLAGS =            # use iff project is a bundle
+PALETTELDFLAGS =           # use iff project is a palette
+
+## Specify which headers in this project should be published to the outside 
+## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be 
+## prepended by DSTROOT, below.  Any subset of these public headers can be
+## precompiled automatically after installation, with extra user-defined flags.
+PUBLIC_HEADER_DIR = 
+PUBLIC_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+## Configure what is linked in at each level here.  Libraries are only used in
+## the final 'app' linking step.  Final 'app' linking is only done via the
+## 'app', 'debug', and 'profile' targets when they are invoked for
+## the top-level app.
+
+# Additional relocatables to be linked in at this level
+OTHER_OFILES = 
+# Additional libs to link apps against ('app' target)
+#OTHER_LIBS = 
+# Additional libs to link apps against ('debug' target)
+OTHER_DEBUG_LIBS = 
+# Additional libs to link apps against ('profile' target)
+OTHER_PROF_LIBS = 
+
+# More 'app' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# More 'debug' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_DEBUG_LIBS = 
+# More 'profile' libs when $(JAPANESE) = "YES"
+OTHER_JAPANESE_PROF_LIBS = 
+
+# If this is a bundle, and you *know* the enclosing application will not
+# be linking with a library which you require in your bundle code, then
+# mention it here so that it gets linked into the bundle.  Note that this
+# is wasteful but sometimes necessary.
+BUNDLE_LIBS = 
+
+## Configure how things get built here.  Additional dependencies, sourcefiles, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+# Precompiled headers to be built before any compilation occurs (e.g., draw.p)
+PRECOMPS = 
+
+# Targets to be built before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# Set the following to "YES" if you want the old behavior of recursively
+# cleaning all nested subprojects during 'make clean'.
+CLEAN_ALL_SUBPROJECTS =
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+# To include a version string, project source must exist in a directory named
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/inetd.tproj/PB.project b/inetd.tproj/PB.project
new file mode 100644
index 0000000..2eafcda
--- /dev/null
+++ b/inetd.tproj/PB.project
@@ -0,0 +1,41 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (pathnames.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (inetd.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, inetd.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = inetd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/inetd.tproj/inetd.8 b/inetd.tproj/inetd.8
new file mode 100644
index 0000000..cc11efe
--- /dev/null
+++ b/inetd.tproj/inetd.8
@@ -0,0 +1,381 @@
+.\" Copyright (c) 1985, 1991, 1993, 1994
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)inetd.8	8.4 (Berkeley) 6/1/94
+.\"
+.Dd June 1, 1994
+.Dt INETD 8
+.Os BSD 4.4
+.Sh NAME
+.Nm inetd
+.Nd internet
+.Dq super-server
+.Sh SYNOPSIS
+.Nm inetd
+.Op Fl d
+.Op Fl R Ar rate
+.Op Ar configuration file
+.Sh DESCRIPTION
+The
+.Nm inetd
+program
+should be run at boot time by
+.Pa /etc/rc
+(see
+.Xr rc 8 ) .
+It then listens for connections on certain
+internet sockets.  When a connection is found on one
+of its sockets, it decides what service the socket
+corresponds to, and invokes a program to service the request.
+The server program is invoked with the service socket
+as its standard input, output and error descriptors.
+After the program is
+finished,
+.Nm inetd
+continues to listen on the socket (except in some cases which
+will be described below).  Essentially,
+.Nm inetd
+allows running one daemon to invoke several others,
+reducing load on the system.
+.Pp
+The options available for
+.Nm inetd:
+.Bl -tag -width Ds
+.It Fl d
+Turns on debugging.
+.It Fl R Ar rate
+Specifies the maximum number of times a service can be invoked
+in one minute; the default is 1000.
+.El
+.Pp
+Upon execution,
+.Nm inetd
+reads its configuration information from a configuration
+file which, by default, is
+.Pa /etc/inetd.conf .
+There must be an entry for each field of the configuration
+file, with entries for each field separated by a tab or
+a space.  Comments are denoted by a ``#'' at the beginning
+of a line.  There must be an entry for each field.  The
+fields of the configuration file are as follows:
+.Pp
+.Bd -unfilled -offset indent -compact
+service name
+socket type
+protocol
+wait/nowait
+user
+server program
+server program arguments
+.Ed
+.Pp
+There are two types of services that 
+.Nm inetd
+can start: standard and TCPMUX.
+A standard service has a well-known port assigned to it;
+it may be a service that implements an official Internet standard or is a
+BSD-specific service.
+As described in 
+.Tn RFC 1078 ,
+TCPMUX services are nonstandard services that do not have a 
+well-known port assigned to them.
+They are invoked from
+.Nm inetd 
+when a program connects to the
+.Dq tcpmux
+well-known port and specifies
+the service name.  
+This feature is useful for adding locally-developed servers.
+.Pp
+The
+.Em service-name
+entry is the name of a valid service in
+the file
+.Pa /etc/services .
+For
+.Dq internal
+services (discussed below), the service
+name
+.Em must
+be the official name of the service (that is, the first entry in
+.Pa /etc/services ) .
+For TCPMUX services, the value of the
+.Em service-name
+field consists of the string
+.Dq tcpmux
+followed by a slash and the
+locally-chosen service name. 
+The service names listed in 
+.Pa /etc/services
+and the name 
+.Dq help
+are reserved.
+Try to choose unique names for your TCPMUX services by prefixing them with
+your organization's name and suffixing them with a version number.
+.Pp
+The
+.Em socket-type
+should be one of
+.Dq stream ,
+.Dq dgram ,
+.Dq raw ,
+.Dq rdm ,
+or
+.Dq seqpacket ,
+depending on whether the socket is a stream, datagram, raw,
+reliably delivered message, or sequenced packet socket.
+TCPMUX services must use 
+.Dq stream .
+.Pp
+The
+.Em protocol
+must be a valid protocol as given in
+.Pa /etc/protocols .
+Examples might be
+.Dq tcp
+or
+.Dq udp .
+TCPMUX services must use 
+.Dq tcp .
+.Pp
+The
+.Em wait/nowait
+entry specifies whether the server that is invoked by inetd will take over
+the socket associated with the service access point, and thus whether
+.Nm inetd
+should wait for the server to exit before listening for new service
+requests.
+Datagram servers must use
+.Dq wait ,
+as they are always invoked with the original datagram socket bound
+to the specified service address.
+These servers must read at least one datagram from the socket
+before exiting.
+If a datagram server connects
+to its peer, freeing the socket so
+.Nm inetd
+can received further messages on the socket, it is said to be
+a
+.Dq multi-threaded
+server;
+it should read one datagram from the socket and create a new socket
+connected to the peer.
+It should fork, and the parent should then exit
+to allow
+.Nm inetd
+to check for new service requests to spawn new servers.
+Datagram servers which process all incoming datagrams
+on a socket and eventually time out are said to be
+.Dq single-threaded .
+.Xr Comsat 8 ,
+.Pq Xr biff 1
+and
+.Xr talkd 8
+are both examples of the latter type of
+datagram server.
+.Xr Tftpd 8
+is an example of a multi-threaded datagram server.
+.Pp
+Servers using stream sockets generally are multi-threaded and
+use the
+.Dq nowait
+entry.
+Connection requests for these services are accepted by
+.Nm inetd ,
+and the server is given only the newly-accepted socket connected
+to a client of the service.
+Most stream-based services operate in this manner.
+Stream-based servers that use
+.Dq wait
+are started with the listening service socket, and must accept
+at least one connection request before exiting.
+Such a server would normally accept and process incoming connection
+requests until a timeout.
+TCPMUX services must use 
+.Dq nowait .
+.Pp
+The
+.Em user
+entry should contain the user name of the user as whom the server
+should run.  This allows for servers to be given less permission
+than root.
+.Pp
+The
+.Em server-program
+entry should contain the pathname of the program which is to be
+executed by
+.Nm inetd
+when a request is found on its socket.  If
+.Nm inetd
+provides this service internally, this entry should
+be
+.Dq internal .
+.Pp
+The
+.Em server program arguments
+should be just as arguments
+normally are, starting with argv[0], which is the name of
+the program.  If the service is provided internally, the
+word
+.Dq internal
+should take the place of this entry.
+.Pp
+The
+.Nm inetd
+program
+provides several
+.Dq trivial
+services internally by use of
+routines within itself.  These services are
+.Dq echo ,
+.Dq discard ,
+.Dq chargen
+(character generator),
+.Dq daytime
+(human readable time), and
+.Dq time
+(machine readable time,
+in the form of the number of seconds since midnight, January
+1, 1900).  All of these services are tcp based.  For
+details of these services, consult the appropriate
+.Tn RFC
+from the Network Information Center.
+.Pp
+The
+.Nm inetd
+program
+rereads its configuration file when it receives a hangup signal,
+.Dv SIGHUP .
+Services may be added, deleted or modified when the configuration file
+is reread.
+Except when started in debugging mode,
+.Nm
+records its process ID in the file
+.Pa /var/run/inetd.pid
+to assist in reconfiguration.
+.Sh TCPMUX
+.Pp
+.Tn RFC 1078 
+describes the TCPMUX protocol:
+``A TCP client connects to a foreign host on TCP port 1.  It sends the
+service name followed by a carriage-return line-feed <CRLF>.  The
+service name is never case sensitive.  The server replies with a
+single character indicating positive (+) or negative (\-)
+acknowledgment, immediately followed by an optional message of
+explanation, terminated with a <CRLF>.  If the reply was positive,
+the selected protocol begins; otherwise the connection is closed.''
+The program is passed the TCP connection as file descriptors 0 and 1.
+.Pp
+If the TCPMUX service name begins with a ``+'',
+.Nm inetd
+returns the positive reply for the program.
+This allows you to invoke programs that use stdin/stdout
+without putting any special server code in them.
+.Pp
+The special service name
+.Dq help
+causes
+.Nm inetd
+to list TCPMUX services in
+.Pa inetd.conf .
+.ne 1i
+.Sh "EXAMPLES"
+.Pp
+Here are several example service entries for the various types of services:
+.Bd -literal
+ftp           stream  tcp   nowait root  /usr/libexec/ftpd       ftpd -l
+ntalk         dgram   udp   wait   root  /usr/libexec/ntalkd     ntalkd
+tcpmux/+date  stream  tcp   nowait guest /bin/date               date
+tcpmux/phonebook stream tcp nowait guest /usr/local/bin/phonebook phonebook
+.Ed
+.Sh "ERROR MESSAGES"
+The
+.Nm inetd
+server
+logs error messages using
+.Xr syslog 3 .
+Important error messages and their explanations are:
+.Bd -literal
+\fIservice\fP/\fIprotocol\fP server failing (looping), service terminated.
+.Ed
+The number of requests for the specified service in the past minute
+exceeded the limit. The limit exists to prevent a broken program
+or a malicious user from swamping the system.
+This message may occur for several reasons:
+1) there are lots of hosts requesting the service within a short time period,
+2) a 'broken' client program is requesting the service too frequently,
+3) a malicious user is running a program to invoke the service in
+a 'denial of service' attack, or
+4) the invoked service program has an error that causes clients
+to retry quickly.
+Use the
+.Op Fl R 
+option,
+as described above, to change the rate limit.
+Once the limit is reached, the service will be
+reenabled automatically in 10 minutes.
+.sp
+.Bd -literal
+\fIservice\fP/\fIprotocol\fP: No such user '\fIuser\fP', service ignored
+\fIservice\fP/\fIprotocol\fP: getpwnam: \fIuser\fP: No such user
+.Ed
+No entry for 
+.Em user
+exists in the 
+.Pa passwd
+file. The first message
+occurs when
+.Nm inetd
+(re)reads the configuration file. The second message occurs when the
+service is invoked.
+.sp
+.Bd -literal
+\fIservice\fP: can't set uid \fInumber\fP
+\fIservice\fP: can't set gid \fInumber\fP
+.Ed
+The user or group ID for the entry's 
+.Em user
+is invalid.
+.Sh SEE ALSO
+.Xr comsat 8 ,
+.Xr fingerd 8 ,
+.Xr ftpd 8 ,
+.Xr rexecd 8 ,
+.Xr rlogind 8 ,
+.Xr rshd 8 ,
+.Xr telnetd 8 ,
+.Xr tftpd 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 .
+TCPMUX is based on code and documentation by Mark Lottor.
diff --git a/inetd.tproj/inetd.c b/inetd.tproj/inetd.c
new file mode 100644
index 0000000..1b93a68
--- /dev/null
+++ b/inetd.tproj/inetd.c
@@ -0,0 +1,1293 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1991, 1993, 1994\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)inetd.c	8.4 (Berkeley) 4/13/94";
+#endif /* not lint */
+
+/*
+ * Inetd - Internet super-server
+ *
+ * This program invokes all internet services as needed.  Connection-oriented
+ * services are invoked each time a connection is made, by creating a process.
+ * This process is passed the connection as file descriptor 0 and is expected
+ * to do a getpeername to find out the source host and port.
+ *
+ * Datagram oriented services are invoked when a datagram
+ * arrives; a process is created and passed a pending message
+ * on file descriptor 0.  Datagram servers may either connect
+ * to their peer, freeing up the original socket for inetd
+ * to receive further messages on, or ``take over the socket'',
+ * processing all arriving datagrams and, eventually, timing
+ * out.	 The first type of server is said to be ``multi-threaded'';
+ * the second type of server ``single-threaded''. 
+ *
+ * Inetd uses a configuration file which is read at startup
+ * and, possibly, at some later time in response to a hangup signal.
+ * The configuration file is ``free format'' with fields given in the
+ * order shown below.  Continuation lines for an entry must being with
+ * a space or tab.  All fields must be present in each entry.
+ *
+ *	service name			must be in /etc/services or must
+ *					name a tcpmux service
+ *	socket type			stream/dgram/raw/rdm/seqpacket
+ *	protocol			must be in /etc/protocols
+ *	wait/nowait			single-threaded/multi-threaded
+ *	user				user to run daemon as
+ *	server program			full path name
+ *	server program arguments	maximum of MAXARGS (20)
+ *
+ * TCP services without official port numbers are handled with the
+ * RFC1078-based tcpmux internal service. Tcpmux listens on port 1 for
+ * requests. When a connection is made from a foreign host, the service
+ * requested is passed to tcpmux, which looks it up in the servtab list
+ * and returns the proper entry for the service. Tcpmux returns a
+ * negative reply if the service doesn't exist, otherwise the invoked
+ * server is expected to return the positive reply if the service type in
+ * inetd.conf file has the prefix "tcpmux/". If the service type has the
+ * prefix "tcpmux/+", tcpmux will return the positive reply for the
+ * process; this is for compatibility with older server code, and also
+ * allows you to invoke programs that use stdin/stdout without putting any
+ * special server code in them. Services that use tcpmux are "nowait"
+ * because they do not have a well-known port and hence cannot listen
+ * for new requests.
+ *
+ * Comment lines are indicated by a `#' in column 1.
+ */
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "pathnames.h"
+
+#define	TOOMANY		100		/* don't start more than TOOMANY */
+#define	CNT_INTVL	60		/* servers in CNT_INTVL sec. */
+#define	RETRYTIME	(60*10)		/* retry after bind or server fail */
+
+#define	SIGBLOCK	(sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM))
+
+
+int	debug = 0;
+int	nsock, maxsock;
+fd_set	allsock;
+int	options;
+int	timingout;
+int	toomany = TOOMANY;
+struct	servent *sp;
+
+struct	servtab {
+	char	*se_service;		/* name of service */
+	int	se_socktype;		/* type of socket to use */
+	char	*se_proto;		/* protocol used */
+	short	se_wait;		/* single threaded server */
+	short	se_checked;		/* looked at during merge */
+	char	*se_user;		/* user name to run as */
+	struct	biltin *se_bi;		/* if built-in, description */
+	char	*se_server;		/* server program */
+#define	MAXARGV 20
+	char	*se_argv[MAXARGV+1];	/* program arguments */
+	int	se_fd;			/* open descriptor */
+	int	se_type;		/* type */
+	struct	sockaddr_in se_ctrladdr;/* bound address */
+	int	se_count;		/* number started since se_time */
+	struct	timeval se_time;	/* start of se_count */
+	struct	servtab *se_next;
+} *servtab;
+
+#define NORM_TYPE	0
+#define MUX_TYPE	1
+#define MUXPLUS_TYPE	2
+#define ISMUX(sep)	(((sep)->se_type == MUX_TYPE) || \
+			 ((sep)->se_type == MUXPLUS_TYPE))
+#define ISMUXPLUS(sep)	((sep)->se_type == MUXPLUS_TYPE)
+
+
+void		chargen_dg __P((int, struct servtab *));
+void		chargen_stream __P((int, struct servtab *));
+void		close_sep __P((struct servtab *));
+void		config __P((int));
+void		daytime_dg __P((int, struct servtab *));
+void		daytime_stream __P((int, struct servtab *));
+void		discard_dg __P((int, struct servtab *));
+void		discard_stream __P((int, struct servtab *));
+void		echo_dg __P((int, struct servtab *));
+void		echo_stream __P((int, struct servtab *));
+void		endconfig __P((void));
+struct servtab *enter __P((struct servtab *));
+void		freeconfig __P((struct servtab *));
+struct servtab *getconfigent __P((void));
+void		machtime_dg __P((int, struct servtab *));
+void		machtime_stream __P((int, struct servtab *));
+char	       *newstr __P((char *));
+char	       *nextline __P((FILE *));
+void		print_service __P((char *, struct servtab *));
+void		reapchild __P((int));
+void		retry __P((int));
+int		setconfig __P((void));
+void		setup __P((struct servtab *));
+char	       *sskip __P((char **));
+char	       *skip __P((char **));
+struct servtab *tcpmux __P((int));
+
+struct biltin {
+	char	*bi_service;		/* internally provided service name */
+	int	bi_socktype;		/* type of socket supported */
+	short	bi_fork;		/* 1 if should fork before call */
+	short	bi_wait;		/* 1 if should wait for child */
+	void	(*bi_fn)();		/* function which performs it */
+} biltins[] = {
+	/* Echo received data */
+	{ "echo",	SOCK_STREAM,	1, 0,	echo_stream },
+	{ "echo",	SOCK_DGRAM,	0, 0,	echo_dg },
+
+	/* Internet /dev/null */
+	{ "discard",	SOCK_STREAM,	1, 0,	discard_stream },
+	{ "discard",	SOCK_DGRAM,	0, 0,	discard_dg },
+
+	/* Return 32 bit time since 1970 */
+	{ "time",	SOCK_STREAM,	0, 0,	machtime_stream },
+	{ "time",	SOCK_DGRAM,	0, 0,	machtime_dg },
+
+	/* Return human-readable time */
+	{ "daytime",	SOCK_STREAM,	0, 0,	daytime_stream },
+	{ "daytime",	SOCK_DGRAM,	0, 0,	daytime_dg },
+
+	/* Familiar character generator */
+	{ "chargen",	SOCK_STREAM,	1, 0,	chargen_stream },
+	{ "chargen",	SOCK_DGRAM,	0, 0,	chargen_dg },
+
+	{ "tcpmux",	SOCK_STREAM,	1, 0,	(void (*)())tcpmux },
+
+	{ NULL }
+};
+
+#define NUMINT	(sizeof(intab) / sizeof(struct inent))
+char	*CONFIG = _PATH_INETDCONF;
+char	*pid_file = _PATH_INETDPID;
+char	**Argv;
+char 	*LastArg;
+
+int
+main(argc, argv, envp)
+	int argc;
+	char *argv[], *envp[];
+{
+	struct servtab *sep;
+	struct passwd *pwd;
+	struct sigvec sv;
+	int tmpint, ch, dofork;
+	pid_t pid;
+	char buf[50];
+
+	Argv = argv;
+	if (envp == 0 || *envp == 0)
+		envp = argv;
+	while (*envp)
+		envp++;
+	LastArg = envp[-1] + strlen(envp[-1]);
+
+	openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
+
+	while ((ch = getopt(argc, argv, "dR:p:")) != EOF)
+		switch(ch) {
+		case 'd':
+			debug = 1;
+			options |= SO_DEBUG;
+			break;
+		case 'R': {	/* invocation rate */
+			char *p;
+
+			tmpint = strtol(optarg, &p, 0);
+			if (tmpint < 1 || *p)
+				syslog(LOG_ERR,
+			         "-R %s: bad value for service invocation rate",
+					optarg);
+			else
+				toomany = tmpint;
+			break;
+		}
+		case 'p': 
+			pid_file = optarg;
+			break;
+		case '?':
+		default:
+			syslog(LOG_ERR,
+				"usage: inetd [-d] [-R rate] [conf-file]");
+			exit(1);
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc > 0)
+		CONFIG = argv[0];
+	if (debug == 0) {
+		FILE *fp;
+		daemon(0, 0);
+
+		pid = getpid();
+		fp = fopen(pid_file, "w");
+		if( fp ) {
+			fprintf(fp, "%ld\n", (long)pid);
+			fclose(fp);
+		} else {
+			syslog(LOG_WARNING, "%s: %m", pid_file);
+		}
+	}
+	memset(&sv, 0, sizeof(sv));
+	sv.sv_mask = SIGBLOCK;
+	sv.sv_handler = retry;
+	sigvec(SIGALRM, &sv, (struct sigvec *)0);
+	config(SIGHUP);
+	sv.sv_handler = config;
+	sigvec(SIGHUP, &sv, (struct sigvec *)0);
+	sv.sv_handler = reapchild;
+	sigvec(SIGCHLD, &sv, (struct sigvec *)0);
+
+	{
+		/* space for daemons to overwrite environment for ps */
+#define	DUMMYSIZE	100
+		char dummy[DUMMYSIZE];
+
+		(void)memset(dummy, 'x', sizeof(DUMMYSIZE) - 1);
+		dummy[DUMMYSIZE - 1] = '\0';
+		(void)setenv("inetd_dummy", dummy, 1);
+	}
+
+	for (;;) {
+	    int n, ctrl;
+	    fd_set readable;
+
+	    if (nsock == 0) {
+		(void) sigblock(SIGBLOCK);
+		while (nsock == 0)
+		    sigpause(0L);
+		(void) sigsetmask(0L);
+	    }
+	    readable = allsock;
+	    if ((n = select(maxsock + 1, &readable, (fd_set *)0,
+		(fd_set *)0, (struct timeval *)0)) <= 0) {
+		    if (n < 0 && errno != EINTR) {
+			syslog(LOG_WARNING, "select: %m");
+	 		sleep(1);
+		    }
+		    continue;
+	    }
+	    for (sep = servtab; n && sep; sep = sep->se_next)
+	        if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) {
+		    n--;
+		    if (debug)
+			    fprintf(stderr, "someone wants %s\n",
+				sep->se_service);
+		    if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
+			    ctrl = accept(sep->se_fd, (struct sockaddr *)0,
+				(int *)0);
+			    if (debug)
+				    fprintf(stderr, "accept, ctrl %d\n", ctrl);
+			    if (ctrl < 0) {
+				    if (errno != EINTR)
+					    syslog(LOG_WARNING,
+						"accept (for %s): %m",
+						sep->se_service);
+				    continue;
+			    }
+			    /*
+			     * Call tcpmux to find the real service to exec.
+			     */
+			    if (sep->se_bi &&
+				sep->se_bi->bi_fn == (void (*)()) tcpmux) {
+				    sep = tcpmux(ctrl);
+				    if (sep == NULL) {
+					    close(ctrl);
+					    continue;
+				    }
+			    }
+		    } else
+			    ctrl = sep->se_fd;
+		    (void) sigblock(SIGBLOCK);
+		    pid = 0;
+		    dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork);
+		    if (dofork) {
+			    if (sep->se_count++ == 0)
+				(void)gettimeofday(&sep->se_time,
+				    (struct timezone *)0);
+			    else if (sep->se_count >= toomany) {
+				struct timeval now;
+
+				(void)gettimeofday(&now, (struct timezone *)0);
+				if (now.tv_sec - sep->se_time.tv_sec >
+				    CNT_INTVL) {
+					sep->se_time = now;
+					sep->se_count = 1;
+				} else {
+					syslog(LOG_ERR,
+			"%s/%s server failing (looping), service terminated",
+					    sep->se_service, sep->se_proto);
+					close_sep(sep);
+					sigsetmask(0L);
+					if (!timingout) {
+						timingout = 1;
+						alarm(RETRYTIME);
+					}
+					continue;
+				}
+			    }
+			    pid = fork();
+		    }
+		    if (pid < 0) {
+			    syslog(LOG_ERR, "fork: %m");
+			    if (!sep->se_wait &&
+				sep->se_socktype == SOCK_STREAM)
+				    close(ctrl);
+			    sigsetmask(0L);
+			    sleep(1);
+			    continue;
+		    }
+		    if (pid && sep->se_wait) {
+			    sep->se_wait = pid;
+			    if (sep->se_fd >= 0) {
+				FD_CLR(sep->se_fd, &allsock);
+			        nsock--;
+			    }
+		    }
+		    sigsetmask(0L);
+		    if (pid == 0) {
+			    if (debug && dofork)
+				setsid();
+			    if (dofork) {
+				if (debug)
+					fprintf(stderr, "+ Closing from %d\n",
+						maxsock);
+				for (tmpint = maxsock; tmpint > 2; tmpint--)
+					if (tmpint != ctrl)
+						close(tmpint);
+			    }
+			    if (sep->se_bi)
+				(*sep->se_bi->bi_fn)(ctrl, sep);
+			    else {
+				if (debug)
+					fprintf(stderr, "%d execl %s\n",
+					    getpid(), sep->se_server);
+				dup2(ctrl, 0);
+				close(ctrl);
+				dup2(0, 1);
+				dup2(0, 2);
+				if ((pwd = getpwnam(sep->se_user)) == NULL) {
+					syslog(LOG_ERR,
+					    "%s/%s: %s: No such user",
+						sep->se_service, sep->se_proto,
+						sep->se_user);
+					if (sep->se_socktype != SOCK_STREAM)
+						recv(0, buf, sizeof (buf), 0);
+					_exit(1);
+				}
+				if (pwd->pw_uid) {
+					if (setgid(pwd->pw_gid) < 0) {
+						syslog(LOG_ERR,
+						  "%s: can't set gid %d: %m", 
+						  sep->se_service, pwd->pw_gid);
+						_exit(1);
+					}
+					(void) initgroups(pwd->pw_name,
+							pwd->pw_gid);
+					if (setuid(pwd->pw_uid) < 0) {
+						syslog(LOG_ERR,
+						  "%s: can't set uid %d: %m", 
+						  sep->se_service, pwd->pw_uid);
+						_exit(1);
+					}
+				}
+				execv(sep->se_server, sep->se_argv);
+				if (sep->se_socktype != SOCK_STREAM)
+					recv(0, buf, sizeof (buf), 0);
+				syslog(LOG_ERR,
+				    "cannot execute %s: %m", sep->se_server);
+				_exit(1);
+			    }
+		    }
+		    if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
+			    close(ctrl);
+		}
+	}
+}
+
+void
+reapchild(signo)
+	int signo;
+{
+	int status;
+	pid_t pid;
+	struct servtab *sep;
+
+	for (;;) {
+		pid = wait3(&status, WNOHANG, (struct rusage *)0);
+		if (pid <= 0)
+			break;
+		if (debug)
+			fprintf(stderr, "%d reaped, status %#x\n", 
+				pid, status);
+		for (sep = servtab; sep; sep = sep->se_next)
+			if (sep->se_wait == pid) {
+				if (status)
+					syslog(LOG_WARNING,
+					    "%s: exit status 0x%x",
+					    sep->se_server, status);
+				if (debug)
+					fprintf(stderr, "restored %s, fd %d\n",
+					    sep->se_service, sep->se_fd);
+				FD_SET(sep->se_fd, &allsock);
+				nsock++;
+				sep->se_wait = 1;
+			}
+	}
+}
+
+void
+config(signo)
+	int signo;
+{
+	struct servtab *sep, *cp, **sepp;
+	struct passwd *pwd;
+	long omask;
+
+	if (!setconfig()) {
+		syslog(LOG_ERR, "%s: %m", CONFIG);
+		return;
+	}
+	for (sep = servtab; sep; sep = sep->se_next)
+		sep->se_checked = 0;
+	while (cp = getconfigent()) {
+		if ((pwd = getpwnam(cp->se_user)) == NULL) {
+			syslog(LOG_ERR,
+				"%s/%s: No such user '%s', service ignored",
+				cp->se_service, cp->se_proto, cp->se_user);
+			continue;
+		}
+		for (sep = servtab; sep; sep = sep->se_next)
+			if (strcmp(sep->se_service, cp->se_service) == 0 &&
+			    strcmp(sep->se_proto, cp->se_proto) == 0)
+				break;
+		if (sep != 0) {
+			int i;
+
+			omask = sigblock(SIGBLOCK);
+			/*
+			 * sep->se_wait may be holding the pid of a daemon
+			 * that we're waiting for.  If so, don't overwrite
+			 * it unless the config file explicitly says don't 
+			 * wait.
+			 */
+			if (cp->se_bi == 0 && 
+			    (sep->se_wait == 1 || cp->se_wait == 0))
+				sep->se_wait = cp->se_wait;
+#define SWAP(a, b) { char *c = a; a = b; b = c; }
+			if (cp->se_user)
+				SWAP(sep->se_user, cp->se_user);
+			if (cp->se_server)
+				SWAP(sep->se_server, cp->se_server);
+			for (i = 0; i < MAXARGV; i++)
+				SWAP(sep->se_argv[i], cp->se_argv[i]);
+			sigsetmask(omask);
+			freeconfig(cp);
+			if (debug)
+				print_service("REDO", sep);
+		} else {
+			sep = enter(cp);
+			if (debug)
+				print_service("ADD ", sep);
+		}
+		sep->se_checked = 1;
+		if (ISMUX(sep)) {
+			sep->se_fd = -1;
+			continue;
+		}
+		sp = getservbyname(sep->se_service, sep->se_proto);
+		if (sp == 0) {
+			syslog(LOG_ERR, "%s/%s: unknown service",
+			    sep->se_service, sep->se_proto);
+			sep->se_checked = 0;
+			continue;
+		}
+		if (sp->s_port != sep->se_ctrladdr.sin_port) {
+			sep->se_ctrladdr.sin_family = AF_INET;
+			sep->se_ctrladdr.sin_port = sp->s_port;
+			if (sep->se_fd >= 0)
+				close_sep(sep);
+		}
+		if (sep->se_fd == -1)
+			setup(sep);
+	}
+	endconfig();
+	/*
+	 * Purge anything not looked at above.
+	 */
+	omask = sigblock(SIGBLOCK);
+	sepp = &servtab;
+	while (sep = *sepp) {
+		if (sep->se_checked) {
+			sepp = &sep->se_next;
+			continue;
+		}
+		*sepp = sep->se_next;
+		if (sep->se_fd >= 0)
+			close_sep(sep);
+		if (debug)
+			print_service("FREE", sep);
+		freeconfig(sep);
+		free((char *)sep);
+	}
+	(void) sigsetmask(omask);
+}
+
+void
+retry(signo)
+	int signo;
+{
+	struct servtab *sep;
+
+	timingout = 0;
+	for (sep = servtab; sep; sep = sep->se_next)
+		if (sep->se_fd == -1)
+			setup(sep);
+}
+
+void
+setup(sep)
+	struct servtab *sep;
+{
+	int on = 1;
+
+	if ((sep->se_fd = socket(AF_INET, sep->se_socktype, 0)) < 0) {
+		if (debug)
+			fprintf(stderr, "socket failed on %s/%s: %s\n", 
+				sep->se_service, sep->se_proto,
+				strerror(errno));
+		syslog(LOG_ERR, "%s/%s: socket: %m",
+		    sep->se_service, sep->se_proto);
+		return;
+	}
+#define	turnon(fd, opt) \
+setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
+	if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&
+	    turnon(sep->se_fd, SO_DEBUG) < 0)
+		syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
+	if (turnon(sep->se_fd, SO_REUSEADDR) < 0)
+		syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m");
+#undef turnon
+	if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr,
+	    sizeof (sep->se_ctrladdr)) < 0) {
+		if (debug)
+			fprintf(stderr, "bind failed on %s/%s: %s\n",
+				sep->se_service, sep->se_proto,
+				strerror(errno));
+		syslog(LOG_ERR, "%s/%s: bind: %m",
+		    sep->se_service, sep->se_proto);
+		(void) close(sep->se_fd);
+		sep->se_fd = -1;
+		if (!timingout) {
+			timingout = 1;
+			alarm(RETRYTIME);
+		}
+		return;
+	}
+	if (sep->se_socktype == SOCK_STREAM)
+		listen(sep->se_fd, 10);
+	FD_SET(sep->se_fd, &allsock);
+	nsock++;
+	if (sep->se_fd > maxsock)
+		maxsock = sep->se_fd;
+	if (debug) {
+		fprintf(stderr, "registered %s on %d\n",
+			sep->se_server, sep->se_fd);
+	}
+}
+
+/*
+ * Finish with a service and its socket.
+ */
+void
+close_sep(sep)
+	struct servtab *sep;
+{
+	if (sep->se_fd >= 0) {
+		nsock--;
+		FD_CLR(sep->se_fd, &allsock);
+		(void) close(sep->se_fd);
+		sep->se_fd = -1;
+	}
+	sep->se_count = 0;
+	/*
+	 * Don't keep the pid of this running deamon: when reapchild()
+	 * reaps this pid, it would erroneously increment nsock.
+	 */
+	if (sep->se_wait > 1)
+		sep->se_wait = 1;
+}
+
+struct servtab *
+enter(cp)
+	struct servtab *cp;
+{
+	struct servtab *sep;
+	long omask;
+
+	sep = (struct servtab *)malloc(sizeof (*sep));
+	if (sep == (struct servtab *)0) {
+		syslog(LOG_ERR, "Out of memory.");
+		exit(-1);
+	}
+	*sep = *cp;
+	sep->se_fd = -1;
+	omask = sigblock(SIGBLOCK);
+	sep->se_next = servtab;
+	servtab = sep;
+	sigsetmask(omask);
+	return (sep);
+}
+
+FILE	*fconfig = NULL;
+struct	servtab serv;
+char	line[LINE_MAX];
+
+int
+setconfig()
+{
+
+	if (fconfig != NULL) {
+		fseek(fconfig, 0L, SEEK_SET);
+		return (1);
+	}
+	fconfig = fopen(CONFIG, "r");
+	return (fconfig != NULL);
+}
+
+void
+endconfig()
+{
+	if (fconfig) {
+		(void) fclose(fconfig);
+		fconfig = NULL;
+	}
+}
+
+struct servtab *
+getconfigent()
+{
+	struct servtab *sep = &serv;
+	int argc;
+	char *cp, *arg;
+	static char TCPMUX_TOKEN[] = "tcpmux/";
+#define MUX_LEN		(sizeof(TCPMUX_TOKEN)-1)
+
+more:
+	while ((cp = nextline(fconfig)) && (*cp == '#' || *cp == '\0'))
+		;
+	if (cp == NULL)
+		return ((struct servtab *)0);
+	/*
+	 * clear the static buffer, since some fields (se_ctrladdr,
+	 * for example) don't get initialized here.
+	 */
+	memset((caddr_t)sep, 0, sizeof *sep);
+	arg = skip(&cp);
+	if (cp == NULL) {
+		/* got an empty line containing just blanks/tabs. */
+		goto more;
+	}
+	if (strncmp(arg, TCPMUX_TOKEN, MUX_LEN) == 0) {
+		char *c = arg + MUX_LEN;
+		if (*c == '+') {
+			sep->se_type = MUXPLUS_TYPE;
+			c++;
+		} else
+			sep->se_type = MUX_TYPE;
+		sep->se_service = newstr(c);
+	} else {
+		sep->se_service = newstr(arg);
+		sep->se_type = NORM_TYPE;
+	}
+	arg = sskip(&cp);
+	if (strcmp(arg, "stream") == 0)
+		sep->se_socktype = SOCK_STREAM;
+	else if (strcmp(arg, "dgram") == 0)
+		sep->se_socktype = SOCK_DGRAM;
+	else if (strcmp(arg, "rdm") == 0)
+		sep->se_socktype = SOCK_RDM;
+	else if (strcmp(arg, "seqpacket") == 0)
+		sep->se_socktype = SOCK_SEQPACKET;
+	else if (strcmp(arg, "raw") == 0)
+		sep->se_socktype = SOCK_RAW;
+	else
+		sep->se_socktype = -1;
+	sep->se_proto = newstr(sskip(&cp));
+	arg = sskip(&cp);
+	sep->se_wait = strcmp(arg, "wait") == 0;
+	if (ISMUX(sep)) {
+		/*
+		 * Silently enforce "nowait" for TCPMUX services since
+		 * they don't have an assigned port to listen on.
+		 */
+		sep->se_wait = 0;
+
+		if (strcmp(sep->se_proto, "tcp")) {
+			syslog(LOG_ERR, 
+				"%s: bad protocol for tcpmux service %s",
+				CONFIG, sep->se_service);
+			goto more;
+		}
+		if (sep->se_socktype != SOCK_STREAM) {
+			syslog(LOG_ERR, 
+				"%s: bad socket type for tcpmux service %s",
+				CONFIG, sep->se_service);
+			goto more;
+		}
+	}
+	sep->se_user = newstr(sskip(&cp));
+	sep->se_server = newstr(sskip(&cp));
+	if (strcmp(sep->se_server, "internal") == 0) {
+		struct biltin *bi;
+
+		for (bi = biltins; bi->bi_service; bi++)
+			if (bi->bi_socktype == sep->se_socktype &&
+			    strcmp(bi->bi_service, sep->se_service) == 0)
+				break;
+		if (bi->bi_service == 0) {
+			syslog(LOG_ERR, "internal service %s unknown",
+				sep->se_service);
+			goto more;
+		}
+		sep->se_bi = bi;
+		sep->se_wait = bi->bi_wait;
+	} else
+		sep->se_bi = NULL;
+	argc = 0;
+	for (arg = skip(&cp); cp; arg = skip(&cp))
+		if (argc < MAXARGV)
+			sep->se_argv[argc++] = newstr(arg);
+	while (argc <= MAXARGV)
+		sep->se_argv[argc++] = NULL;
+	return (sep);
+}
+
+void
+freeconfig(cp)
+	struct servtab *cp;
+{
+	int i;
+
+	if (cp->se_service)
+		free(cp->se_service);
+	if (cp->se_proto)
+		free(cp->se_proto);
+	if (cp->se_user)
+		free(cp->se_user);
+	if (cp->se_server)
+		free(cp->se_server);
+	for (i = 0; i < MAXARGV; i++)
+		if (cp->se_argv[i])
+			free(cp->se_argv[i]);
+}
+
+
+/*
+ * Safe skip - if skip returns null, log a syntax error in the
+ * configuration file and exit.
+ */
+char *
+sskip(cpp)
+	char **cpp;
+{
+	char *cp;
+
+	cp = skip(cpp);
+	if (cp == NULL) {
+		syslog(LOG_ERR, "%s: syntax error", CONFIG);
+		exit(-1);
+	}
+	return (cp);
+}
+
+char *
+skip(cpp)
+	char **cpp;
+{
+	char *cp = *cpp;
+	char *start;
+
+again:
+	while (*cp == ' ' || *cp == '\t')
+		cp++;
+	if (*cp == '\0') {
+		int c;
+
+		c = getc(fconfig);
+		(void) ungetc(c, fconfig);
+		if (c == ' ' || c == '\t')
+			if (cp = nextline(fconfig))
+				goto again;
+		*cpp = (char *)0;
+		return ((char *)0);
+	}
+	start = cp;
+	while (*cp && *cp != ' ' && *cp != '\t')
+		cp++;
+	if (*cp != '\0')
+		*cp++ = '\0';
+	*cpp = cp;
+	return (start);
+}
+
+char *
+nextline(fd)
+	FILE *fd;
+{
+	char *cp;
+
+	if (fgets(line, sizeof (line), fd) == NULL)
+		return ((char *)0);
+	cp = strchr(line, '\n');
+	if (cp)
+		*cp = '\0';
+	return (line);
+}
+
+char *
+newstr(cp)
+	char *cp;
+{
+	if (cp = strdup(cp ? cp : ""))
+		return (cp);
+	syslog(LOG_ERR, "strdup: %m");
+	exit(-1);
+}
+
+void
+setproctitle(a, s)
+	char *a;
+	int s;
+{
+	int size;
+	char *cp;
+	struct sockaddr_in sin;
+	char buf[80];
+
+	cp = Argv[0];
+	size = sizeof(sin);
+	if (getpeername(s, (struct sockaddr *)&sin, &size) == 0)
+		(void) sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr)); 
+	else
+		(void) sprintf(buf, "-%s", a); 
+	strncpy(cp, buf, LastArg - cp);
+	cp += strlen(cp);
+	while (cp < LastArg)
+		*cp++ = ' ';
+}
+
+/*
+ * Internet services provided internally by inetd:
+ */
+#define	BUFSIZE	8192
+
+/* ARGSUSED */
+void
+echo_stream(s, sep)		/* Echo service -- echo data back */
+	int s;
+	struct servtab *sep;
+{
+	char buffer[BUFSIZE];
+	int i;
+
+	setproctitle(sep->se_service, s);
+	while ((i = read(s, buffer, sizeof(buffer))) > 0 &&
+	    write(s, buffer, i) > 0)
+		;
+	exit(0);
+}
+
+/* ARGSUSED */
+void
+echo_dg(s, sep)			/* Echo service -- echo data back */
+	int s;
+	struct servtab *sep;
+{
+	char buffer[BUFSIZE];
+	int i, size;
+	struct sockaddr sa;
+
+	size = sizeof(sa);
+	if ((i = recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size)) < 0)
+		return;
+	(void) sendto(s, buffer, i, 0, &sa, sizeof(sa));
+}
+
+/* ARGSUSED */
+void
+discard_stream(s, sep)		/* Discard service -- ignore data */
+	int s;
+	struct servtab *sep;
+{
+	int ret;
+	char buffer[BUFSIZE];
+
+	setproctitle(sep->se_service, s);
+	while (1) {
+		while ((ret = read(s, buffer, sizeof(buffer))) > 0)
+			;
+		if (ret == 0 || errno != EINTR)
+			break;
+	}
+	exit(0);
+}
+
+/* ARGSUSED */
+void
+discard_dg(s, sep)		/* Discard service -- ignore data */
+	int s;
+	struct servtab *sep;
+{
+	char buffer[BUFSIZE];
+
+	(void) read(s, buffer, sizeof(buffer));
+}
+
+#include <ctype.h>
+#define LINESIZ 72
+char ring[128];
+char *endring;
+
+void
+initring()
+{
+	int i;
+
+	endring = ring;
+
+	for (i = 0; i <= 128; ++i)
+		if (isprint(i))
+			*endring++ = i;
+}
+
+/* ARGSUSED */
+void
+chargen_stream(s, sep)		/* Character generator */
+	int s;
+	struct servtab *sep;
+{
+	int len;
+	char *rs, text[LINESIZ+2];
+
+	setproctitle(sep->se_service, s);
+
+	if (!endring) {
+		initring();
+		rs = ring;
+	}
+
+	text[LINESIZ] = '\r';
+	text[LINESIZ + 1] = '\n';
+	for (rs = ring;;) {
+		if ((len = endring - rs) >= LINESIZ)
+			memmove(text, rs, LINESIZ);
+		else {
+			memmove(text, rs, len);
+			memmove(text + len, ring, LINESIZ - len);
+		}
+		if (++rs == endring)
+			rs = ring;
+		if (write(s, text, sizeof(text)) != sizeof(text))
+			break;
+	}
+	exit(0);
+}
+
+/* ARGSUSED */
+void
+chargen_dg(s, sep)		/* Character generator */
+	int s;
+	struct servtab *sep;
+{
+	struct sockaddr sa;
+	static char *rs;
+	int len, size;
+	char text[LINESIZ+2];
+
+	if (endring == 0) {
+		initring();
+		rs = ring;
+	}
+
+	size = sizeof(sa);
+	if (recvfrom(s, text, sizeof(text), 0, &sa, &size) < 0)
+		return;
+
+	if ((len = endring - rs) >= LINESIZ)
+		memmove(text, rs, LINESIZ);
+	else {
+		memmove(text, rs, len);
+		memmove(text + len, ring, LINESIZ - len);
+	}
+	if (++rs == endring)
+		rs = ring;
+	text[LINESIZ] = '\r';
+	text[LINESIZ + 1] = '\n';
+	(void) sendto(s, text, sizeof(text), 0, &sa, sizeof(sa));
+}
+
+/*
+ * Return a machine readable date and time, in the form of the
+ * number of seconds since midnight, Jan 1, 1900.  Since gettimeofday
+ * returns the number of seconds since midnight, Jan 1, 1970,
+ * we must add 2208988800 seconds to this figure to make up for
+ * some seventy years Bell Labs was asleep.
+ */
+
+long
+machtime()
+{
+	struct timeval tv;
+
+	if (gettimeofday(&tv, (struct timezone *)0) < 0) {
+		if (debug)
+			fprintf(stderr, "Unable to get time of day\n");
+		return (0L);
+	}
+#define	OFFSET ((u_long)25567 * 24*60*60)
+	return (htonl((long)(tv.tv_sec + OFFSET)));
+#undef OFFSET
+}
+
+/* ARGSUSED */
+void
+machtime_stream(s, sep)
+	int s;
+	struct servtab *sep;
+{
+	long result;
+
+	result = machtime();
+	(void) write(s, (char *) &result, sizeof(result));
+}
+
+/* ARGSUSED */
+void
+machtime_dg(s, sep)
+	int s;
+	struct servtab *sep;
+{
+	long result;
+	struct sockaddr sa;
+	int size;
+
+	size = sizeof(sa);
+	if (recvfrom(s, (char *)&result, sizeof(result), 0, &sa, &size) < 0)
+		return;
+	result = machtime();
+	(void) sendto(s, (char *) &result, sizeof(result), 0, &sa, sizeof(sa));
+}
+
+/* ARGSUSED */
+void
+daytime_stream(s, sep)		/* Return human-readable time of day */
+	int s;
+	struct servtab *sep;
+{
+	char buffer[256];
+	time_t clock;
+
+	clock = time((time_t *) 0);
+
+	(void) sprintf(buffer, "%.24s\r\n", ctime(&clock));
+	(void) write(s, buffer, strlen(buffer));
+}
+
+/* ARGSUSED */
+void
+daytime_dg(s, sep)		/* Return human-readable time of day */
+	int s;
+	struct servtab *sep;
+{
+	char buffer[256];
+	time_t clock;
+	struct sockaddr sa;
+	int size;
+
+	clock = time((time_t *) 0);
+
+	size = sizeof(sa);
+	if (recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size) < 0)
+		return;
+	(void) sprintf(buffer, "%.24s\r\n", ctime(&clock));
+	(void) sendto(s, buffer, strlen(buffer), 0, &sa, sizeof(sa));
+}
+
+/*
+ * print_service:
+ *	Dump relevant information to stderr
+ */
+void
+print_service(action, sep)
+	char *action;
+	struct servtab *sep;
+{
+	fprintf(stderr,
+	    "%s: %s proto=%s, wait=%d, user=%s builtin=%x server=%s\n",
+	    action, sep->se_service, sep->se_proto,
+	    sep->se_wait, sep->se_user, (int)sep->se_bi, sep->se_server);
+}
+
+/*
+ *  Based on TCPMUX.C by Mark K. Lottor November 1988
+ *  sri-nic::ps:<mkl>tcpmux.c
+ */
+
+
+static int		/* # of characters upto \r,\n or \0 */
+getline(fd, buf, len)
+	int fd;
+	char *buf;
+	int len;
+{
+	int count = 0, n;
+
+	do {
+		n = read(fd, buf, len-count);
+		if (n == 0)
+			return (count);
+		if (n < 0)
+			return (-1);
+		while (--n >= 0) {
+			if (*buf == '\r' || *buf == '\n' || *buf == '\0')
+				return (count);
+			count++;
+			buf++;
+		}
+	} while (count < len);
+	return (count);
+}
+
+#define MAX_SERV_LEN	(256+2)		/* 2 bytes for \r\n */
+
+#define strwrite(fd, buf)	(void) write(fd, buf, sizeof(buf)-1)
+
+struct servtab *
+tcpmux(s)
+	int s;
+{
+	struct servtab *sep;
+	char service[MAX_SERV_LEN+1];
+	int len;
+
+	/* Get requested service name */
+	if ((len = getline(s, service, MAX_SERV_LEN)) < 0) {
+		strwrite(s, "-Error reading service name\r\n");
+		return (NULL);
+	}
+	service[len] = '\0';
+
+	if (debug)
+		fprintf(stderr, "tcpmux: someone wants %s\n", service);
+
+	/*
+	 * Help is a required command, and lists available services,
+	 * one per line.
+	 */
+	if (!strcasecmp(service, "help")) {
+		for (sep = servtab; sep; sep = sep->se_next) {
+			if (!ISMUX(sep))
+				continue;
+			(void)write(s,sep->se_service,strlen(sep->se_service));
+			strwrite(s, "\r\n");
+		}
+		return (NULL);
+	}
+
+	/* Try matching a service in inetd.conf with the request */
+	for (sep = servtab; sep; sep = sep->se_next) {
+		if (!ISMUX(sep))
+			continue;
+		if (!strcasecmp(service, sep->se_service)) {
+			if (ISMUXPLUS(sep)) {
+				strwrite(s, "+Go\r\n");
+			}
+			return (sep);
+		}
+	}
+	strwrite(s, "-Service not available\r\n");
+	return (NULL);
+}
diff --git a/inetd.tproj/pathnames.h b/inetd.tproj/pathnames.h
new file mode 100644
index 0000000..4a7b367
--- /dev/null
+++ b/inetd.tproj/pathnames.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/6/93
+ */
+
+#include <paths.h>
+
+#define	_PATH_INETDCONF	"/etc/inetd.conf"
+
+#ifndef _PATH_VARRUN
+#define    _PATH_VARRUN    "/var/run/"
+#endif
+
+#define _PATH_INETDPID      _PATH_VARRUN "inetd.pid"
diff --git a/ipfw.tproj/Makefile b/ipfw.tproj/Makefile
new file mode 100644
index 0000000..7114d40
--- /dev/null
+++ b/ipfw.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the Apple Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ipfw
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = ipfw.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble ipfw.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /sbin
+WINDOWS_INSTALLDIR = /Library/Executables
+PDO_UNIX_INSTALLDIR = /bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ipfw.tproj/Makefile.postamble b/ipfw.tproj/Makefile.postamble
new file mode 100644
index 0000000..ef51853
--- /dev/null
+++ b/ipfw.tproj/Makefile.postamble
@@ -0,0 +1,104 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGES: langages in which the project is written (default "English")
+#  English_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+
+install-man-page:
+	install -d $(DSTROOT)/usr/share/man/man8
+	install -c -m 444 ipfw.8 $(DSTROOT)/usr/share/man/man8/ipfw.8
diff --git a/ipfw.tproj/Makefile.preamble b/ipfw.tproj/Makefile.preamble
new file mode 100644
index 0000000..a4606c6
--- /dev/null
+++ b/ipfw.tproj/Makefile.preamble
@@ -0,0 +1,140 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.  For library projects you should
+#       set this to something like /Developer/Headers/$(NAME).  Do not set
+#       this variable for framework projects unless you do not want the
+#       header files included in the framework.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. This defaults to
+#       DYNAMIC.
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Uncomment to suppress generation of a KeyValueCoding index when installing 
+# frameworks (This index is used by WOB and IB to determine keys available
+# for an object).  Set to YES by default.
+# PREINDEX_FRAMEWORK = NO
+
+# Change this definition to install projects somewhere other than the
+# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
+# and "" on other systems.
+DSTROOT = $(HOME)
+
+AFTER_INSTALL += install-man-page
+
diff --git a/ipfw.tproj/PB.project b/ipfw.tproj/PB.project
new file mode 100644
index 0000000..ab3c121
--- /dev/null
+++ b/ipfw.tproj/PB.project
@@ -0,0 +1,25 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        OTHER_LINKED = (ipfw.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, ipfw.8); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_INSTALLDIR = /bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ipfw; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = /Library/Executables; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ipfw.tproj/ipfw.8 b/ipfw.tproj/ipfw.8
new file mode 100644
index 0000000..26a7980
--- /dev/null
+++ b/ipfw.tproj/ipfw.8
@@ -0,0 +1,733 @@
+.\"
+.\" $Id: ipfw.8,v 1.1.1.1 2000/01/11 01:48:49 wsanchez Exp $
+.\"
+.Dd July 20, 1996
+.Dt IPFW 8 SMM
+.Os FreeBSD
+.Sh NAME
+.Nm ipfw
+.Nd controlling utility for IP firewall
+.Sh SYNOPSIS
+.Nm ipfw
+.Op Fl q
+.Oo
+.Fl p Ar preproc
+.Op Fl D Ar macro Ns Op Ns =value
+.Op Fl U Ar macro
+.Oc
+file
+.Nm ipfw
+.Oo
+.Fl f
+|
+.Fl q
+.Oc
+flush
+.Nm ipfw
+.Oo
+.Fl q
+.Oc
+zero
+.Op Ar number ...
+.Nm ipfw
+delete
+.Ar number ...
+.Nm ipfw
+.Op Fl aftN
+list
+.Op Ar number ...
+.Nm ipfw
+.Oo
+.Fl ftN
+.Oc
+show
+.Op Ar number ...
+.Nm ipfw
+.Oo
+.Fl q
+.Oc
+add
+.Op Ar number
+.Ar action 
+.Op log
+.Ar proto
+from
+.Ar src
+to
+.Ar dst
+.Op via Ar name | ipno
+.Op Ar options
+.Sh DESCRIPTION
+If used as shown in the first synopsis line, the
+.Ar file
+will be read line by line and applied as arguments to the 
+.Nm
+command.
+.Pp
+Optionally, a preprocessor can be specified using
+.Fl p Ar preproc
+where
+.Ar file
+is to be piped through.  Useful preprocessors include
+.Xr cpp 1
+and
+.Xr m4 1 .
+If
+.Ar preproc
+doesn't start with a slash as its first character, the usual
+.Ev PATH
+name search is performed.  Care should be taken with this in environments
+where not all filesystems are mounted (yet) by the time
+.Nm
+is being run (e. g. since they are mounted over NFS).  Once
+.Fl p
+has been specified, optional
+.Fl D
+and
+.Fl U
+specifications can follow and will be passed on to the preprocessor.
+This allows for flexible configuration files (like conditionalizing
+them on the local hostname) and the use of macros to centralize
+frequently required arguments like IP addresses.
+.Pp
+Each packet that has been received or is about to be sent goes through
+the
+.Nm
+rules. In the case of a host acting as a gateway, packets that are
+forwarded by the host are processed by
+.Nm
+twice
+.Po
+once when entering, and once when leaving
+.Pc .
+Each packet can be filtered based on the following information that is
+associated with it:
+.Pp
+.Bl -tag -offset indent -compact -width xxxx
+.It Receive Interface Pq Ar recv
+Interface over which the packet was received
+.It Transmit Interface Pq Ar xmit
+Interface over which the packet would be transmitted
+.It Incoming Pq Ar in
+Packet was just received
+.It Outgoing Pq Ar out
+Packet would be transmitted
+.It Source IP Address
+Sender's IP Address
+.It Destination IP Address
+Target's IP Address
+.It Protocol
+IP protocol, including but not limited to IP
+.Pq Ar ip ,
+UDP
+.Pq Ar udp ,
+TCP
+.Pq Ar tcp ,
+or
+ICMP
+.Pq Ar icmp
+.It Source Port
+Sender's UDP or TCP port
+.It Destination Port
+Target's UDP or TCP port
+.It Connection Setup Flag Pq Ar setup
+This packet is a request to setup a TCP connection
+.It Connection Established Flag Pq Ar established
+This packet is part of an established TCP connection
+.It All TCP Flags Pq Ar tcpflags
+One or more of the TCP flags: close connection
+.Pq Ar fin ,
+open connection
+.Pq Ar syn ,
+reset connection
+.Pq Ar rst ,
+push
+.Pq Ar psh ,
+acknowledgment
+.Pq Ar ack ,
+and
+urgent
+.Pq Ar urg
+.It Fragment Flag Pq Ar frag
+This packet is a fragment of an IP packet
+.It IP Options Pq Ar ipoptions
+One or more of the IP options: strict source route
+.Pq Ar ssrr ,
+loose source route
+.Pq Ar lsrr ,
+record route
+.Pq Ar rr ,
+and timestamp
+.Pq Ar ts
+.It ICMP Types Pq Ar icmptypes
+One or more of the ICMP types: echo reply
+.Pq Ar 0 ,
+destination unreachable
+.Pq Ar 3 ,
+source quench
+.Pq Ar 4 ,
+redirect
+.Pq Ar 5 ,
+echo request
+.Pq Ar 8 ,
+router advertisement
+.Pq Ar 9 ,
+router solicitation
+.Pq Ar 10 ,
+time-to-live exceeded
+.Pq Ar 11 ,
+IP header bad
+.Pq Ar 12 ,
+timestamp request
+.Pq Ar 13 ,
+timestamp reply
+.Pq Ar 14 ,
+information request
+.Pq Ar 15 ,
+information reply
+.Pq Ar 16 ,
+address mask request
+.Pq Ar 17 ,
+and address mask reply
+.Pq Ar 18
+.El
+.Pp
+Note that may be dangerous to filter on the source IP address or
+source TCP/UDP port because either or both could easily be spoofed.
+.Pp
+The
+.Nm
+code works by going through the rule-list for each packet
+until a match is found.
+All rules have two associated counters, a packet count and
+a byte count.
+These counters are updated when a packet matches the rule.
+.Pp
+The rules are ordered by a 
+.Dq line-number
+from 1 to 65534 that is used
+to order and delete rules. Rules are tried in increasing order, and the
+first rule that matches a packet applies.
+Multiple rules may share the same number and apply in
+the order in which they were added.
+.Pp
+If a rule is added without a number, it is numbered 100 higher than the highest
+defined rule number, unless the highest defined rule number is 65435 or
+greater, in which case new rules are given that same number.
+.Pp
+The delete operation deletes the first rule with number
+.Ar number ,
+if any.
+.Pp
+The list command prints out the current rule set.
+.Pp
+The show command is equivalent to 
+.Sq ipfw -a list .
+.Pp
+The zero operation zeroes the counters associated with rule number
+.Ar number .
+.Pp
+The flush operation removes all rules.
+.Pp
+Any command beginning with a 
+.Sq # ,
+or being all blank, is ignored.
+.Pp
+One rule is always present:
+.Bd -literal -offset center
+65535 deny all from any to any
+.Ed
+.Pp
+This rule is the default policy, i.e., don't allow anything at all.
+Your job in setting up rules is to modify this policy to match your
+needs.
+.Pp
+However, if the kernel option
+.Dq IPFIREWALL_DEFAULT_TO_ACCEPT
+is active, the rule is instead:
+.Bd -literal -offset center
+65535 allow all from any to any
+.Ed
+.Pp
+This variation lets everything pass through.  This option should only be
+activated in particular circumstances, such as if you use the firewall
+system as an on-demand denial-of-service filter that is normally wide open.
+.Pp
+The following options are available:
+.Bl -tag -width flag
+.It Fl a
+While listing, show counter values.  See also 
+.Dq show
+command.
+.It Fl f
+Don't ask for confirmation for commands that can cause problems if misused
+(i.e. flush).
+.Ar Note ,
+if there is no tty associated with the process, this is implied.
+.It Fl q
+While adding, zeroing or flushing, be quiet about actions (implies '-f'). 
+This is useful for adjusting rules by executing multiple
+.Nm
+commands in a script
+.Po
+e.g.,
+.Sq sh /etc/rc.firewall
+.Pc ,
+or by processing a file of many
+.Nm 
+rules,
+across a remote login session.  If a flush is performed in normal
+(verbose) mode (with the default kernel configuration), it prints a message.
+Because all rules are flushed, the
+message cannot be delivered to the login session.  This causes the
+remote login session to be closed and the remainder of the ruleset is
+not processed.  Access to the console is required to recover.
+.It Fl t
+While listing, show last match timestamp.
+.It Fl N
+Try to resolve addresses and service names in output.
+.El
+.Pp
+.Ar action :
+.Bl -hang -offset flag -width 1234567890123456
+.It Ar allow
+Allow packets that match rule.
+The search terminates. Aliases are
+.Ar pass ,
+.Ar permit ,
+and
+.Ar accept .
+.It Ar deny
+Discard packets that match this rule.
+The search terminates.
+.Ar Drop
+is an alias for
+.Ar deny .
+.It Ar reject
+(Deprecated.) Discard packets that match this rule, and try to send an ICMP
+host unreachable notice.
+The search terminates.
+.It Ar unreach code
+Discard packets that match this rule, and try to send an ICMP
+unreachable notice with code
+.Ar code ,
+where
+.Ar code
+is a number from zero to 255, or one of these aliases:
+.Ar net ,
+.Ar host ,
+.Ar protocol ,
+.Ar port ,
+.Ar needfrag ,
+.Ar srcfail ,
+.Ar net-unknown ,
+.Ar host-unknown ,
+.Ar isolated ,
+.Ar net-prohib ,
+.Ar host-prohib ,
+.Ar tosnet ,
+.Ar toshost ,
+.Ar filter-prohib ,
+.Ar host-precedence ,
+or
+.Ar precedence-cutoff .
+The search terminates.
+.It Ar reset
+TCP packets only. Discard packets that match this rule,
+and try to send a TCP reset
+.Pq RST
+notice.
+The search terminates.
+.It Ar count
+Update counters for all packets that match rule.
+The search continues with the next rule.
+.It Ar divert port
+Divert packets that match this rule to the
+.Xr divert 4
+socket bound to port
+.Ar port .
+The search terminates.
+.It Ar tee port
+Send a copy of packets matching this rule to the
+.Xr divert 4
+socket bound to port
+.Ar port .
+The search continues with the next rule. This feature is not yet implemeted.
+.It Ar fwd ipaddr Op ,port
+Change the next-hop on matching packets to
+.Ar ipaddr ,
+which can be an IP address in dotted quad or a host name.
+If
+.Ar ipaddr
+is not a directly-reachable address, the route 
+as found in the local routing table for that IP is used
+instead.
+If
+.Ar ipaddr
+is a local address, then on a packet entering the system from a remote
+host it will be diverted to
+.Ar port
+on the local machine, keeping the local address of the socket set
+to the original IP address the packet was destined for. This is intended
+for use with transparent proxy servers. If the IP is not
+a local address then the port number (if specified) is ignored and
+the rule only applies to packets leaving the system. This will
+also map addresses to local ports when packets are generated locally.
+The search terminates if this rule matches. If the port number is not 
+given then the port number in the packet is used, so that a packet for
+an external machine port Y would be forwarded to local port Y. The kernel
+must have been compiled with optiions IPFIREWALL_FORWARD.
+.It Ar skipto number
+Skip all subsequent rules numbered less than
+.Ar number .
+The search continues with the first rule numbered
+.Ar number
+or higher.
+.El
+.Pp
+If a packet matches more than one
+.Ar divert
+and/or
+.Ar tee
+rule, all but the last are ignored.
+.Pp
+If the kernel was compiled with
+.Dv IPFIREWALL_VERBOSE ,
+then when a packet matches a rule with the
+.Ar log
+keyword a message will be printed on the console.
+If the kernel was compiled with the
+.Dv IPFIREWALL_VERBOSE_LIMIT
+option, then logging will cease after the number of packets
+specified by the option are received for that particular
+chain entry.  Logging may then be re-enabled by clearing
+the packet counter for that entry.
+.Pp
+Console logging and the log limit are adjustable dynamically
+through the
+.Xr sysctl 8
+interface.
+.Pp
+.Ar proto :
+.Bl -hang -offset flag -width 1234567890123456
+.It Ar ip
+All packets match. The alias
+.Ar all
+has the same effect.
+.It Ar tcp
+Only TCP packets match.
+.It Ar udp
+Only UDP packets match.
+.It Ar icmp
+Only ICMP packets match.
+.It Ar <number|name>
+Only packets for the specified protocol matches (see
+.Pa /etc/protocols
+for a complete list).
+.El
+.Pp
+.Ar src 
+and
+.Ar dst :
+.Bl -hang -offset flag
+.It Ar <address/mask>
+.Op Ar ports
+.El
+.Pp
+The
+.Em <address/mask>
+may be specified as:
+.Bl -hang -offset flag -width 1234567890123456
+.It Ar ipno
+An ipnumber of the form 1.2.3.4.
+Only this exact ip number match the rule.
+.It Ar ipno/bits
+An ipnumber with a mask width of the form 1.2.3.4/24.
+In this case all ip numbers from 1.2.3.0 to 1.2.3.255 will match.
+.It Ar ipno:mask
+An ipnumber with a mask width of the form 1.2.3.4:255.255.240.0.
+In this case all ip numbers from 1.2.0.0 to 1.2.15.255 will match.
+.El
+.Pp
+The sense of the match can be inverted by preceding an address with the
+.Dq not
+modifier, causing all other addresses to be matched instead. This
+does not affect the selection of port numbers.
+.Pp
+With the TCP and UDP protocols, optional
+.Em ports
+may be specified as:
+.Pp
+.Bl -hang -offset flag
+.It Ns {port|port-port} Ns Op ,port Ns Op ,...
+.El
+.Pp
+Service names (from 
+.Pa /etc/services )
+may be used instead of numeric port values.
+A range may only be specified as the first value,
+and the length of the port list is limited to
+.Dv IP_FW_MAX_PORTS
+(as defined in 
+.Pa /usr/src/sys/netinet/ip_fw.h )
+ports.
+.Pp
+Fragmented packets which have a non-zero offset (i.e. not the first
+fragment) will never match a rule which has one or more port
+specifications.  See the
+.Ar frag
+option for details on matching fragmented packets.
+.Pp
+Rules can apply to packets when they are incoming, or outgoing, or both.
+The
+.Ar in
+keyword indicates the rule should only match incoming packets.
+The
+.Ar out
+keyword indicates the rule should only match outgoing packets.
+.Pp
+To match packets going through a certain interface, specify
+the interface using
+.Ar via :
+.Bl -hang -offset flag -width 1234567890123456
+.It Ar via ifX
+Packet must be going through interface
+.Ar ifX.
+.It Ar via if*
+Packet must be going through interface
+.Ar ifX ,
+where X is any unit number.
+.It Ar via any
+Packet must be going through
+.Em some
+interface.
+.It Ar via ipno
+Packet must be going through the interface having IP address
+.Ar ipno .
+.El
+.Pp
+The
+.Ar via
+keyword causes the interface to always be checked.
+If
+.Ar recv
+or
+.Ar xmit
+is used instead of
+.Ar via ,
+then the only receive or transmit interface (respectively) is checked.
+By specifying both, it is possible to match packets based on both receive
+and transmit interface, e.g.:
+.Pp
+.Dl "ipfw add 100 deny ip from any to any out recv ed0 xmit ed1"
+.Pp
+The
+.Ar recv
+interface can be tested on either incoming or outgoing packets, while the
+.Ar xmit
+interface can only be tested on outgoing packets. So
+.Ar out
+is required (and
+.Ar in
+invalid) whenver
+.Ar xmit
+is used. Specifying
+.Ar via
+together with
+.Ar xmit
+or
+.Ar recv
+is invalid.
+.Pp
+A packet may not have a receive or transmit interface: packets originating
+from the local host have no receive interface. while packets destined for
+the local host have no transmit interface.
+.Pp
+Additional
+.Ar options :
+.Bl -hang -offset flag -width 1234567890123456
+.It frag
+Matches if the packet is a fragment and this is not the first fragment
+of the datagram.
+.Ar frag
+may not be used in conjunction with either
+.Ar tcpflags
+or TCP/UDP port specifications.
+.It in
+Matches if this packet was on the way in.
+.It out
+Matches if this packet was on the way out.
+.It ipoptions Ar spec
+Matches if the IP header contains the comma separated list of 
+options specified in
+.Ar spec .
+The supported IP options are:
+.Ar ssrr 
+(strict source route),
+.Ar lsrr 
+(loose source route),
+.Ar rr 
+(record packet route), and
+.Ar ts 
+(timestamp).
+The absence of a particular option may be denoted
+with a
+.Dq ! .
+.It established
+Matches packets that have the RST or ACK bits set.
+TCP packets only.
+.It setup
+Matches packets that have the SYN bit set but no ACK bit.
+TCP packets only.
+.It tcpflags Ar spec
+Matches if the TCP header contains the comma separated list of
+flags specified in
+.Ar spec .
+The supported TCP flags are:
+.Ar fin ,
+.Ar syn ,
+.Ar rst ,
+.Ar psh ,
+.Ar ack ,
+and
+.Ar urg .
+The absence of a particular flag may be denoted
+with a
+.Dq ! .
+A rule which contains a
+.Ar tcpflags
+specification can never match a fragmented packet which has
+a non-zero offset.  See the
+.Ar frag
+option for details on matching fragmented packets.
+.It icmptypes Ar types
+Matches if the ICMP type is in the list
+.Ar types .
+The list may be specified as any combination of ranges
+or individual types separated by commas.
+.El
+.Sh CHECKLIST
+Here are some important points to consider when designing your
+rules:
+.Bl -bullet -hang -offset flag 
+.It 
+Remember that you filter both packets going in and out.
+Most connections need packets going in both directions.
+.It
+Remember to test very carefully.
+It is a good idea to be near the console when doing this.
+.It
+Don't forget the loopback interface.
+.El
+.Sh FINE POINTS
+There is one kind of packet that the firewall will always discard,
+that is an IP fragment with a fragment offset of one.
+This is a valid packet, but it only has one use, to try to circumvent
+firewalls.
+.Pp
+If you are logged in over a network, loading the KLD version of
+.Nm
+is probably not as straightforward as you would think.
+I recommend this command line:
+.Bd -literal -offset center
+kldload /modules/ipfw.ko && \e
+ipfw add 32000 allow all from any to any
+.Ed
+.Pp
+Along the same lines, doing an
+.Bd -literal -offset center
+ipfw flush
+.Ed
+.Pp
+in similar surroundings is also a bad idea.
+.Pp
+The IP filter list may not be modified if the system security level
+is set to 3 or higher
+.Po
+see
+.Xr init 8
+for information on system security levels
+.Pc .
+.Sh PACKET DIVERSION
+A divert socket bound to the specified port will receive all packets diverted
+to that port; see
+.Xr divert 4 .
+If no socket is bound to the destination port, or if the kernel
+wasn't compiled with divert socket support, diverted packets are dropped.
+.Sh EXAMPLES
+This command adds an entry which denies all tcp packets from
+.Em cracker.evil.org
+to the telnet port of
+.Em wolf.tambov.su
+from being forwarded by the host:
+.Pp
+.Dl ipfw add deny tcp from cracker.evil.org to wolf.tambov.su 23
+.Pp 
+This one disallows any connection from the entire crackers network to
+my host:
+.Pp
+.Dl ipfw add deny all from 123.45.67.0/24 to my.host.org
+.Pp
+Here is a good usage of the
+.Ar list
+command to see accounting records
+and timestamp information:
+.Pp
+.Dl ipfw -at l
+.Pp
+or in short form without timestamps:
+.Pp
+.Dl ipfw -a l
+.Pp
+This rule diverts all incoming packets from 192.168.2.0/24 to divert port 5000:
+.Pp
+.Dl ipfw divert 5000 all from 192.168.2.0/24 to any in
+.Sh SEE ALSO
+.Xr cpp 1 ,
+.Xr m4 1 ,
+.Xr divert 4 ,
+.Xr ip 4 ,
+.Xr ipfirewall 4 ,
+.Xr protocols 5 ,
+.Xr services 5 ,
+.Xr init 8 ,
+.Xr kldload 8 ,
+.Xr reboot 8 ,
+.Xr sysctl 8 ,
+.Xr syslogd 8 .
+.Sh BUGS
+.Pp
+.Em WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!
+.Pp
+This program can put your computer in rather unusable state. When
+using it for the first time, work on the console of the computer, and
+do
+.Em NOT
+do anything you don't understand.
+.Pp
+When manipulating/adding chain entries, service and protocol names are
+not accepted.
+.Pp
+Incoming packet fragments diverted by
+.Ar divert
+are reassembled before delivery to the socket, whereas fragments diverted via
+.Ar tee
+are not.
+.Pp
+Port aliases containing dashes cannot be first in a list.
+.Pp
+The
+.Dq tee
+action is unimplemented.
+.Sh AUTHORS
+.An Ugen J. S. Antsilevich ,
+.An Poul-Henning Kamp ,
+.An Alex Nash ,
+.An Archie Cobbs .
+API based upon code written by
+.An Daniel Boulet
+for BSDI.
+.Sh HISTORY
+.Nm
+first appeared in
+.Fx 2.0 .
diff --git a/ipfw.tproj/ipfw.c b/ipfw.tproj/ipfw.c
new file mode 100644
index 0000000..7992ec4
--- /dev/null
+++ b/ipfw.tproj/ipfw.c
@@ -0,0 +1,1613 @@
+/*
+ * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
+ * Copyright (c) 1994 Ugen J.S.Antsilevich
+ *
+ * Idea and grammar partially left from:
+ * Copyright (c) 1993 Daniel Boulet
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * NEW command line interface for IP firewall facility
+ *
+ * $Id: ipfw.c,v 1.2 2000/06/07 04:22:47 lindak Exp $
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_fw.h>
+#include <net/route.h> /* def. of struct route */
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <netinet/ip_dummynet.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+int 		lineno = -1;
+
+int 		s;				/* main RAW socket 	   */
+int 		do_resolv=0;			/* Would try to resolve all */
+int		do_acct=0;			/* Show packet/byte count  */
+int		do_time=0;			/* Show time stamps        */
+int		do_quiet=0;			/* Be quiet in add and flush  */
+int		do_force=0;			/* Don't ask for confirmation */
+int		do_pipe=0;                      /* this cmd refers to a pipe */
+
+struct icmpcode {
+	int	code;
+	char	*str;
+};
+
+static struct icmpcode icmpcodes[] = {
+      { ICMP_UNREACH_NET,		"net" },
+      { ICMP_UNREACH_HOST,		"host" },
+      { ICMP_UNREACH_PROTOCOL,		"protocol" },
+      { ICMP_UNREACH_PORT,		"port" },
+      { ICMP_UNREACH_NEEDFRAG,		"needfrag" },
+      { ICMP_UNREACH_SRCFAIL,		"srcfail" },
+      { ICMP_UNREACH_NET_UNKNOWN,	"net-unknown" },
+      { ICMP_UNREACH_HOST_UNKNOWN,	"host-unknown" },
+      { ICMP_UNREACH_ISOLATED,		"isolated" },
+      { ICMP_UNREACH_NET_PROHIB,	"net-prohib" },
+      { ICMP_UNREACH_HOST_PROHIB,	"host-prohib" },
+      { ICMP_UNREACH_TOSNET,		"tosnet" },
+      { ICMP_UNREACH_TOSHOST,		"toshost" },
+      { ICMP_UNREACH_FILTER_PROHIB,	"filter-prohib" },
+      { ICMP_UNREACH_HOST_PRECEDENCE,	"host-precedence" },
+      { ICMP_UNREACH_PRECEDENCE_CUTOFF,	"precedence-cutoff" },
+      { 0, NULL }
+};
+
+static void show_usage(const char *fmt, ...);
+
+static int
+mask_bits(struct in_addr m_ad)
+{
+	int h_fnd=0,h_num=0,i;
+	u_long mask;
+
+	mask=ntohl(m_ad.s_addr);
+	for (i=0;i<sizeof(u_long)*CHAR_BIT;i++) {
+		if (mask & 1L) {
+			h_fnd=1;
+			h_num++;
+		} else {
+			if (h_fnd)
+				return -1;
+		}
+		mask=mask>>1;
+	}
+	return h_num;
+}                         
+
+static void
+print_port(prot, port, comma)
+	u_char  prot;
+	u_short port;
+	const char *comma;
+{
+	struct servent *se;
+	struct protoent *pe;
+	const char *protocol;
+	int printed = 0;
+
+	if (do_resolv) {
+		pe = getprotobynumber(prot);
+		if (pe)
+			protocol = pe->p_name;
+		else
+			protocol = NULL;
+
+		se = getservbyport(htons(port), protocol);
+		if (se) {
+			printf("%s%s", comma, se->s_name);
+			printed = 1;
+		}
+	} 
+	if (!printed)
+		printf("%s%d",comma,port);
+}
+
+static void
+print_iface(char *key, union ip_fw_if *un, int byname)
+{
+	char ifnb[FW_IFNLEN+1];
+
+	if (byname) {
+		strncpy(ifnb, un->fu_via_if.name, FW_IFNLEN);
+		ifnb[FW_IFNLEN]='\0';
+		if (un->fu_via_if.unit == -1)
+			printf(" %s %s*", key, ifnb);
+		else 
+			printf(" %s %s%d", key, ifnb, un->fu_via_if.unit);
+	} else if (un->fu_via_ip.s_addr != 0) {
+		printf(" %s %s", key, inet_ntoa(un->fu_via_ip));
+	} else
+		printf(" %s any", key);
+}
+
+static void
+print_reject_code(int code)
+{
+	struct icmpcode *ic;
+
+	for (ic = icmpcodes; ic->str; ic++)
+		if (ic->code == code) {
+			printf("%s", ic->str);
+			return;
+		}
+	printf("%u", code);
+}
+
+static void
+show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
+{
+	char *comma;
+	u_long adrt;
+	struct hostent *he;
+	struct protoent *pe;
+	int i, mb;
+	int nsp = IP_FW_GETNSRCP(chain);
+	int ndp = IP_FW_GETNDSTP(chain);
+
+	if (do_resolv)
+		setservent(1/*stayopen*/);
+
+	printf("%05u ", chain->fw_number);
+
+	if (do_acct) 
+		printf("%*qu %*qu ",pcwidth,chain->fw_pcnt,bcwidth,chain->fw_bcnt);
+
+	if (do_time)
+	{
+		if (chain->timestamp)
+		{
+			char timestr[30];
+
+			strcpy(timestr, ctime((time_t *)&chain->timestamp));
+			*strchr(timestr, '\n') = '\0';
+			printf("%s ", timestr);
+		}
+		else
+			printf("                         ");
+	}
+
+	switch (chain->fw_flg & IP_FW_F_COMMAND)
+	{
+		case IP_FW_F_ACCEPT:
+			printf("allow");
+			break;
+		case IP_FW_F_DENY:
+			printf("deny");
+			break;
+		case IP_FW_F_COUNT:
+			printf("count");
+			break;
+		case IP_FW_F_DIVERT:
+			printf("divert %u", chain->fw_divert_port);
+			break;
+		case IP_FW_F_TEE:
+			printf("tee %u", chain->fw_divert_port);
+			break;
+		case IP_FW_F_SKIPTO:
+			printf("skipto %u", chain->fw_skipto_rule);
+			break;
+                case IP_FW_F_PIPE:
+                        printf("pipe %u", chain->fw_skipto_rule);
+                        break ;
+		case IP_FW_F_REJECT:
+			if (chain->fw_reject_code == IP_FW_REJECT_RST)
+				printf("reset");
+			else {
+				printf("unreach ");
+				print_reject_code(chain->fw_reject_code);
+			}
+			break;
+		case IP_FW_F_FWD:
+			printf("fwd %s", inet_ntoa(chain->fw_fwd_ip.sin_addr));
+			if(chain->fw_fwd_ip.sin_port)
+				printf(",%d", chain->fw_fwd_ip.sin_port);
+			break;
+		default:
+			errx(EX_OSERR, "impossible");
+	}
+   
+	if (chain->fw_flg & IP_FW_F_PRN)
+		printf(" log");
+
+	pe = getprotobynumber(chain->fw_prot);
+	if (pe)
+		printf(" %s", pe->p_name);
+	else
+		printf(" %u", chain->fw_prot);
+
+	printf(" from %s", chain->fw_flg & IP_FW_F_INVSRC ? "not " : "");
+
+	adrt=ntohl(chain->fw_smsk.s_addr);
+	if (adrt==ULONG_MAX && do_resolv) {
+		adrt=(chain->fw_src.s_addr);
+		he=gethostbyaddr((char *)&adrt,sizeof(u_long),AF_INET);
+		if (he==NULL) {
+			printf(inet_ntoa(chain->fw_src));
+		} else
+			printf("%s",he->h_name);
+	} else {
+		if (adrt!=ULONG_MAX) {
+			mb=mask_bits(chain->fw_smsk);
+			if (mb == 0) {
+				printf("any");
+			} else {
+				if (mb > 0) {
+					printf(inet_ntoa(chain->fw_src));
+					printf("/%d",mb);
+				} else {
+					printf(inet_ntoa(chain->fw_src));
+					printf(":");
+					printf(inet_ntoa(chain->fw_smsk));
+				}
+			}
+		} else
+			printf(inet_ntoa(chain->fw_src));
+	}
+
+	if (chain->fw_prot == IPPROTO_TCP || chain->fw_prot == IPPROTO_UDP) {
+		comma = " ";
+		for (i = 0; i < nsp; i++) {
+			print_port(chain->fw_prot, chain->fw_uar.fw_pts[i], comma);
+			if (i==0 && (chain->fw_flg & IP_FW_F_SRNG))
+				comma = "-";
+			else
+				comma = ",";
+		}
+	}
+
+	printf(" to %s", chain->fw_flg & IP_FW_F_INVDST ? "not " : "");
+
+	adrt=ntohl(chain->fw_dmsk.s_addr);
+	if (adrt==ULONG_MAX && do_resolv) {
+		adrt=(chain->fw_dst.s_addr);
+		he=gethostbyaddr((char *)&adrt,sizeof(u_long),AF_INET);
+		if (he==NULL) {
+			printf(inet_ntoa(chain->fw_dst));
+		} else
+			printf("%s",he->h_name);
+	} else {
+		if (adrt!=ULONG_MAX) {
+			mb=mask_bits(chain->fw_dmsk);
+			if (mb == 0) {
+				printf("any");
+			} else {
+				if (mb > 0) {
+					printf(inet_ntoa(chain->fw_dst));
+					printf("/%d",mb);
+				} else {
+					printf(inet_ntoa(chain->fw_dst));
+					printf(":");
+					printf(inet_ntoa(chain->fw_dmsk));
+				}
+			}
+		} else
+			printf(inet_ntoa(chain->fw_dst));
+	}
+
+	if (chain->fw_prot == IPPROTO_TCP || chain->fw_prot == IPPROTO_UDP) {
+		comma = " ";
+		for (i = 0; i < ndp; i++) {
+			print_port(chain->fw_prot, chain->fw_uar.fw_pts[nsp+i], comma);
+			if (i==0 && (chain->fw_flg & IP_FW_F_DRNG))
+				comma = "-";
+			else
+				comma = ",";
+		}
+	}
+
+	/* Direction */
+	if ((chain->fw_flg & IP_FW_F_IN) && !(chain->fw_flg & IP_FW_F_OUT))
+		printf(" in");
+	if (!(chain->fw_flg & IP_FW_F_IN) && (chain->fw_flg & IP_FW_F_OUT))
+		printf(" out");
+
+	/* Handle hack for "via" backwards compatibility */
+	if ((chain->fw_flg & IF_FW_F_VIAHACK) == IF_FW_F_VIAHACK) {
+		print_iface("via",
+		    &chain->fw_in_if, chain->fw_flg & IP_FW_F_IIFNAME);
+	} else {
+		/* Receive interface specified */
+		if (chain->fw_flg & IP_FW_F_IIFACE)
+			print_iface("recv", &chain->fw_in_if,
+			    chain->fw_flg & IP_FW_F_IIFNAME);
+		/* Transmit interface specified */
+		if (chain->fw_flg & IP_FW_F_OIFACE)
+			print_iface("xmit", &chain->fw_out_if,
+			    chain->fw_flg & IP_FW_F_OIFNAME);
+	}
+
+	if (chain->fw_flg & IP_FW_F_FRAG)
+		printf(" frag");
+
+	if (chain->fw_ipopt || chain->fw_ipnopt) {
+		int 	_opt_printed = 0;
+#define PRINTOPT(x)	{if (_opt_printed) printf(",");\
+			printf(x); _opt_printed = 1;}
+
+		printf(" ipopt ");
+		if (chain->fw_ipopt  & IP_FW_IPOPT_SSRR) PRINTOPT("ssrr");
+		if (chain->fw_ipnopt & IP_FW_IPOPT_SSRR) PRINTOPT("!ssrr");
+		if (chain->fw_ipopt  & IP_FW_IPOPT_LSRR) PRINTOPT("lsrr");
+		if (chain->fw_ipnopt & IP_FW_IPOPT_LSRR) PRINTOPT("!lsrr");
+		if (chain->fw_ipopt  & IP_FW_IPOPT_RR)   PRINTOPT("rr");
+		if (chain->fw_ipnopt & IP_FW_IPOPT_RR)   PRINTOPT("!rr");
+		if (chain->fw_ipopt  & IP_FW_IPOPT_TS)   PRINTOPT("ts");
+		if (chain->fw_ipnopt & IP_FW_IPOPT_TS)   PRINTOPT("!ts");
+	} 
+
+	if (chain->fw_tcpf & IP_FW_TCPF_ESTAB) 
+		printf(" established");
+	else if (chain->fw_tcpf == IP_FW_TCPF_SYN &&
+	    chain->fw_tcpnf == IP_FW_TCPF_ACK)
+		printf(" setup");
+	else if (chain->fw_tcpf || chain->fw_tcpnf) {
+		int 	_flg_printed = 0;
+#define PRINTFLG(x)	{if (_flg_printed) printf(",");\
+			printf(x); _flg_printed = 1;}
+
+		printf(" tcpflg ");
+		if (chain->fw_tcpf  & IP_FW_TCPF_FIN)  PRINTFLG("fin");
+		if (chain->fw_tcpnf & IP_FW_TCPF_FIN)  PRINTFLG("!fin");
+		if (chain->fw_tcpf  & IP_FW_TCPF_SYN)  PRINTFLG("syn");
+		if (chain->fw_tcpnf & IP_FW_TCPF_SYN)  PRINTFLG("!syn");
+		if (chain->fw_tcpf  & IP_FW_TCPF_RST)  PRINTFLG("rst");
+		if (chain->fw_tcpnf & IP_FW_TCPF_RST)  PRINTFLG("!rst");
+		if (chain->fw_tcpf  & IP_FW_TCPF_PSH)  PRINTFLG("psh");
+		if (chain->fw_tcpnf & IP_FW_TCPF_PSH)  PRINTFLG("!psh");
+		if (chain->fw_tcpf  & IP_FW_TCPF_ACK)  PRINTFLG("ack");
+		if (chain->fw_tcpnf & IP_FW_TCPF_ACK)  PRINTFLG("!ack");
+		if (chain->fw_tcpf  & IP_FW_TCPF_URG)  PRINTFLG("urg");
+		if (chain->fw_tcpnf & IP_FW_TCPF_URG)  PRINTFLG("!urg");
+	} 
+	if (chain->fw_flg & IP_FW_F_ICMPBIT) {
+		int type_index;
+		int first = 1;
+
+		printf(" icmptype");
+
+		for (type_index = 0; type_index < IP_FW_ICMPTYPES_DIM * sizeof(unsigned) * 8; ++type_index)
+			if (chain->fw_uar.fw_icmptypes[type_index / (sizeof(unsigned) * 8)] & 
+				(1U << (type_index % (sizeof(unsigned) * 8)))) {
+				printf("%c%d", first == 1 ? ' ' : ',', type_index);
+				first = 0;
+			}
+	}
+	printf("\n");
+	if (do_resolv)
+		endservent();
+}
+
+static void
+list(ac, av)
+	int	ac;
+	char 	**av;
+{
+	struct ip_fw *rules;
+	struct dn_pipe *pipes;
+	void *data = NULL;
+	int pcwidth = 0;
+	int bcwidth = 0;
+	int n, num = 0;
+
+	/* get rules or pipes from kernel, resizing array as necessary */
+	{
+		const int unit = do_pipe ? sizeof(*pipes) : sizeof(*rules);
+		const int ocmd = do_pipe ? IP_DUMMYNET_GET : IP_FW_GET;
+		int nalloc = 0;
+		int nbytes;
+
+		while (num >= nalloc) {
+			nalloc = nalloc * 2 + 200;
+			nbytes = nalloc * unit;
+			if ((data = realloc(data, nbytes)) == NULL)
+				err(EX_OSERR, "realloc");
+			if (getsockopt(s, IPPROTO_IP, ocmd, data, &nbytes) < 0)
+				err(EX_OSERR, "getsockopt(IP_%s_GET)",
+				    do_pipe ? "DUMMYNET" : "FW");
+			num = nbytes / unit;
+		}
+	}
+
+	/* display requested pipes */
+	if (do_pipe) {
+	    u_long rulenum;
+
+	    pipes = (struct dn_pipe *) data;
+	    if (ac > 0)
+		rulenum = strtoul(*av++, NULL, 10);
+	    else
+		rulenum = 0 ;
+	    for (n = 0; n < num; n++) {
+		struct dn_pipe *const p = &pipes[n];
+		double b = p->bandwidth ;
+		char buf[30] ;
+		char qs[30] ;
+		char plr[30] ;
+		int l ;
+
+		if (rulenum != 0 && rulenum != p->pipe_nr)
+			continue;
+		if (b == 0)
+		    sprintf(buf, "unlimited");
+		else if (b >= 1000000)
+		    sprintf(buf, "%7.3f Mbit/s", b/1000000 );
+		else if (b >= 1000)
+		    sprintf(buf, "%7.3f Kbit/s", b/1000 );
+		else
+		    sprintf(buf, "%7.3f bit/s ", b );
+
+		if ( (l = p->queue_size_bytes) != 0 ) {
+		    if (l >= 8192)
+			sprintf(qs,"%d KB", l / 1024);
+		    else
+			sprintf(qs,"%d B", l);
+		} else
+		    sprintf(qs,"%3d sl.", p->queue_size);
+		if (p->plr)
+		    sprintf(plr,"plr %f", 1.0*p->plr/(double)(0x7fffffff));
+		else
+		    plr[0]='\0';
+
+		printf("%05d: %s %4d ms %s %s -- %d pkts (%d B) %d drops\n",
+		    p->pipe_nr, buf, p->delay, qs, plr,
+		    p->r_len, p->r_len_bytes, p->r_drops);
+	    }
+	    free(data);
+	    return;
+	}
+
+	/* if showing stats, figure out column widths ahead of time */
+	rules = (struct ip_fw *) data;
+	if (do_acct) {
+		for (n = 0; n < num; n++) {
+			struct ip_fw *const r = &rules[n];
+			char temp[32];
+			int width;
+
+			/* packet counter */
+			width = sprintf(temp, "%qu", r->fw_pcnt);
+			if (width > pcwidth)
+				pcwidth = width;
+
+			/* byte counter */
+			width = sprintf(temp, "%qu", r->fw_bcnt);
+			if (width > bcwidth)
+				bcwidth = width;
+		}
+	}
+	if (ac == 0) {
+		/* display all rules */
+		for (n = 0; n < num; n++) {
+			struct ip_fw *const r = &rules[n];
+
+			show_ipfw(r, pcwidth, bcwidth);
+		}
+	} else {
+		/* display specific rules requested on command line */
+		int exitval = EX_OK;
+
+		while (ac--) {
+			u_long rnum;
+			char *endptr;
+			int seen;
+
+			/* convert command line rule # */
+			rnum = strtoul(*av++, &endptr, 10);
+			if (*endptr) {
+				exitval = EX_USAGE;
+				warnx("invalid rule number: %s", *(av - 1));
+				continue;
+			}
+			for (seen = n = 0; n < num; n++) {
+				struct ip_fw *const r = &rules[n];
+
+				if (r->fw_number > rnum)
+					break;
+				if (r->fw_number == rnum) {
+					show_ipfw(r, pcwidth, bcwidth);
+					seen = 1;
+				}
+			}
+			if (!seen) {
+				/* give precedence to other error(s) */
+				if (exitval == EX_OK)
+					exitval = EX_UNAVAILABLE;
+				warnx("rule %lu does not exist", rnum);
+			}
+		}
+		if (exitval != EX_OK)
+			exit(exitval);
+	}
+	free(data);
+}
+
+static void
+show_usage(const char *fmt, ...)
+{
+	if (fmt) {
+		char buf[100];
+		va_list args;
+
+		va_start(args, fmt);
+		vsnprintf(buf, sizeof(buf), fmt, args);
+		va_end(args);
+		warnx("error: %s", buf);
+	}
+	fprintf(stderr, "usage: ipfw [options]\n"
+"    flush\n"
+"    add [number] rule\n"
+"    delete number ...\n"
+"    list [number ...]\n"
+"    show [number ...]\n"
+"    zero [number ...]\n"
+"  rule:  action proto src dst extras...\n"
+"    action:\n"
+"      {allow|permit|accept|pass|deny|drop|reject|unreach code|\n"
+"       reset|count|skipto num|divert port|tee port|fwd ip} [log]\n"
+"    proto: {ip|tcp|udp|icmp|<number>}\n"
+"    src: from [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
+"    dst: to [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
+"  extras:\n"
+"    fragment     (may not be used with ports or tcpflags)\n"
+"    in\n"
+"    out\n"
+"    {xmit|recv|via} {iface|ip|any}\n"
+"    {established|setup}\n"
+"    tcpflags [!]{syn|fin|rst|ack|psh|urg},...\n"
+"    ipoptions [!]{ssrr|lsrr|rr|ts},...\n"
+"    icmptypes {type[,type]}...\n");
+
+	exit(EX_USAGE);
+}
+
+static int
+lookup_host (host, ipaddr)
+	char *host;
+	struct in_addr *ipaddr;
+{
+	struct hostent *he = gethostbyname(host);
+
+    if (!he) {
+        if (inet_aton(host, ipaddr))
+            return(0);
+        else
+            return(-1);
+    }
+	*ipaddr = *(struct in_addr *)he->h_addr_list[0];
+
+	return(0);
+}
+
+static void
+fill_ip(ipno, mask, acp, avp)
+	struct in_addr *ipno, *mask;
+	int *acp;
+	char ***avp;
+{
+	int ac = *acp;
+	char **av = *avp;
+	char *p = 0, md = 0;
+
+	if (ac && !strncmp(*av,"any",strlen(*av))) {
+		ipno->s_addr = mask->s_addr = 0; av++; ac--;
+	} else {
+		p = strchr(*av, '/');
+		if (!p) 
+			p = strchr(*av, ':');
+		if (p) {
+			md = *p;
+			*p++ = '\0'; 
+		}
+
+		if (lookup_host(*av, ipno) != 0)
+			show_usage("hostname ``%s'' unknown", *av);
+		switch (md) {
+			case ':':
+				if (!inet_aton(p,mask))
+					show_usage("bad netmask ``%s''", p);
+				break;
+			case '/':
+				if (atoi(p) == 0) {
+					mask->s_addr = 0;
+				} else if (atoi(p) > 32) {
+					show_usage("bad width ``%s''", p);
+				} else {
+					mask->s_addr =
+					    htonl(~0 << (32 - atoi(p)));
+				}
+				break;
+			default:
+				mask->s_addr = htonl(~0);
+				break;
+		}
+		ipno->s_addr &= mask->s_addr;
+		av++;
+		ac--;
+	}
+	*acp = ac;
+	*avp = av;
+}
+
+static void
+fill_reject_code(u_short *codep, char *str)
+{
+	struct icmpcode *ic;
+	u_long val;
+	char *s;
+
+	val = strtoul(str, &s, 0);
+	if (s != str && *s == '\0' && val < 0x100) {
+		*codep = val;
+		return;
+	}
+	for (ic = icmpcodes; ic->str; ic++)
+		if (!strcasecmp(str, ic->str)) {
+			*codep = ic->code;
+			return;
+		}
+	show_usage("unknown ICMP unreachable code ``%s''", str);
+}
+
+static void
+add_port(cnt, ptr, off, port)
+	u_short *cnt, *ptr, off, port;
+{
+	if (off + *cnt >= IP_FW_MAX_PORTS)
+		errx(EX_USAGE, "too many ports (max is %d)", IP_FW_MAX_PORTS);
+	ptr[off+*cnt] = port;
+	(*cnt)++;
+}
+
+static int
+lookup_port(const char *arg, int test, int nodash)
+{
+	int		val;
+	char		*earg, buf[32];
+	struct servent	*s;
+
+	snprintf(buf, sizeof(buf), "%s", arg);
+	buf[strcspn(arg, nodash ? "-," : ",")] = 0;
+	val = (int) strtoul(buf, &earg, 0);
+	if (!*buf || *earg) {
+		setservent(1);
+		if ((s = getservbyname(buf, NULL))) {
+			val = htons(s->s_port);
+		} else {
+			if (!test) {
+				errx(EX_DATAERR, "unknown port ``%s''", arg);
+			}
+			val = -1;
+		}
+	} else {
+		if (val < 0 || val > 0xffff) {
+			if (!test) {
+				errx(EX_DATAERR, "port ``%s'' out of range", arg);
+			}
+			val = -1;
+		}
+	}
+	return(val);
+}
+
+static int
+fill_port(cnt, ptr, off, arg)
+	u_short *cnt, *ptr, off;
+	char *arg;
+{
+	char *s;
+	int initial_range = 0;
+
+	s = arg + strcspn(arg, "-,");	/* first port name can't have a dash */
+	if (*s == '-') {
+		*s++ = '\0';
+		if (strchr(arg, ','))
+			errx(EX_USAGE, "port range must be first in list");
+		add_port(cnt, ptr, off, *arg ? lookup_port(arg, 0, 0) : 0x0000);
+		arg = s;
+		s = strchr(arg,',');
+		if (s)
+			*s++ = '\0';
+		add_port(cnt, ptr, off, *arg ? lookup_port(arg, 0, 0) : 0xffff);
+		arg = s;
+		initial_range = 1;
+	}
+	while (arg != NULL) {
+		s = strchr(arg,',');
+		if (s)
+			*s++ = '\0';
+		add_port(cnt, ptr, off, lookup_port(arg, 0, 0));
+		arg = s;
+	}
+	return initial_range;
+}
+
+static void
+fill_tcpflag(set, reset, vp)
+	u_char *set, *reset;
+	char **vp;
+{
+	char *p = *vp,*q;
+	u_char *d;
+
+	while (p && *p) {
+		struct tpcflags {
+			char * name;
+			u_char value;
+		} flags[] = {
+			{ "syn", IP_FW_TCPF_SYN },
+			{ "fin", IP_FW_TCPF_FIN },
+			{ "ack", IP_FW_TCPF_ACK },
+			{ "psh", IP_FW_TCPF_PSH },
+			{ "rst", IP_FW_TCPF_RST },
+			{ "urg", IP_FW_TCPF_URG }
+		};
+		int i;
+
+		if (*p == '!') {
+			p++;
+			d = reset;
+		} else {
+			d = set;
+		}
+		q = strchr(p, ',');
+		if (q) 
+			*q++ = '\0';
+		for (i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i)
+			if (!strncmp(p, flags[i].name, strlen(p))) {
+				*d |= flags[i].value;
+				break;
+			}
+		if (i == sizeof(flags) / sizeof(flags[0]))
+			show_usage("invalid tcp flag ``%s''", p);
+		p = q;
+	}
+}
+
+static void
+fill_ipopt(u_char *set, u_char *reset, char **vp)
+{
+	char *p = *vp,*q;
+	u_char *d;
+
+	while (p && *p) {
+		if (*p == '!') {
+			p++;
+			d = reset;
+		} else {
+			d = set;
+		}
+		q = strchr(p, ',');
+		if (q) 
+			*q++ = '\0';
+		if (!strncmp(p,"ssrr",strlen(p))) *d |= IP_FW_IPOPT_SSRR;
+		if (!strncmp(p,"lsrr",strlen(p))) *d |= IP_FW_IPOPT_LSRR;
+		if (!strncmp(p,"rr",strlen(p)))   *d |= IP_FW_IPOPT_RR;
+		if (!strncmp(p,"ts",strlen(p)))   *d |= IP_FW_IPOPT_TS;
+		p = q;
+	}
+}
+
+static void
+fill_icmptypes(types, vp, fw_flg)
+	u_long *types;
+	char **vp;
+	u_int *fw_flg;
+{
+	char *c = *vp;
+
+	while (*c)
+	{
+		unsigned long icmptype;
+
+		if ( *c == ',' )
+			++c;
+
+		icmptype = strtoul(c, &c, 0);
+
+		if ( *c != ',' && *c != '\0' )
+			show_usage("invalid ICMP type");
+
+		if (icmptype >= IP_FW_ICMPTYPES_DIM * sizeof(unsigned) * 8)
+			show_usage("ICMP type out of range");
+
+		types[icmptype / (sizeof(unsigned) * 8)] |= 
+			1 << (icmptype % (sizeof(unsigned) * 8));
+		*fw_flg |= IP_FW_F_ICMPBIT;
+	}
+}
+
+static void
+delete(ac,av)
+	int ac;
+	char **av;
+{
+	struct ip_fw rule;
+	struct dn_pipe pipe;
+	int i;
+	int exitval = EX_OK;
+
+	memset(&rule, 0, sizeof rule);
+	memset(&pipe, 0, sizeof pipe);
+
+	av++; ac--;
+
+	/* Rule number */
+	while (ac && isdigit(**av)) {
+            if (do_pipe) {
+                pipe.pipe_nr = atoi(*av); av++; ac--;
+                i = setsockopt(s, IPPROTO_IP, IP_DUMMYNET_DEL,
+                    &pipe, sizeof pipe);
+                if (i) {
+                    exitval = 1;
+                    warn("rule %u: setsockopt(%s)", pipe.pipe_nr, "IP_DUMMYNET_DEL");
+                }
+            } else {
+		rule.fw_number = atoi(*av); av++; ac--;
+		i = setsockopt(s, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule);
+		if (i) {
+			exitval = EX_UNAVAILABLE;
+			warn("rule %u: setsockopt(%s)", rule.fw_number, "IP_FW_DEL");
+		}
+	}
+	}
+	if (exitval != EX_OK)
+		exit(exitval);
+}
+
+static void
+verify_interface(union ip_fw_if *ifu)
+{
+	struct ifreq ifr;
+
+	/*
+	 *	If a unit was specified, check for that exact interface.
+	 *	If a wildcard was specified, check for unit 0.
+	 */
+	snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", 
+			 ifu->fu_via_if.name,
+			 ifu->fu_via_if.unit == -1 ? 0 : ifu->fu_via_if.unit);
+
+	if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
+		warnx("warning: interface ``%s'' does not exist", ifr.ifr_name);
+}
+
+static void
+fill_iface(char *which, union ip_fw_if *ifu, int *byname, int ac, char *arg)
+{
+	if (!ac)
+	    show_usage("missing argument for ``%s''", which);
+
+	/* Parse the interface or address */
+	if (!strcmp(arg, "any")) {
+		ifu->fu_via_ip.s_addr = 0;
+		*byname = 0;
+	} else if (!isdigit(*arg)) {
+		char *q;
+
+		*byname = 1;
+		strncpy(ifu->fu_via_if.name, arg, sizeof(ifu->fu_via_if.name));
+		ifu->fu_via_if.name[sizeof(ifu->fu_via_if.name) - 1] = '\0';
+		for (q = ifu->fu_via_if.name;
+		    *q && !isdigit(*q) && *q != '*'; q++)
+			continue;
+		ifu->fu_via_if.unit = (*q == '*') ? -1 : atoi(q);
+		*q = '\0';
+		verify_interface(ifu);
+	} else if (!inet_aton(arg, &ifu->fu_via_ip)) {
+		show_usage("bad ip address ``%s''", arg);
+	} else
+		*byname = 0;
+}
+
+static void
+config_pipe(int ac, char **av)
+{
+       struct dn_pipe pipe;
+        int i ;
+        char *end ;
+ 
+        memset(&pipe, 0, sizeof pipe);
+ 
+        av++; ac--;
+        /* Pipe number */
+        if (ac && isdigit(**av)) {
+                pipe.pipe_nr = atoi(*av); av++; ac--;
+        }
+        while (ac > 1) {
+            if (!strncmp(*av,"bw",strlen(*av)) ||
+                ! strncmp(*av,"bandwidth",strlen(*av))) {
+                pipe.bandwidth = strtoul(av[1], &end, 0);
+                if (*end == 'K')
+                        end++, pipe.bandwidth *= 1000 ;
+                else if (*end == 'M')
+                        end++, pipe.bandwidth *= 1000000 ;
+                if (*end == 'B')
+                        pipe.bandwidth *= 8 ;
+                av+=2; ac-=2;
+            } else if (!strncmp(*av,"delay",strlen(*av)) ) {
+                pipe.delay = strtoul(av[1], NULL, 0);
+                av+=2; ac-=2;
+            } else if (!strncmp(*av,"plr",strlen(*av)) ) {
+                
+                double d = strtod(av[1], NULL);
+                pipe.plr = (int)(d*0x7fffffff) ;
+                av+=2; ac-=2;
+            } else if (!strncmp(*av,"queue",strlen(*av)) ) {
+                end = NULL ;
+                pipe.queue_size = strtoul(av[1], &end, 0);
+                if (*end == 'K') {
+                    pipe.queue_size_bytes = pipe.queue_size*1024 ;
+                    pipe.queue_size = 0 ;
+                } else if (*end == 'B') {
+                    pipe.queue_size_bytes = pipe.queue_size ;
+                    pipe.queue_size = 0 ;
+                }
+                av+=2; ac-=2;
+            } else
+                show_usage("unrecognised option ``%s''", *av);
+        }
+        if (pipe.pipe_nr == 0 )
+            show_usage("pipe_nr %d be > 0", pipe.pipe_nr);
+        if (pipe.queue_size > 100 )
+            show_usage("queue size %d must be 2 <= x <= 100", pipe.queue_size);
+        if (pipe.delay > 10000 )
+            show_usage("delay %d must be < 10000", pipe.delay);
+#if 0
+        printf("configuring pipe %d bw %d delay %d size %d\n",
+                pipe.pipe_nr, pipe.bandwidth, pipe.delay, pipe.queue_size);
+#endif
+        i = setsockopt(s,IPPROTO_IP, IP_DUMMYNET_CONFIGURE, &pipe,sizeof pipe);
+        if (i)
+                err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE");
+                
+}
+
+static void
+add(ac,av)
+	int ac;
+	char **av;
+{
+	struct ip_fw rule;
+	int i;
+	u_char proto;
+	struct protoent *pe;
+	int saw_xmrc = 0, saw_via = 0;
+	
+	memset(&rule, 0, sizeof rule);
+
+	av++; ac--;
+
+	/* Rule number */
+	if (ac && isdigit(**av)) {
+		rule.fw_number = atoi(*av); av++; ac--;
+	}
+
+	/* Action */
+	if (ac == 0)
+		show_usage("missing action");
+	if (!strncmp(*av,"accept",strlen(*av))
+		    || !strncmp(*av,"pass",strlen(*av))
+		    || !strncmp(*av,"allow",strlen(*av))
+		    || !strncmp(*av,"permit",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_ACCEPT; av++; ac--;
+	} else if (!strncmp(*av,"count",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_COUNT; av++; ac--;
+        } else if (!strncmp(*av,"pipe",strlen(*av))) {
+                rule.fw_flg |= IP_FW_F_PIPE; av++; ac--;
+                if (!ac)
+                        show_usage("missing pipe number");
+                rule.fw_divert_port = strtoul(*av, NULL, 0); av++; ac--;
+	} else if (!strncmp(*av,"divert",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_DIVERT; av++; ac--;
+		if (!ac)
+			show_usage("missing %s port", "divert");
+		rule.fw_divert_port = strtoul(*av, NULL, 0); av++; ac--;
+		if (rule.fw_divert_port == 0) {
+			struct servent *s;
+			setservent(1);
+			s = getservbyname(av[-1], "divert");
+			if (s != NULL)
+				rule.fw_divert_port = ntohs(s->s_port);
+			else
+				show_usage("illegal %s port", "divert");
+		}
+	} else if (!strncmp(*av,"tee",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_TEE; av++; ac--;
+		if (!ac)
+			show_usage("missing %s port", "tee divert");
+		rule.fw_divert_port = strtoul(*av, NULL, 0); av++; ac--;
+		if (rule.fw_divert_port == 0) {
+			struct servent *s;
+			setservent(1);
+			s = getservbyname(av[-1], "divert");
+			if (s != NULL)
+				rule.fw_divert_port = ntohs(s->s_port);
+			else
+				show_usage("illegal %s port", "tee divert");
+		}
+#ifndef IPFW_TEE_IS_FINALLY_IMPLEMENTED
+		err(EX_USAGE, "the ``tee'' action is not implemented");
+#endif
+	} else if (!strncmp(*av,"fwd",strlen(*av)) ||
+		   !strncmp(*av,"forward",strlen(*av))) {
+		struct in_addr dummyip;
+		char *pp;
+		rule.fw_flg |= IP_FW_F_FWD; av++; ac--;
+		if (!ac)
+			show_usage("missing forwarding IP address");
+		rule.fw_fwd_ip.sin_len = sizeof(struct sockaddr_in);
+		rule.fw_fwd_ip.sin_family = AF_INET;
+		rule.fw_fwd_ip.sin_port = 0;
+		pp = strchr(*av, ':');
+		if(pp == NULL)
+			pp = strchr(*av, ',');
+		if(pp != NULL)
+		{
+			*(pp++) = '\0';
+			rule.fw_fwd_ip.sin_port = lookup_port(pp, 1, 1);
+			if(rule.fw_fwd_ip.sin_port == (unsigned int)-1)
+				show_usage("illegal forwarding port");
+		}
+		fill_ip(&(rule.fw_fwd_ip.sin_addr), &dummyip, &ac, &av);
+		if (rule.fw_fwd_ip.sin_addr.s_addr == 0)
+			show_usage("illegal forwarding IP address");
+
+	} else if (!strncmp(*av,"skipto",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_SKIPTO; av++; ac--;
+		if (!ac)
+			show_usage("missing skipto rule number");
+		rule.fw_skipto_rule = strtoul(*av, NULL, 0); av++; ac--;
+	} else if ((!strncmp(*av,"deny",strlen(*av))
+		    || !strncmp(*av,"drop",strlen(*av)))) {
+		rule.fw_flg |= IP_FW_F_DENY; av++; ac--;
+	} else if (!strncmp(*av,"reject",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_REJECT; av++; ac--;
+		rule.fw_reject_code = ICMP_UNREACH_HOST;
+	} else if (!strncmp(*av,"reset",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_REJECT; av++; ac--;
+		rule.fw_reject_code = IP_FW_REJECT_RST;	/* check TCP later */
+	} else if (!strncmp(*av,"unreach",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_REJECT; av++; ac--;
+		fill_reject_code(&rule.fw_reject_code, *av); av++; ac--;
+	} else {
+		show_usage("invalid action ``%s''", *av);
+	}
+
+	/* [log] */
+	if (ac && !strncmp(*av,"log",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_PRN; av++; ac--;
+	}
+
+	/* protocol */
+	if (ac == 0)
+		show_usage("missing protocol");
+	if ((proto = atoi(*av)) > 0) {
+		rule.fw_prot = proto; av++; ac--;
+	} else if (!strncmp(*av,"all",strlen(*av))) {
+		rule.fw_prot = IPPROTO_IP; av++; ac--;
+	} else if ((pe = getprotobyname(*av)) != NULL) {
+		rule.fw_prot = pe->p_proto; av++; ac--;
+	} else {
+		show_usage("invalid protocol ``%s''", *av);
+	}
+
+	if (rule.fw_prot != IPPROTO_TCP
+	    && (rule.fw_flg & IP_FW_F_COMMAND) == IP_FW_F_REJECT
+	    && rule.fw_reject_code == IP_FW_REJECT_RST)
+		show_usage("``reset'' is only valid for tcp packets");
+
+	/* from */
+	if (ac && !strncmp(*av,"from",strlen(*av))) { av++; ac--; }
+	else
+		show_usage("missing ``from''");
+
+	if (ac && !strncmp(*av,"not",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_INVSRC;
+		av++; ac--;
+	}
+	if (!ac)
+		show_usage("missing arguments");
+
+	fill_ip(&rule.fw_src, &rule.fw_smsk, &ac, &av);
+
+	if (ac && (isdigit(**av) || lookup_port(*av, 1, 1) >= 0)) {
+		u_short nports = 0;
+
+		if (fill_port(&nports, rule.fw_uar.fw_pts, 0, *av))
+			rule.fw_flg |= IP_FW_F_SRNG;
+		IP_FW_SETNSRCP(&rule, nports);
+		av++; ac--;
+	}
+
+	/* to */
+	if (ac && !strncmp(*av,"to",strlen(*av))) { av++; ac--; }
+	else
+		show_usage("missing ``to''");
+
+	if (ac && !strncmp(*av,"not",strlen(*av))) {
+		rule.fw_flg |= IP_FW_F_INVDST;
+		av++; ac--;
+	}
+	if (!ac)
+		show_usage("missing arguments");
+
+	fill_ip(&rule.fw_dst, &rule.fw_dmsk, &ac, &av);
+
+	if (ac && (isdigit(**av) || lookup_port(*av, 1, 1) >= 0)) {
+		u_short	nports = 0;
+
+		if (fill_port(&nports,
+		    rule.fw_uar.fw_pts, IP_FW_GETNSRCP(&rule), *av))
+			rule.fw_flg |= IP_FW_F_DRNG;
+		IP_FW_SETNDSTP(&rule, nports);
+		av++; ac--;
+	}
+
+	if ((rule.fw_prot != IPPROTO_TCP) && (rule.fw_prot != IPPROTO_UDP)
+	    && (IP_FW_GETNSRCP(&rule) || IP_FW_GETNDSTP(&rule))) {
+		show_usage("only TCP and UDP protocols are valid"
+		    " with port specifications");
+	}
+
+	while (ac) {
+		if (!strncmp(*av,"in",strlen(*av))) { 
+			rule.fw_flg |= IP_FW_F_IN;
+			av++; ac--; continue;
+		}
+		if (!strncmp(*av,"out",strlen(*av))) { 
+			rule.fw_flg |= IP_FW_F_OUT;
+			av++; ac--; continue;
+		}
+		if (ac && !strncmp(*av,"xmit",strlen(*av))) {
+			union ip_fw_if ifu;
+			int byname;
+
+			if (saw_via) {
+badviacombo:
+				show_usage("``via'' is incompatible"
+				    " with ``xmit'' and ``recv''");
+			}
+			saw_xmrc = 1;
+			av++; ac--; 
+			fill_iface("xmit", &ifu, &byname, ac, *av);
+			rule.fw_out_if = ifu;
+			rule.fw_flg |= IP_FW_F_OIFACE;
+			if (byname)
+				rule.fw_flg |= IP_FW_F_OIFNAME;
+			av++; ac--; continue;
+		}
+		if (ac && !strncmp(*av,"recv",strlen(*av))) {
+			union ip_fw_if ifu;
+			int byname;
+
+			if (saw_via)
+				goto badviacombo;
+			saw_xmrc = 1;
+			av++; ac--; 
+			fill_iface("recv", &ifu, &byname, ac, *av);
+			rule.fw_in_if = ifu;
+			rule.fw_flg |= IP_FW_F_IIFACE;
+			if (byname)
+				rule.fw_flg |= IP_FW_F_IIFNAME;
+			av++; ac--; continue;
+		}
+		if (ac && !strncmp(*av,"via",strlen(*av))) {
+			union ip_fw_if ifu;
+			int byname = 0;
+
+			if (saw_xmrc)
+				goto badviacombo;
+			saw_via = 1;
+			av++; ac--; 
+			fill_iface("via", &ifu, &byname, ac, *av);
+			rule.fw_out_if = rule.fw_in_if = ifu;
+			if (byname)
+				rule.fw_flg |=
+				    (IP_FW_F_IIFNAME | IP_FW_F_OIFNAME);
+			av++; ac--; continue;
+		}
+		if (!strncmp(*av,"fragment",strlen(*av))) {
+			rule.fw_flg |= IP_FW_F_FRAG;
+			av++; ac--; continue;
+		}
+		if (!strncmp(*av,"ipoptions",strlen(*av))) { 
+			av++; ac--; 
+			if (!ac)
+				show_usage("missing argument"
+				    " for ``ipoptions''");
+			fill_ipopt(&rule.fw_ipopt, &rule.fw_ipnopt, av);
+			av++; ac--; continue;
+		}
+		if (rule.fw_prot == IPPROTO_TCP) {
+			if (!strncmp(*av,"established",strlen(*av))) { 
+				rule.fw_tcpf  |= IP_FW_TCPF_ESTAB;
+				av++; ac--; continue;
+			}
+			if (!strncmp(*av,"setup",strlen(*av))) { 
+				rule.fw_tcpf  |= IP_FW_TCPF_SYN;
+				rule.fw_tcpnf  |= IP_FW_TCPF_ACK;
+				av++; ac--; continue;
+			}
+			if (!strncmp(*av,"tcpflags",strlen(*av))) { 
+				av++; ac--; 
+				if (!ac)
+					show_usage("missing argument"
+					    " for ``tcpflags''");
+				fill_tcpflag(&rule.fw_tcpf, &rule.fw_tcpnf, av);
+				av++; ac--; continue;
+			}
+		}
+		if (rule.fw_prot == IPPROTO_ICMP) {
+			if (!strncmp(*av,"icmptypes",strlen(*av))) {
+				av++; ac--;
+				if (!ac)
+					show_usage("missing argument"
+					    " for ``icmptypes''");
+				fill_icmptypes(rule.fw_uar.fw_icmptypes,
+				    av, &rule.fw_flg);
+				av++; ac--; continue;
+			}
+		}
+		show_usage("unknown argument ``%s''", *av);
+	}
+
+	/* No direction specified -> do both directions */
+	if (!(rule.fw_flg & (IP_FW_F_OUT|IP_FW_F_IN)))
+		rule.fw_flg |= (IP_FW_F_OUT|IP_FW_F_IN);
+
+	/* Sanity check interface check, but handle "via" case separately */
+	if (saw_via) {
+		if (rule.fw_flg & IP_FW_F_IN)
+			rule.fw_flg |= IP_FW_F_IIFACE;
+		if (rule.fw_flg & IP_FW_F_OUT)
+			rule.fw_flg |= IP_FW_F_OIFACE;
+	} else if ((rule.fw_flg & IP_FW_F_OIFACE) && (rule.fw_flg & IP_FW_F_IN))
+		show_usage("can't check xmit interface of incoming packets");
+
+	/* frag may not be used in conjunction with ports or TCP flags */
+	if (rule.fw_flg & IP_FW_F_FRAG) {
+		if (rule.fw_tcpf || rule.fw_tcpnf)
+			show_usage("can't mix 'frag' and tcpflags");
+
+		if (rule.fw_nports)
+			show_usage("can't mix 'frag' and port specifications");
+	}
+
+	if (!do_quiet)
+		show_ipfw(&rule, 10, 10);
+	i = setsockopt(s, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
+	if (i)
+		err(EX_UNAVAILABLE, "setsockopt(%s)", "IP_FW_ADD");
+}
+
+static void
+zero (ac, av)
+	int ac;
+	char **av;
+{
+	av++; ac--;
+
+	if (!ac) {
+		/* clear all entries */
+		if (setsockopt(s,IPPROTO_IP,IP_FW_ZERO,NULL,0)<0)
+			err(EX_UNAVAILABLE, "setsockopt(%s)", "IP_FW_ZERO");
+		if (!do_quiet)
+			printf("Accounting cleared.\n");
+	} else {
+		struct ip_fw rule;
+		int failed = EX_OK;
+
+		memset(&rule, 0, sizeof rule);
+		while (ac) {
+			/* Rule number */
+			if (isdigit(**av)) {
+				rule.fw_number = atoi(*av); av++; ac--;
+				if (setsockopt(s, IPPROTO_IP,
+				    IP_FW_ZERO, &rule, sizeof rule)) {
+					warn("rule %u: setsockopt(%s)", rule.fw_number,
+						 "IP_FW_ZERO");
+					failed = EX_UNAVAILABLE;
+				}
+				else if (!do_quiet)
+					printf("Entry %d cleared\n",
+					    rule.fw_number);
+			} else
+				show_usage("invalid rule number ``%s''", *av);
+		}
+		if (failed != EX_OK)
+			exit(failed);
+	}
+}
+
+static int
+ipfw_main(ac,av)
+	int 	ac;
+	char 	**av;
+{
+
+	int 		ch;
+	extern int 	optreset; /* XXX should be declared in <unistd.h> */
+
+	if ( ac == 1 ) {
+		show_usage(NULL);
+	}
+
+	/* Set the force flag for non-interactive processes */
+	do_force = !isatty(STDIN_FILENO);
+
+	optind = optreset = 1;
+	while ((ch = getopt(ac, av, "afqtN")) != -1)
+	switch(ch) {
+		case 'a':
+			do_acct=1;
+			break;
+		case 'f':
+			do_force=1;
+			break;
+		case 'q':
+			do_quiet=1;
+			break;
+		case 't':
+			do_time=1;
+			break;
+		case 'N':
+	 		do_resolv=1;
+			break;
+		default:
+			show_usage(NULL);
+	}
+
+	ac -= optind;
+	if (*(av+=optind)==NULL) {
+		 show_usage("Bad arguments");
+	}
+
+        if (!strncmp(*av, "pipe", strlen(*av))) {
+                do_pipe = 1 ;
+                ac-- ;
+                av++ ;
+        }
+	if (!ac) {
+		show_usage("pipe requires arguments");
+	}
+        /* allow argument swapping */
+        if (ac > 1 && *av[0]>='0' && *av[0]<='9') {
+                char *p = av[0] ;
+                av[0] = av[1] ;
+                av[1] = p ;
+        }
+	if (!strncmp(*av, "add", strlen(*av))) {
+		add(ac,av);
+        } else if (do_pipe && !strncmp(*av, "config", strlen(*av))) {
+                config_pipe(ac,av);
+	} else if (!strncmp(*av, "delete", strlen(*av))) {
+		delete(ac,av);
+	} else if (!strncmp(*av, "flush", strlen(*av))) {
+		int do_flush = 0;
+
+		if ( do_force || do_quiet )
+			do_flush = 1;
+		else {
+			int c;
+
+			/* Ask the user */
+			printf("Are you sure? [yn] ");
+			do {
+				fflush(stdout);
+				c = toupper(getc(stdin));
+				while (c != '\n' && getc(stdin) != '\n')
+					if (feof(stdin))
+						return (0);
+			} while (c != 'Y' && c != 'N');
+			printf("\n");
+			if (c == 'Y') 
+				do_flush = 1;
+		}
+		if ( do_flush ) {
+			if (setsockopt(s,IPPROTO_IP,IP_FW_FLUSH,NULL,0) < 0)
+				err(EX_UNAVAILABLE, "setsockopt(%s)", "IP_FW_FLUSH");
+			if (!do_quiet)
+				printf("Flushed all rules.\n");
+		}
+	} else if (!strncmp(*av, "zero", strlen(*av))) {
+		zero(ac,av);
+	} else if (!strncmp(*av, "print", strlen(*av))) {
+		list(--ac,++av);
+	} else if (!strncmp(*av, "list", strlen(*av))) {
+		list(--ac,++av);
+	} else if (!strncmp(*av, "show", strlen(*av))) {
+		do_acct++;
+		list(--ac,++av);
+	} else {
+		show_usage("Bad arguments");
+	}
+	return 0;
+}
+
+int 
+main(ac, av)
+	int	ac;
+	char	**av;
+{
+#define MAX_ARGS	32
+#define WHITESP		" \t\f\v\n\r"
+	char	buf[BUFSIZ];
+	char	*a, *p, *args[MAX_ARGS], *cmd = NULL;
+	char	linename[10];
+	int 	i, c, qflag, pflag, status;
+	FILE	*f = NULL;
+	pid_t	preproc = 0;
+
+	s = socket( AF_INET, SOCK_RAW, IPPROTO_RAW );
+	if ( s < 0 )
+		err(EX_UNAVAILABLE, "socket");
+
+	setbuf(stdout,0);
+
+	if (ac > 1 && access(av[ac - 1], R_OK) == 0) {
+		qflag = pflag = i = 0;
+		lineno = 0;
+
+		while ((c = getopt(ac, av, "D:U:p:q")) != -1)
+			switch(c) {
+			case 'D':
+				if (!pflag)
+					errx(EX_USAGE, "-D requires -p");
+				if (i > MAX_ARGS - 2)
+					errx(EX_USAGE,
+					     "too many -D or -U options");
+				args[i++] = "-D";
+				args[i++] = optarg;
+				break;
+
+			case 'U':
+				if (!pflag)
+					errx(EX_USAGE, "-U requires -p");
+				if (i > MAX_ARGS - 2)
+					errx(EX_USAGE,
+					     "too many -D or -U options");
+				args[i++] = "-U";
+				args[i++] = optarg;
+				break;
+
+			case 'p':
+				pflag = 1;
+				cmd = optarg;
+				args[0] = cmd;
+				i = 1;
+				break;
+
+			case 'q':
+				qflag = 1;
+				break;
+
+			default:
+				show_usage(NULL);
+			}
+
+		av += optind;
+		ac -= optind;
+		if (ac != 1)
+			show_usage("extraneous filename arguments");
+
+		if ((f = fopen(av[0], "r")) == NULL)
+			err(EX_UNAVAILABLE, "fopen: %s", av[0]);
+
+		if (pflag) {
+			/* pipe through preprocessor (cpp or m4) */
+			int pipedes[2];
+
+			args[i] = 0;
+
+			if (pipe(pipedes) == -1)
+				err(EX_OSERR, "cannot create pipe");
+
+			switch((preproc = fork())) {
+			case -1:
+				err(EX_OSERR, "cannot fork");
+
+			case 0:
+				/* child */
+				if (dup2(fileno(f), 0) == -1 ||
+				    dup2(pipedes[1], 1) == -1)
+					err(EX_OSERR, "dup2()");
+				fclose(f);
+				close(pipedes[1]);
+				close(pipedes[0]);
+				execvp(cmd, args);
+				err(EX_OSERR, "execvp(%s) failed", cmd);
+
+			default:
+				/* parent */
+				fclose(f);
+				close(pipedes[1]);
+				if ((f = fdopen(pipedes[0], "r")) == NULL) {
+					int savederrno = errno;
+
+					(void)kill(preproc, SIGTERM);
+					errno = savederrno;
+					err(EX_OSERR, "fdopen()");
+				}
+			}
+		}
+
+		while (fgets(buf, BUFSIZ, f)) {
+			lineno++;
+			sprintf(linename, "Line %d", lineno);
+			args[0] = linename;
+
+			if (*buf == '#')
+				continue;
+			if ((p = strchr(buf, '#')) != NULL)
+				*p = '\0';
+			i=1;
+			if (qflag) args[i++]="-q";
+			for (a = strtok(buf, WHITESP);
+			    a && i < MAX_ARGS; a = strtok(NULL, WHITESP), i++)
+				args[i] = a;
+			if (i == (qflag? 2: 1))
+				continue;
+			if (i == MAX_ARGS)
+				errx(EX_USAGE, "%s: too many arguments", linename);
+			args[i] = NULL;
+
+			ipfw_main(i, args); 
+		}
+		fclose(f);
+		if (pflag) {
+			if (waitpid(preproc, &status, 0) != -1) {
+				if (WIFEXITED(status)) {
+					if (WEXITSTATUS(status) != EX_OK)
+						errx(EX_UNAVAILABLE,
+						     "preprocessor exited with status %d",
+						     WEXITSTATUS(status));
+				} else if (WIFSIGNALED(status)) {
+					errx(EX_UNAVAILABLE,
+					     "preprocessor exited with signal %d",
+					     WTERMSIG(status));
+				}
+			}
+		}
+
+	} else
+		ipfw_main(ac,av);
+	return EX_OK;
+}
diff --git a/logger.tproj/Makefile b/logger.tproj/Makefile
new file mode 100644
index 0000000..c186192
--- /dev/null
+++ b/logger.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = logger
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = logger.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
+            h.template logger.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/logger.tproj/Makefile.postamble b/logger.tproj/Makefile.postamble
new file mode 100644
index 0000000..7823726
--- /dev/null
+++ b/logger.tproj/Makefile.postamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
diff --git a/logger.tproj/Makefile.preamble b/logger.tproj/Makefile.preamble
new file mode 100644
index 0000000..74ce95a
--- /dev/null
+++ b/logger.tproj/Makefile.preamble
@@ -0,0 +1,130 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES =
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
diff --git a/logger.tproj/PB.project b/logger.tproj/PB.project
new file mode 100644
index 0000000..796d25c
--- /dev/null
+++ b/logger.tproj/PB.project
@@ -0,0 +1,34 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_LINKED = (logger.c); 
+        OTHER_SOURCES = (
+            Makefile.preamble, 
+            Makefile, 
+            Makefile.postamble, 
+            m.template, 
+            h.template, 
+            logger.1
+        ); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = logger; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/logger.tproj/h.template b/logger.tproj/h.template
new file mode 100644
index 0000000..f3c1b04
--- /dev/null
+++ b/logger.tproj/h.template
@@ -0,0 +1,11 @@
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+#import <Foundation/Foundation.h>
+
+@interface $FILENAMESANSEXTENSION$ : NSObject
+{
+
+}
+
+@end
diff --git a/logger.tproj/logger.1 b/logger.tproj/logger.1
new file mode 100644
index 0000000..3a942e8
--- /dev/null
+++ b/logger.tproj/logger.1
@@ -0,0 +1,102 @@
+.\"	$OpenBSD: logger.1,v 1.2 1996/06/26 05:35:58 deraadt Exp $
+.\"	$NetBSD: logger.1,v 1.4 1994/12/22 06:26:59 jtc Exp $
+.\"
+.\" Copyright (c) 1983, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)logger.1	8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt LOGGER 1
+.Os BSD 4.3
+.Sh NAME
+.Nm logger
+.Nd make entries in the system log
+.Sh SYNOPSIS
+.Nm logger
+.Op Fl is
+.Op Fl f Ar file
+.Op Fl p Ar pri
+.Op Fl t Ar tag
+.Op Ar message ...
+.Sh DESCRIPTION
+.Nm Logger
+provides a shell command interface to the
+.Xr syslog  3
+system log module.
+.Pp
+Options:
+.Pp
+.Bl -tag -width "message"
+.It Fl i
+Log the process id of the logger process
+with each line.
+.It Fl s
+Log the message to standard error, as well as the system log.
+.It Fl f Ar file 
+Log the specified file.
+.It Fl p Ar pri 
+Enter the message with the specified priority.
+The priority may be specified numerically or as a ``facility.level''
+pair.
+For example, ``\-p local3.info'' logs the message(s) as
+.Ar info Ns rmational
+level in the
+.Ar local3
+facility.
+The default is ``user.notice.''
+.It Fl t Ar tag 
+Mark every line in the log with the specified
+.Ar tag  .
+.It Ar message
+Write the message to log; if not specified, and the
+.Fl f
+flag is not
+provided, standard input is logged.
+.El
+.Pp
+The
+.Nm logger
+utility exits 0 on success, and >0 if an error occurs.
+.Sh EXAMPLES
+.Bd -literal -offset indent -compact
+logger System rebooted
+
+logger \-p local0.notice \-t HOSTIDM \-f /dev/idmc
+.Ed
+.Sh SEE ALSO
+.Xr syslog 3 ,
+.Xr syslogd 8
+.Sh STANDARDS
+The
+.Nm logger
+utility conforms to
+.St -p1003.2-92 .
diff --git a/logger.tproj/logger.c b/logger.tproj/logger.c
new file mode 100644
index 0000000..0ec8b27
--- /dev/null
+++ b/logger.tproj/logger.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#define	SYSLOG_NAMES
+#include <syslog.h>
+
+int	decode __P((char *, CODE *));
+int	pencode __P((char *));
+void	usage __P((void));
+
+/*
+ * logger -- read and log utility
+ *
+ *	Reads from an input and arranges to write the result on the system
+ *	log.
+ */
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int ch, logflags, pri;
+	char *tag, buf[1024];
+
+	tag = NULL;
+	pri = LOG_NOTICE;
+	logflags = 0;
+	while ((ch = getopt(argc, argv, "f:ip:st:")) != -1)
+		switch((char)ch) {
+		case 'f':		/* file to log */
+			if (freopen(optarg, "r", stdin) == NULL) {
+				(void)fprintf(stderr, "logger: %s: %s.\n",
+				    optarg, strerror(errno));
+				exit(1);
+			}
+			break;
+		case 'i':		/* log process id also */
+			logflags |= LOG_PID;
+			break;
+		case 'p':		/* priority */
+			pri = pencode(optarg);
+			break;
+		case 's':		/* log to standard error */
+			logflags |= LOG_PERROR;
+			break;
+		case 't':		/* tag */
+			tag = optarg;
+			break;
+		case '?':
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	/* setup for logging */
+	openlog(tag ? tag : getlogin(), logflags, 0);
+	(void) fclose(stdout);
+
+	/* log input line if appropriate */
+	if (argc > 0) {
+		register char *p, *endp;
+		int len;
+
+		for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {
+			len = strlen(*argv);
+			if (p + len > endp && p > buf) {
+				syslog(pri, "%s", buf);
+				p = buf;
+			}
+			if (len > sizeof(buf) - 1)
+				syslog(pri, "%s", *argv++);
+			else {
+				if (p != buf)
+					*p++ = ' ';
+				bcopy(*argv++, p, len);
+				*(p += len) = '\0';
+			}
+		}
+		if (p != buf)
+			syslog(pri, "%s", buf);
+	} else
+		while (fgets(buf, sizeof(buf), stdin) != NULL)
+			syslog(pri, "%s", buf);
+	exit(0);
+}
+
+/*
+ *  Decode a symbolic name to a numeric value
+ */
+int
+pencode(s)
+	register char *s;
+{
+	char *save;
+	int fac, lev;
+
+	for (save = s; *s && *s != '.'; ++s);
+	if (*s) {
+		*s = '\0';
+		fac = decode(save, facilitynames);
+		if (fac < 0) {
+			(void)fprintf(stderr,
+			    "logger: unknown facility name: %s.\n", save);
+			exit(1);
+		}
+		*s++ = '.';
+	}
+	else {
+		fac = 0;
+		s = save;
+	}
+	lev = decode(s, prioritynames);
+	if (lev < 0) {
+		(void)fprintf(stderr,
+		    "logger: unknown priority name: %s.\n", save);
+		exit(1);
+	}
+	return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK));
+}
+
+int
+decode(name, codetab)
+	char *name;
+	CODE *codetab;
+{
+	register CODE *c;
+
+	if (isdigit(*name))
+		return (atoi(name));
+
+	for (c = codetab; c->c_name; c++)
+		if (!strcasecmp(name, c->c_name))
+			return (c->c_val);
+
+	return (-1);
+}
+
+void
+usage()
+{
+	(void)fprintf(stderr,
+	    "logger: [-is] [-f file] [-p pri] [-t tag] [ message ... ]\n");
+	exit(1);
+}
diff --git a/logger.tproj/m.template b/logger.tproj/m.template
new file mode 100644
index 0000000..1216fe5
--- /dev/null
+++ b/logger.tproj/m.template
@@ -0,0 +1,18 @@
+$$ Lines starting with $$ are not inserted into newly created files
+$$ The following substitutions are made:
+$$
+$$ $FILENAME$                e.g. foo.m
+$$ $FILENAMESANSEXTENSION$   e.g. foo
+$$ $DIRECTORY$               e.g. /tmp/MyNewApp
+$$ $PROJECTNAME$             e.g. MyNewApp
+$$ $SUBPROJECTNAME$          e.g. TheGoodPart.subproj
+$$ $USERNAME$                e.g. mwagner
+$$ $DATE$                    e.g. Jan-1-1994
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+#import "$FILENAMESANSEXTENSION$.h"
+
+@implementation $FILENAMESANSEXTENSION$
+
+@end
diff --git a/makedbm.tproj/Makefile b/makedbm.tproj/Makefile
new file mode 100644
index 0000000..143e661
--- /dev/null
+++ b/makedbm.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = makedbm
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = db.h ypdb.h ypdef.h
+
+CFILES = db.c makedbm.c ypdb.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble makedbm.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/makedbm.tproj/Makefile.postamble b/makedbm.tproj/Makefile.postamble
new file mode 100644
index 0000000..509e7f5
--- /dev/null
+++ b/makedbm.tproj/Makefile.postamble
@@ -0,0 +1,101 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGE: langage in which the project is written (default "English")
+#  LOCAL_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/makedbm.tproj/Makefile.preamble b/makedbm.tproj/Makefile.preamble
new file mode 100644
index 0000000..83f25c7
--- /dev/null
+++ b/makedbm.tproj/Makefile.preamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. <<default?>>
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSION: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
diff --git a/makedbm.tproj/PB.project b/makedbm.tproj/PB.project
new file mode 100644
index 0000000..1c1cc6f
--- /dev/null
+++ b/makedbm.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (db.h, ypdb.h, ypdef.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (db.c, makedbm.c, ypdb.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, makedbm.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = makedbm; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/makedbm.tproj/db.c b/makedbm.tproj/db.c
new file mode 100644
index 0000000..9d5396d
--- /dev/null
+++ b/makedbm.tproj/db.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: db.c,v 1.1 1997/07/22 10:52:59 maja Exp $ */
+
+/*
+ * Copyright (c) 1997 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: db.c,v 1.1 1997/07/22 10:52:59 maja Exp $";
+#endif
+
+#include <sys/types.h>
+#include <bsd/db.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include "db.h"
+#include "ypdb.h"
+
+/*
+ * This module was created to be able to read database files created
+ * by sendmail -bi.
+ */
+
+int db_hash_list_database(database)
+char *database;
+{
+	DB *db;
+	int  status;
+	DBT key, val;
+	char path[MAXPATHLEN];
+
+	snprintf(path, sizeof(path), "%s%s", database, ".db");
+
+	db = dbopen(path, O_RDONLY, 0, DB_HASH, NULL);
+	if (db != NULL) {
+		status = db->seq(db, &key, &val, R_FIRST);
+		while (status == 0) {
+			printf("%*.*s %*.*s\n",
+			       key.size-1, key.size-1, key.data,
+			       val.size-1, val.size-1, val.data);
+			status = db->seq(db, &key, &val, R_NEXT);
+		}
+		db->close(db);
+		return(1);
+	}
+	return(0);
+}
+
diff --git a/makedbm.tproj/db.h b/makedbm.tproj/db.h
new file mode 100644
index 0000000..bbcf1a1
--- /dev/null
+++ b/makedbm.tproj/db.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: db.h,v 1.1 1997/07/22 10:52:59 maja Exp $ */
+
+/*
+ * Copyright (c) 1997 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _MAKEDBM_DB_H_
+#define _MAKEDBM_DB_H_
+
+__BEGIN_DECLS
+int		db_hash_list_database __P((char *));
+__END_DECLS
+
+#endif /* !_MAKEDBM_DB_H_ */
+
+
diff --git a/makedbm.tproj/makedbm.8 b/makedbm.tproj/makedbm.8
new file mode 100644
index 0000000..151d29f
--- /dev/null
+++ b/makedbm.tproj/makedbm.8
@@ -0,0 +1,97 @@
+.\"	$OpenBSD: makedbm.8,v 1.5 1997/07/22 10:53:00 maja Exp $
+.\" Copyright (c) 1994-97 Mats O Jansson <moj@stacken.kth.se>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by Mats O Jansson
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd July 19, 1994
+.Dt MAKEDBM 8
+.Os
+.Sh NAME
+.Nm makedbm
+.Nd create a YP database
+.Sh SYNOPSIS
+.Nm makedbm
+.Fl u Ar file
+.Nm makedbm
+.Fl U Ar file
+.Nm makedbm
+.Op Fl bls
+.Op Fl i Ar yp_input_file
+.Op Fl o Ar yp_output_file
+.Op Fl d Ar yp_domain_name
+.Op Fl m Ar yp_master_name
+.Ar infile
+.Ar outfile
+.Sh DESCRIPTION
+.Nm Makedbm
+is the utiliy in YP that creates the database file containing the YP map.
+The databse format is a slightly modified version of ndbm.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl u
+Dump a database to standard output.
+.It Fl U
+Same as
+.Fl u
+but also try 
+.Xr db 3
+hash format.
+.It Fl b
+Interdomain. Include an entry in the database informing a YP server to use
+DNS to get information about unknown hosts. This option will only have
+effect on the two maps hosts.byname and hosts.byaddr.
+.It Fl l
+Lowercase. Convert all keys to lower case before adding them to the YP
+database.
+.It Fl s 
+Secure map. Include an entry in the database informing 
+.Xr ypxfr 8
+and
+.Xr ypserv 8
+that the YP map is going to be handled as secure.
+.It Fl i Ar yp_input_file
+Include an entry the in the map with the key YP_INPUT_FILE and the argument
+as value.
+.It Fl o Ar yp_output_file
+Include an entry the in the map with the key YP_OUTPUT_FILE and the argument
+as value.
+.It Fl d Ar yp_domain_name
+Include an entry the in the map with the key YP_DOMAIN_NAME and the argument
+as value.
+.It Fl m Ar yp_master_name
+Include an entry the in the map with the key YP_MASTER_NAME and the argument
+as value.
+.El
+.Sh SEE ALSO
+.Xr yp 8 ,
+.Xr db 3 ,
+.Xr ypxfr 8 ,
+.Xr ypserv 8 
+.Sh AUTHOR
+Mats O Jansson <moj@stacken.kth.se>
diff --git a/makedbm.tproj/makedbm.c b/makedbm.tproj/makedbm.c
new file mode 100644
index 0000000..8d2f73e
--- /dev/null
+++ b/makedbm.tproj/makedbm.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: makedbm.c,v 1.9 1997/08/18 03:11:34 millert Exp $ */
+
+/*
+ * Copyright (c) 1994-97 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: makedbm.c,v 1.9 1997/08/18 03:11:34 millert Exp $";
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/errno.h>
+#include "ypdb.h"
+#include "ypdef.h"
+#include "db.h"
+
+extern char *__progname;		/* from crt0.o */
+
+/*
+ * Read one line
+ */
+
+static int read_line(fp, buf, size)
+	FILE	*fp;
+	char	*buf;
+	int	size;
+{
+	int	done;
+
+	done = 0;
+
+	do {
+		while (fgets(buf, size, fp)) {
+			int len = strlen(buf);
+			done += len;
+			if (len > 1 && buf[len-2] == '\\' &&
+					buf[len-1] == '\n') {
+				int ch;
+				buf += len - 2;
+				size -= len - 2;
+				*buf = '\n'; buf[1] = '\0';
+				
+				/* Skip leading white space on next line */
+				while ((ch = getc(fp)) != EOF &&
+					isascii(ch) && isspace(ch))
+						;
+				(void) ungetc(ch, fp);
+			} else {
+				return done;
+			}
+		}
+	} while (size > 0 && !feof(fp));
+
+	return done;
+}
+
+void 
+add_record(db, str1, str2, check)
+	DBM	*db;
+	char	*str1, *str2;
+	int     check;
+{
+        datum   key,val;
+        int     status;
+
+	key.dptr = str1;
+	key.dsize = strlen(str1);
+	
+	if (check) {
+	        val = ypdb_fetch(db,key);
+
+		if (val.dptr != NULL)
+			return;		/* already there */
+		
+	}
+
+        val.dptr  = str2;
+	val.dsize = strlen(str2);
+	status = ypdb_store(db, key, val, YPDB_INSERT);
+	
+	if (status != 0) {
+		printf("%s: problem storing %s %s\n",__progname,str1,str2);
+		exit(1);
+	}
+}
+
+static char *
+file_date(filename)
+	char	*filename;
+{
+	struct	stat finfo;
+	static	char datestr[11];
+	int	status;
+	
+	if (strcmp(filename,"-") == 0) {
+		sprintf(datestr, "%010d", time(0));
+	} else {
+		status = stat(filename, &finfo);
+		if (status < 0) {
+			fprintf(stderr, "%s: can't stat %s\n", __progname, filename);
+			exit(1);
+		}	
+		sprintf(datestr, "%010d", finfo.st_mtime);
+	}
+  	
+	return datestr;
+}
+
+void
+list_database(database,Uflag)
+	char	*database;
+	int	Uflag;
+{
+	DBM	*db;
+	datum	key,val;
+  	
+	db = ypdb_open(database, O_RDONLY, 0444);
+	
+	if (db == NULL) {
+
+		if (Uflag != 0) {
+			
+			if (db_hash_list_database(database)) return;
+			
+		}
+
+
+		fprintf(stderr, "%s: can't open database %s\n", __progname, database);
+		exit(1);
+	}
+	
+	key = ypdb_firstkey(db);
+	
+	while (key.dptr != NULL) {
+	        val = ypdb_fetch(db,key);
+		printf("%*.*s %*.*s\n",
+		       key.dsize, key.dsize, key.dptr,
+		       val.dsize, val.dsize, val.dptr);
+		key = ypdb_nextkey(db);
+	}
+	  
+	ypdb_close(db);
+	
+}
+
+void
+
+create_database(infile,database,
+		yp_input_file,yp_output_file,
+		yp_master_name,yp_domain_name,
+		bflag, lflag, sflag)
+	char	*infile, *database;
+	char	*yp_input_file, *yp_output_file;
+	char	*yp_master_name, *yp_domain_name;
+	int	bflag, lflag, sflag;        
+{
+	FILE	*data_file;
+	char	data_line[4096]; /* XXX: DB bsize = 4096 in ypdb.c */
+	char	myname[MAXHOSTNAMELEN];
+	int	line_no = 0;
+	int	len;
+	char	*p,*k,*v;
+	char	*slash;
+	DBM	*new_db;
+	static	char mapname[] = "ypdbXXXXXXXXXX";
+	char	db_mapname[MAXPATHLEN],db_outfile[MAXPATHLEN],
+		db_tempname[MAXPATHLEN];
+	char	empty_str[] = "";
+	
+	if (strcmp(infile,"-") == 0) {
+		data_file = stdin;
+	} else {
+		data_file = fopen(infile, "r");
+		if (errno != 0) {
+			(void)fprintf(stderr,"%s: ",__progname);
+			perror(infile);
+			exit(1);
+		}
+	}
+	
+	if (strlen(database) + strlen(YPDB_SUFFIX) > MAXPATHLEN) {
+		fprintf(stderr,"%s: %s: file name too long\n",
+			__progname, database);
+		exit(1);
+	}
+	snprintf(db_outfile, sizeof(db_outfile), "%s%s", database, YPDB_SUFFIX);
+
+	slash = strrchr(database, '/');
+	if (slash != NULL) 
+		slash[1] = 0; 			/* truncate to dir */
+	else
+		*database = 0;			/* elminate */
+
+	/* note: database is now directory where map goes ! */
+
+	if (strlen(database) + strlen(mapname) 
+			+ strlen(YPDB_SUFFIX) > MAXPATHLEN) {
+		fprintf(stderr,"%s: %s: directory name too long\n",
+			__progname, database);
+		exit(1);
+	}
+
+	snprintf(db_tempname, sizeof(db_tempname), "%s%s", database,
+		mapname);
+	mktemp(db_tempname);
+	snprintf(db_mapname, sizeof(db_mapname), "%s%s", db_tempname,
+		YPDB_SUFFIX);
+
+	new_db = ypdb_open(db_tempname, O_RDWR|O_CREAT, 0444);
+	
+	while (read_line(data_file,data_line,sizeof(data_line))) {
+		
+		line_no++;
+		len =  strlen(data_line);
+		
+		/* Check if we have the whole line */ 
+		
+		if (data_line[len-1] != '\n') {
+			fprintf(stderr, "line %d in \"%s\" is too long",
+				line_no, infile);
+		} else {
+			data_line[len-1] = '\0';
+		}
+		
+		p = (char *) &data_line;
+		
+		k  = p;				     /* save start of key */
+		while (!isspace(*p)) {		    /* find first "space" */
+			if (lflag && isupper(*p))   /* if force lower case */
+				*p = tolower(*p);   /* fix it */
+			p++;
+		};
+		while (isspace(*p)) {		/* replace space with <NUL> */
+			*p = '\0';
+			p++;
+		};
+		
+		v = p;				/* save start of value */
+		while(*p != '\0') { p++; };	/* find end of string */
+		
+		add_record(new_db, k, v, TRUE);	/* save record */
+		
+	}
+	
+	if (strcmp(infile,"-") != 0) {
+		(void) fclose(data_file);
+	}
+	
+	add_record(new_db, YP_LAST_KEY, file_date(infile), FALSE);
+	
+	if (yp_input_file) {
+		add_record(new_db, YP_INPUT_KEY, yp_input_file, FALSE);
+	}
+	
+	if (yp_output_file) {
+		add_record(new_db, YP_OUTPUT_KEY, yp_output_file, FALSE);
+	}
+	
+	if (yp_master_name) {
+		add_record(new_db, YP_MASTER_KEY, yp_master_name, FALSE);
+	} else {
+		gethostname(myname, sizeof(myname) - 1);
+		add_record(new_db, YP_MASTER_KEY, myname, FALSE);
+	}
+	
+	if (yp_domain_name) {
+		add_record(new_db, YP_DOMAIN_KEY, yp_domain_name, FALSE);
+	}
+	
+	if (bflag) {
+		add_record(new_db, YP_INTERDOMAIN_KEY, empty_str, FALSE);
+	}
+
+	if (sflag) {
+		add_record(new_db, YP_SECURE_KEY, empty_str, FALSE);
+	}
+
+	ypdb_close(new_db);
+	if (rename(db_mapname,db_outfile) < 0) {
+		perror("rename");
+		fprintf(stderr,"rename %s -> %s failed!\n", db_mapname,
+			db_outfile);
+		exit(1);
+	}
+	
+}
+
+int
+main (argc,argv)
+	int	argc;
+	char	*argv[];
+{
+	int	aflag, uflag, bflag, lflag, sflag, Uflag;
+	char	*yp_input_file, *yp_output_file;
+	char	*yp_master_name,*yp_domain_name;
+	char	*infile,*outfile;
+	int	usage = 0;
+	int	ch;
+	
+	extern int optind;
+	
+	yp_input_file = yp_output_file = NULL;
+	yp_master_name = yp_domain_name = NULL;
+	aflag = uflag = bflag = lflag = sflag = Uflag = 0;
+	infile = outfile = NULL;
+	
+	while ((ch = getopt(argc, argv, "Ublsui:o:m:d:")) != -1)
+		switch (ch) {
+			case 'U': 
+				uflag++;
+				Uflag++;
+				break;
+			case 'b':
+		  		bflag++;
+				aflag++;
+				break;
+			case 'l':
+				lflag++;
+				aflag++;
+				break;
+			case 's':
+				sflag++;
+				aflag++;
+				break;
+			case 'i':
+				yp_input_file = argv[optind];
+				aflag++;
+				break;
+			case 'o':
+				yp_output_file = argv[optind];
+				aflag++;
+				break;
+			case 'm':
+				yp_master_name = argv[optind];
+				aflag++;
+				break;
+			case 'd':
+				yp_domain_name = argv[optind];
+				aflag++;
+				break;
+			case 'u':
+				uflag++;
+				break;
+			default:
+				usage++;
+				break;
+		}
+	
+	if ((uflag != 0) && (aflag != 0)) {
+		usage++;
+	} else {
+		
+		if (uflag != 0) {
+			if (argc == (optind + 1)) {
+				infile = argv[optind];
+			} else {
+				usage++;
+			}
+		} else {
+			if (argc == (optind + 2)) {
+				infile = argv[optind];
+				outfile = argv[optind+1];
+			} else {
+				usage++;
+			}
+		}
+	}
+	
+	if (usage) {
+		fprintf(stderr,"%s%s%s",
+			"usage:\tmakedbm [-u|-U] file\n\tmakedbm [-bls]",
+			" [-i YP_INPUT_FILE] [-o YP_OUTPUT_FILE]\n\t\t",
+			"[-d YP_DOMAIN_NAME] [-m YP_MASTER_NAME] infile outfile\n");
+		exit(1);
+	}
+	
+	if (uflag != 0) {
+		list_database(infile,Uflag);
+	} else {
+		create_database(infile,outfile,
+				yp_input_file,yp_output_file,
+				yp_master_name,yp_domain_name,
+				bflag, lflag, sflag);
+	}
+	
+	return(0);
+	
+}
diff --git a/makedbm.tproj/ypdb.c b/makedbm.tproj/ypdb.c
new file mode 100644
index 0000000..c9bd178
--- /dev/null
+++ b/makedbm.tproj/ypdb.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdb.c,v 1.5 1997/02/09 09:49:36 maja Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * This code is derived from ndbm module of BSD4.4 db (hash) by
+ * Mats O Jansson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ypdb.h"
+
+#ifdef YPDB_PATCH
+extern DBM *__hash_open();
+#else
+extern DBM *__bt_open();
+#endif
+
+/*
+ * Returns:
+ * 	*DBM on success
+ *	 NULL on failure
+ */
+
+extern DBM *
+ypdb_open(file, flags, mode)
+	const char *file;
+	int flags, mode;
+{
+#ifdef YPDB_PATCH
+	HASHINFO info;
+	char path[MAXPATHLEN];
+
+	info.bsize = 4096;
+	info.ffactor = 40;
+	info.nelem = 1;
+	info.cachesize = NULL;
+	info.hash = NULL;
+	info.lorder = 0;
+	snprintf(path, sizeof(path), "%s%s", file, YPDB_SUFFIX);
+	return ((DBM *)__hash_open(path, flags, mode, &info, 0));
+#else
+	BTREEINFO info;
+	char path[MAXPATHLEN];
+	DBM *db;
+
+	info.flags = 0;
+	info.cachesize = 0;
+	info.maxkeypage = 0;
+	info.minkeypage = 0;
+	info.psize = 0;
+	info.compare = NULL;
+	info.prefix = NULL;
+	info.lorder = 0;
+	snprintf(path, sizeof(path), "%s%s", file, YPDB_SUFFIX);
+	db = (DBM *)__bt_open(path, flags, mode, &info, 0);
+	return (db);
+#endif
+}
+
+/*
+ * Returns:
+ * 	*DBM on success
+ *	 NULL on failure
+ */
+
+extern DBM *
+ypdb_open_suf(file, flags, mode)
+	const char *file;
+	int flags, mode;
+{
+#ifdef YPDB_PATCH
+	HASHINFO info;
+
+	info.bsize = 4096;
+	info.ffactor = 40;
+	info.nelem = 1;
+	info.cachesize = NULL;
+	info.hash = NULL;
+	info.lorder = 0;
+	return ((DBM *)__hash_open(file, flags, mode, &info, 0));
+#else
+	BTREEINFO info;
+	DBM *db;
+
+	info.flags = 0;
+	info.cachesize = 0;
+	info.maxkeypage = 0;
+	info.minkeypage = 0;
+	info.psize = 0;
+	info.compare = NULL;
+	info.prefix = NULL;
+	info.lorder = 0;
+	db = (DBM *)__bt_open(file, flags, mode, &info, 0);
+	return (db);
+#endif
+}
+
+extern void
+ypdb_close(db)
+	DBM *db;
+{
+	(void)(db->close)(db);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_fetch(db, key)
+	DBM *db;
+	datum key;
+{
+	datum retval;
+	int status;
+
+	status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
+	if (status) {
+		retval.dptr = NULL;
+		retval.dsize = 0;
+	}
+	return (retval);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_firstkey(db)
+	DBM *db;
+{
+	int status;
+	datum retdata, retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+	if (status)
+		retkey.dptr = NULL;
+	return (retkey);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_nextkey(db)
+	DBM *db;
+{
+	int status;
+	datum retdata, retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+	if (status)
+		retkey.dptr = NULL;
+	return (retkey);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_setkey(db, key)
+	DBM *db;
+        datum key;
+{
+	int status;
+	datum retdata;
+#ifdef YPDB_PATCH
+	datum retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+	if (status)
+		retkey.dptr = NULL;
+	while ((retkey.dptr != NULL) &&
+	       ((retkey.dsize != key.dsize) ||
+		(strncmp(key.dptr,retkey.dptr,retkey.dsize) != 0))) {
+	  status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+	  if (status)
+	  	retkey.dptr = NULL;
+	};
+	return (retkey);
+#else
+	status = (db->seq)(db, (DBT *)&key, (DBT *)&retdata, R_CURSOR);
+	if (status)
+		key.dptr = NULL;
+	return (key);
+#endif
+}
+
+/*
+ * Returns:
+ *	 0 on success
+ *	<0 failure
+ */
+
+int
+ypdb_delete(db, key)
+	DBM *db;
+	datum key;
+{
+	int status;
+
+	status = (db->del)(db, (DBT *)&key, 0);
+	if (status)
+		return (-1);
+	else
+		return (0);
+}
+
+/*
+ * Returns:
+ *	 0 on success
+ *	<0 failure
+ *	 1 if YPDB_INSERT and entry exists
+ */
+
+int
+ypdb_store(db, key, content, flags)
+	DBM *db;
+	datum key, content;
+	int flags;
+{
+	return ((db->put)(db, (DBT *)&key, (DBT *)&content,
+	    (flags == YPDB_INSERT) ? R_NOOVERWRITE : 0));
+}
+
diff --git a/makedbm.tproj/ypdb.h b/makedbm.tproj/ypdb.h
new file mode 100644
index 0000000..9afbad5
--- /dev/null
+++ b/makedbm.tproj/ypdb.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdb.h,v 1.5 1997/02/09 09:49:37 maja Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * This code is derived from ndbm module of BSD4.4 db (hash) by
+ * Mats O Jansson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPDB_H_
+#define _YPDB_H_
+
+#ifndef _DB_H_
+#include <bsd/db.h>
+#endif
+
+#define YPDB_SUFFIX	".db"
+
+/* Flags to ypdb_store(). */
+#define YPDB_INSERT      0
+#define YPDB_REPLACE     1
+
+#ifndef DATUM
+typedef struct {
+	char	*dptr;
+	int	dsize;
+} datum;
+#define DATUM
+#endif
+
+typedef DB DBM;
+
+__BEGIN_DECLS
+void	 ypdb_close __P((DBM *));
+datum	 ypdb_fetch __P((DBM *, datum));
+datum	 ypdb_firstkey __P((DBM *));
+datum	 ypdb_nextkey __P((DBM *));
+datum	 ypdb_setkey __P((DBM *, datum));
+DBM     *ypdb_open __P((const char *, int, int));
+DBM     *ypdb_open_suf __P((const char *, int, int));
+int	 ypdb_store __P((DBM *, datum, datum, int));
+__END_DECLS
+
+#endif /* !_YPDB_H_ */
diff --git a/makedbm.tproj/ypdef.h b/makedbm.tproj/ypdef.h
new file mode 100644
index 0000000..89970d7
--- /dev/null
+++ b/makedbm.tproj/ypdef.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdef.h,v 1.6 1997/03/30 20:51:14 maja Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPDEF_H_
+#define _YPDEF_H_
+
+#define YP_DB_PATH "/var/yp"
+#define YP_LAST_KEY        "YP_LAST_MODIFIED"
+#define YP_LAST_LEN	   (sizeof(YP_LAST_KEY)-1)
+#define YP_INPUT_KEY       "YP_INPUT_FILE"
+#define YP_INPUT_LEN	   (sizeof(YP_INPUT_KEY)-1)
+#define YP_OUTPUT_KEY      "YP_OUTPUT_FILE"
+#define YP_OUTPUT_LEN	   (sizeof(YP_OUTPUT_KEY)-1)
+#define YP_MASTER_KEY      "YP_MASTER_NAME"
+#define YP_MASTER_LEN	   (sizeof(YP_MASTER_KEY)-1)
+#define YP_DOMAIN_KEY      "YP_DOMAIN_NAME"
+#define YP_DOMAIN_LEN	   (sizeof(YP_DOMAIN_KEY)-1)
+#define YP_INTERDOMAIN_KEY "YP_INTERDOMAIN"
+#define YP_INTERDOMAIN_LEN (sizeof(YP_INTERDOMAIN_KEY)-1)
+#define YP_SECURE_KEY      "YP_SECURE"
+#define YP_SECURE_LEN      (sizeof(YP_SECURE_KEY)-1)
+
+#define MAX_LAST_LEN 10
+#define MAX_MASTER_LEN 255
+#define YP_HOSTNAME "hosts.byname"
+#define YP_HOSTADDR "hosts.byaddr"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define YPXFR_PROC "/usr/sbin/ypxfr"
+#define YPPUSH_PROC "/usr/sbin/yppush"
+#define YPSERV_PID_PATH "/var/run/ypserv.pid"
+#define YP_SECURENET_FILE "/var/yp/securenet"
+
+#endif /* !_YPDEF_H_ */
diff --git a/natd.tproj/Makefile b/natd.tproj/Makefile
new file mode 100644
index 0000000..ad7ef52
--- /dev/null
+++ b/natd.tproj/Makefile
@@ -0,0 +1,50 @@
+#
+# Generated by the Apple Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = natd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = natd.h
+
+CFILES = icmp.c natd.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble natd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /Library/Executables
+PDO_UNIX_INSTALLDIR = /bin
+LIBS = -lalias
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/natd.tproj/Makefile.postamble b/natd.tproj/Makefile.postamble
new file mode 100644
index 0000000..acc4f20
--- /dev/null
+++ b/natd.tproj/Makefile.postamble
@@ -0,0 +1,104 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGES: langages in which the project is written (default "English")
+#  English_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+install-man-page:
+	install -d $(DSTROOT)/usr/share/man/man8
+	install -c -m 444 natd.8 $(DSTROOT)/usr/share/man/man8/natd.8
+
diff --git a/natd.tproj/Makefile.preamble b/natd.tproj/Makefile.preamble
new file mode 100644
index 0000000..a4606c6
--- /dev/null
+++ b/natd.tproj/Makefile.preamble
@@ -0,0 +1,140 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.  For library projects you should
+#       set this to something like /Developer/Headers/$(NAME).  Do not set
+#       this variable for framework projects unless you do not want the
+#       header files included in the framework.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. This defaults to
+#       DYNAMIC.
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Uncomment to suppress generation of a KeyValueCoding index when installing 
+# frameworks (This index is used by WOB and IB to determine keys available
+# for an object).  Set to YES by default.
+# PREINDEX_FRAMEWORK = NO
+
+# Change this definition to install projects somewhere other than the
+# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
+# and "" on other systems.
+DSTROOT = $(HOME)
+
+AFTER_INSTALL += install-man-page
+
diff --git a/natd.tproj/PB.project b/natd.tproj/PB.project
new file mode 100644
index 0000000..a64fa2f
--- /dev/null
+++ b/natd.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (natd.h); 
+        OTHER_LIBS = (alias); 
+        OTHER_LINKED = (icmp.c, natd.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, natd.8); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = natd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = /Library/Executables; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/natd.tproj/icmp.c b/natd.tproj/icmp.c
new file mode 100644
index 0000000..10d3bda
--- /dev/null
+++ b/natd.tproj/icmp.c
@@ -0,0 +1,126 @@
+/*
+ * natd - Network Address Translation Daemon for FreeBSD.
+ *
+ * This software is provided free of charge, with no 
+ * warranty of any kind, either expressed or implied.
+ * Use at your own risk.
+ * 
+ * You may copy, modify and distribute this software (icmp.c) freely.
+ *
+ * Ari Suutari <suutari@iki.fi>
+ *
+ *	$Id: icmp.c,v 1.1.1.1 2000/01/11 01:48:51 wsanchez Exp $
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <netdb.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+
+#include <alias.h>
+
+#include "natd.h"
+
+int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu)
+{
+	char			icmpBuf[IP_MAXPACKET];
+	struct ip*		ip;
+	struct icmp*		icmp;
+	int			icmpLen;
+	int			failBytes;
+	int			failHdrLen;
+	struct sockaddr_in	addr;
+	int			wrote;
+	struct in_addr		swap;
+/*
+ * Don't send error if packet is
+ * not the first fragment.
+ */
+	if (ntohs (failedDgram->ip_off) & ~(IP_MF | IP_DF))
+		return 0;
+/*
+ * Dont respond if failed datagram is ICMP.
+ */
+	if (failedDgram->ip_p == IPPROTO_ICMP)
+		return 0;
+/*
+ * Start building the message.
+ */
+	ip   = (struct ip*) icmpBuf;
+	icmp = (struct icmp*) (icmpBuf + sizeof (struct ip));
+/*
+ * Complete ICMP part.
+ */
+	icmp->icmp_type  	= ICMP_UNREACH;
+	icmp->icmp_code		= ICMP_UNREACH_NEEDFRAG;
+	icmp->icmp_cksum	= 0;
+	icmp->icmp_void		= 0;
+	icmp->icmp_nextmtu	= htons (mtu);
+/*
+ * Copy header + 64 bits of original datagram.
+ */
+	failHdrLen = (failedDgram->ip_hl << 2);
+	failBytes  = failedDgram->ip_len - failHdrLen;
+	if (failBytes > 8)
+		failBytes = 8;
+
+	failBytes += failHdrLen;
+	icmpLen    = ICMP_MINLEN + failBytes;
+
+	memcpy (&icmp->icmp_ip, failedDgram, failBytes);
+/*
+ * Calculate checksum.
+ */
+	icmp->icmp_cksum = PacketAliasInternetChecksum ((u_short*) icmp,
+							icmpLen);
+/*
+ * Add IP header using old IP header as template.
+ */
+	memcpy (ip, failedDgram, sizeof (struct ip));
+
+	ip->ip_v	= 4;
+	ip->ip_hl	= 5;
+	ip->ip_len	= htons (sizeof (struct ip) + icmpLen);
+	ip->ip_p	= IPPROTO_ICMP;
+	ip->ip_tos	= 0;
+
+	swap = ip->ip_dst;
+	ip->ip_dst = ip->ip_src;
+	ip->ip_src = swap;
+
+	PacketAliasIn ((char*) ip, IP_MAXPACKET);
+
+	addr.sin_family		= AF_INET;
+	addr.sin_addr		= ip->ip_dst;
+	addr.sin_port		= 0;
+/*
+ * Put packet into processing queue.
+ */
+	wrote = sendto (sock, 
+		        icmp,
+	    		icmpLen,
+	    		0,
+	    		(struct sockaddr*) &addr,
+	    		sizeof addr);
+	
+	if (wrote != icmpLen)
+		Warn ("Cannot send ICMP message.");
+
+	return 1;
+}
+
+
diff --git a/natd.tproj/natd.8 b/natd.tproj/natd.8
new file mode 100644
index 0000000..1d1cb7f
--- /dev/null
+++ b/natd.tproj/natd.8
@@ -0,0 +1,426 @@
+.\" manual page [] for natd 1.4
+.\"	$Id: natd.8,v 1.1.1.1 2000/01/11 01:48:51 wsanchez Exp $
+.Dd 15 April 1997
+.Os FreeBSD
+.Dt NATD 8
+.Sh NAME
+.Nm natd
+.Nd
+Network Address Translation Daemon
+.Sh SYNOPSIS
+.Nm
+.Op Fl ldsmvu
+.Op Fl dynamic
+.Op Fl i Ar inport
+.Op Fl o Ar outport
+.Op Fl p Ar port
+.Op Fl a Ar address
+.Op Fl n Ar interface
+.Op Fl f Ar configfile
+
+.Nm
+.Op Fl log
+.Op Fl deny_incoming
+.Op Fl log_denied
+.Op Fl use_sockets
+.Op Fl same_ports
+.Op Fl verbose
+.Op Fl log_facility Ar facility_name
+.Op Fl unregistered_only
+.Op Fl dynamic
+.Op Fl inport Ar inport
+.Op Fl outport Ar outport
+.Op Fl port Ar port
+.Op Fl alias_address Ar address
+.Op Fl interface Ar interface
+.Op Fl config Ar configfile
+.Op Fl redirect_port Ar linkspec
+.Op Fl redirect_address Ar localIP publicIP
+.Op Fl reverse
+.Op Fl proxy_only
+.Op Fl proxy_rule Ar proxyspec
+.Op Fl pptpalias Ar localIP
+
+.Sh DESCRIPTION
+This program provides a Network Address Translation facility for use
+with
+.Xr divert 4
+sockets under FreeBSD.  It is intended for use with NICs - if you want
+to do NAT on a PPP link, use the -alias switch to
+.Xr ppp 8 .
+
+.Pp
+.Nm Natd
+normally runs in the background as a daemon.  It is passed raw IP packets
+as they travel into and out of the machine, and will possibly change these
+before re-injecting them back into the IP packet stream.
+
+.Pp
+.Nm Natd
+changes all packets destined for another host so that their source
+IP number is that of the current machine.  For each packet changed
+in this manner, an internal table entry is created to record this
+fact.  The source port number is also changed to indicate the
+table entry applying to the packet.  Packets that are received with
+a target IP of the current host are checked against this internal
+table.  If an entry is found, it is used to determine the correct
+target IP number and port to place in the packet.
+
+.Pp
+The following command line options are available.
+.Bl -tag -width Fl
+
+.It Fl log | l
+Log various aliasing statistics and information to the file
+.Pa /var/log/alias.log .
+This file is truncated each time natd is started.
+
+.It Fl deny_incoming | d
+Reject packets destined for the current IP number that have no entry
+in the internal translation table.
+
+.It Fl log_denied
+Log denied incoming packets via syslog (see also log_facility)
+
+.It Fl log_facility Ar facility_name
+Use specified log facility when logging information via syslog.
+Facility names are as in
+.Xr syslog.conf 5
+
+.It Fl use_sockets | s
+Allocate a
+.Xr socket 2
+in order to establish an FTP data or IRC DCC send connection.  This
+option uses more system resources, but guarantees successful connections
+when port numbers conflict.
+
+.It Fl same_ports | m
+Try to keep the same port number when altering outgoing packets.
+With this option, protocols such as RPC will have a better chance
+of working.  If it is not possible to maintain the port number, it
+will be silently changed as per normal.
+
+.It Fl verbose | v
+Don't call
+.Xr fork 2
+or
+.Xr daemon 3
+on startup.  Instead, stay attached to the controling terminal and
+display all packet alterations to the standard output.  This option
+should only be used for debugging purposes.
+
+.It Fl unregistered_only | u
+Only alter outgoing packets with an unregistered source address.
+According to rfc 1918, unregistered source addresses are 10.0.0.0/8,
+172.16.0.0/12 and 192.168.0.0/16.
+
+.It Fl redirect_port Ar proto targetIP:targetPORT [aliasIP:]aliasPORT [remoteIP[:remotePORT]]
+Redirect incoming connections arriving to given port to another host and port.
+Proto is either tcp or udp, targetIP is the desired target IP
+number, targetPORT is the desired target PORT number, aliasPORT
+is the requested PORT number and aliasIP is the aliasing address.
+RemoteIP and remotePORT can be used to specify the connection
+more accurately if necessary.
+For example, the argument
+
+.Ar tcp inside1:telnet 6666
+
+means that tcp packets destined for port 6666 on this machine will
+be sent to the telnet port on the inside1 machine.
+
+.It Fl redirect_address Ar localIP publicIP
+Redirect traffic for public IP address to a machine on the local
+network. This function is known as "static NAT". Normally static NAT
+is useful if your ISP has allocated a small block of IP addresses to you,
+but it can even be used in the case of single address:
+
+  redirect_address 10.0.0.8 0.0.0.0
+
+The above command would redirect all incoming traffic
+to machine 10.0.0.8.
+
+If several address aliases specify the same public address
+as follows
+
+  redirect_address 192.168.0.2 public_addr
+  redirect_address 192.168.0.3 public_addr
+  redirect_address 192.168.0.4 public_addr
+  
+the incoming traffic will be directed to the last
+translated local address (192.168.0.4), but outgoing
+traffic to the first two addresses will still be aliased
+to specified public address.
+
+.It Fl dynamic
+If the
+.Fl n
+or
+.Fl interface
+option is used,
+.Nm
+will monitor the routing socket for alterations to the
+.Ar interface
+passed.  If the interfaces IP number is changed,
+.Nm
+will dynamically alter its concept of the alias address.
+
+.It Fl i | inport Ar inport
+Read from and write to
+.Ar inport ,
+treating all packets as packets coming into the machine.
+
+.It Fl o | outport Ar outport
+Read from and write to
+.Ar outport ,
+treating all packets as packets going out of the machine.
+
+.It Fl p | port Ar port
+Read from and write to
+.Ar port ,
+distinguishing packets as incoming our outgoing using the rules specified in
+.Xr divert 4 .
+If
+.Ar port
+is not numeric, it is searched for in the
+.Pa /etc/services
+database using the
+.Xr getservbyname 3
+function.  If this flag is not specified, the divert port named natd will
+be used as a default.  An example entry in the
+.Pa /etc/services
+database would be:
+
+  natd   8668/divert  # Network Address Translation socket
+
+Refer to
+.Xr services 5
+for further details.
+
+.It Fl a | alias_address Ar address
+Use
+.Ar address
+as the alias address.  If this option is not specified, the
+.Fl n
+or
+.Fl interface
+option must be used.  The specified address should be the address assigned
+to the public network interface.
+.Pp
+All data passing out through this addresses interface will be rewritten
+with a source address equal to
+.Ar address .
+All data arriving at the interface from outside will be checked to
+see if it matches any already-aliased outgoing connection.  If it does,
+the packet is altered accordingly.  If not, all
+.Fl redirect_port
+and
+.Fl redirect_address
+assignments are checked and actioned.  If no other action can be made,
+and if
+.Fl deny_incoming
+is not specified, the packet is delivered to the local machine and port
+as specified in the packet.
+
+.It Fl n | interface Ar interface
+Use
+.Ar interface
+to determine the alias address.  If there is a possibility that the
+IP number associated with
+.Ar interface
+may change, the
+.Fl dynamic
+flag should also be used.  If this option is not specified, the
+.Fl a
+or
+.Fl alias_address
+flag must be used.
+.Pp
+The specified
+.Ar interface
+must be the public network interface.
+.It Fl f | config Ar configfile
+Read configuration from
+.Ar configfile .
+.Ar Configfile
+contains a list of options, one per line in the same form as the
+long form of the above command line flags.  For example, the line
+
+  alias_address 158.152.17.1
+
+would specify an alias address of 158.152.17.1.  Options that don't
+take an argument are specified with an option of
+.Ar yes
+or
+.Ar no
+in the configuration file.  For example, the line
+
+  log yes
+
+is synonomous with
+.Fl log .
+Empty lines and lines beginning with '#' are ignored.
+
+.It Fl reverse
+Reverse operation of natd. This can be useful in some 
+transparent proxying situations when outgoing traffic
+is redirected to the local machine and natd is running on the
+incoming interface (it usually runs on the outgoing interface).
+
+.It Fl proxy_only
+Force natd to perform transparent proxying
+only. Normal address translation is not performed.
+
+.It Fl proxy_rule Ar [type encode_ip_hdr|encode_tcp_stream] port xxxx server a.b.c.d:yyyy
+Enable transparent proxying. Packets with the given port going through this
+host to any other host are redirected to the given server and port.
+Optionally, the original target address can be encoded into the packet. Use 
+.Dq encode_ip_hdr
+to put this information into the IP option field or
+.Dq encode_tcp_stream
+to inject the data into the beginning of the TCP stream.
+
+.It Fl pptpalias Ar localIP
+Allow PPTP packets to go to the defined localIP address. PPTP is a VPN or secure
+IP tunneling technology being developed primarily by Microsoft. For its encrypted traffic,
+it uses an old IP encapsulation protocol called GRE (47). This
+natd option will translate any traffic of this protocol to a
+single, specified IP address. This would allow either one client or one server 
+to be serviced with natd. If you are setting up a server, don't forget to allow the TCP traffic
+for the PPTP setup. For a client or server, you must allow GRE (protocol 47) if you have firewall lists active.
+
+.El
+
+.Sh RUNNING NATD
+The following steps are necessary before attempting to run
+.Nm natd :
+
+.Bl -enum
+.It
+Get FreeBSD version 2.2 or higher.  Versions before this do not support
+.Xr divert 4
+sockets.
+
+.It
+Build a custom kernel with the following options:
+
+  options IPFIREWALL
+  options IPDIVERT
+
+Refer to the handbook for detailed instructions on building a custom
+kernel.
+
+.It
+Ensure that your machine is acting as a gateway.  This can be done by
+specifying the line
+
+  gateway_enable=YES
+
+in
+.Pa /etc/rc.conf ,
+or using the command
+
+  sysctl -w net.inet.ip.forwarding=1
+
+.It
+If you wish to use the
+.Fl n
+or
+.Fl interface
+flags, make sure that your interface is already configured.  If, for
+example, you wish to specify tun0 as your
+.Ar interface ,
+and you're using
+.Xr ppp 8
+on that interface, you must make sure that you start
+.Nm ppp
+prior to starting
+.Nm natd .
+
+.It
+Create an entry in
+.Pa /etc/services :
+
+  natd          8668/divert  # Network Address Translation socket
+
+This gives a default for the
+.Fl p
+or
+.Fl port
+flag.
+
+.El
+.Pp
+Running
+.Nm
+is fairly straight forward.  The line
+
+  natd -interface ed0
+
+should suffice in most cases (substituting the correct interface name).  Once
+.Nm
+is running, you must ensure that traffic is diverted to natd:
+
+.Bl -enum
+.It
+You will need to adjust the
+.Pa /etc/rc.firewall
+script to taste.  If you're not interested in having a firewall, the
+following lines will do:
+
+  /sbin/ipfw -f flush
+  /sbin/ipfw add divert natd all from any to any via ed0
+  /sbin/ipfw add pass all from any to any
+
+The second line depends on your interface (change ed0 as appropriate)
+and assumes that you've updated
+.Pa /etc/services
+with the natd entry as above.  If you specify real firewall rules, it's
+best to specify line 2 at the start of the script so that
+.Nm
+sees all packets before they are dropped by the firewall.  The firewall
+rules will be run again on each packet after translation by
+.Nm natd ,
+minus any divert rules.
+
+.It
+Enable your firewall by setting
+
+  firewall_enable=YES
+
+in
+.Pa /etc/rc.conf .
+This tells the system startup scripts to run the
+.Pa /etc/rc.firewall
+script.  If you don't wish to reboot now, just run this by hand from the
+console.  NEVER run this from a virtual session unless you put it into
+the background.  If you do, you'll lock yourself out after the flush
+takes place, and execution of
+.Pa /etc/rc.firewall
+will stop at this point - blocking all accesses permanently.  Running
+the script in the background should be enough to prevent this disaster.
+
+.El
+
+.Sh SEE ALSO
+.Xr getservbyname 2 ,
+.Xr socket 2 ,
+.Xr divert 4 ,
+.Xr services 5 ,
+.Xr ipfw 8
+
+.Sh AUTHORS
+This program is the result of the efforts of many people at different
+times:
+
+.An Archie Cobbs Aq archie@whistle.com
+(divert sockets)
+.An Charles Mott Aq cmott@srv.net
+(packet aliasing)
+.An Eivind Eklund Aq perhaps@yes.no
+(IRC support & misc additions)
+.An Ari Suutari Aq suutari@iki.fi
+(natd)
+.An Dru Nelson Aq dnelson@redwoodsoft.com
+(PPTP support)
+.An Brian Somers Aq brian@awfulhak.org
+(glue)
diff --git a/natd.tproj/natd.c b/natd.tproj/natd.c
new file mode 100644
index 0000000..bbb8678
--- /dev/null
+++ b/natd.tproj/natd.c
@@ -0,0 +1,1578 @@
+/*
+ * natd - Network Address Translation Daemon for FreeBSD.
+ *
+ * This software is provided free of charge, with no 
+ * warranty of any kind, either expressed or implied.
+ * Use at your own risk.
+ * 
+ * You may copy, modify and distribute this software (natd.c) freely.
+ *
+ * Ari Suutari <suutari@iki.fi>
+ *
+ *	$Id: natd.c,v 1.1.1.1 2000/01/11 01:48:51 wsanchez Exp $
+ */
+
+#define SYSLOG_NAMES
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <arpa/inet.h>
+
+#include <alias.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "natd.h"
+
+/* 
+ * Default values for input and output
+ * divert socket ports.
+ */
+
+#define	DEFAULT_SERVICE	"natd"
+
+/*
+ * Definition of a port range, and macros to deal with values.
+ * FORMAT:  HI 16-bits == first port in range, 0 == all ports.
+ *          LO 16-bits == number of ports in range
+ * NOTES:   - Port values are not stored in network byte order.
+ */
+
+typedef u_long port_range;
+
+#define GETLOPORT(x)     ((x) >> 0x10)
+#define GETNUMPORTS(x)   ((x) & 0x0000ffff)
+#define GETHIPORT(x)     (GETLOPORT((x)) + GETNUMPORTS((x)))
+
+/* Set y to be the low-port value in port_range variable x. */
+#define SETLOPORT(x,y)   ((x) = ((x) & 0x0000ffff) | ((y) << 0x10))
+
+/* Set y to be the number of ports in port_range variable x. */
+#define SETNUMPORTS(x,y) ((x) = ((x) & 0xffff0000) | (y))
+
+/*
+ * Function prototypes.
+ */
+
+static void	DoAliasing (int fd, int direction);
+static void	DaemonMode (void);
+static void	HandleRoutingInfo (int fd);
+static void	Usage (void);
+static char*	FormatPacket (struct ip*);
+static void	PrintPacket (struct ip*);
+static void	SyslogPacket (struct ip*, int priority, const char *label);
+static void	SetAliasAddressFromIfName (char* ifName);
+static void	InitiateShutdown (int);
+static void	Shutdown (int);
+static void	RefreshAddr (int);
+static void	ParseOption (const char* option, const char* parms, int cmdLine);
+static void	ReadConfigFile (const char* fileName);
+static void	SetupPortRedirect (const char* parms);
+static void	SetupAddressRedirect (const char* parms);
+static void	SetupPptpAlias (const char* parms);
+static void	StrToAddr (const char* str, struct in_addr* addr);
+static u_short  StrToPort (const char* str, const char* proto);
+static int      StrToPortRange (const char* str, const char* proto, port_range *portRange);
+static int 	StrToProto (const char* str);
+static int      StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange);
+static void	ParseArgs (int argc, char** argv);
+static void	FlushPacketBuffer (int fd);
+
+/*
+ * Globals.
+ */
+
+static	int			verbose;
+static 	int			background;
+static	int			running;
+static	int			assignAliasAddr;
+static	char*			ifName;
+static  int			ifIndex;
+static	u_short			inPort;
+static	u_short			outPort;
+static	u_short			inOutPort;
+static	struct in_addr		aliasAddr;
+static 	int			dynamicMode;
+static  int			ifMTU;
+static	int			aliasOverhead;
+static 	int			icmpSock;
+static	char			packetBuf[IP_MAXPACKET];
+static 	int			packetLen;
+static	struct sockaddr_in	packetAddr;
+static 	int			packetSock;
+static 	int			packetDirection;
+static  int			dropIgnoredIncoming;
+static  int			logDropped;
+static	int			logFacility;
+
+int main (int argc, char** argv)
+{
+	int			divertIn;
+	int			divertOut;
+	int			divertInOut;
+	int			routeSock;
+	struct sockaddr_in	addr;
+	fd_set			readMask;
+	fd_set			writeMask;
+	int			fdMax;
+/* 
+ * Initialize packet aliasing software.
+ * Done already here to be able to alter option bits
+ * during command line and configuration file processing.
+ */
+	PacketAliasInit ();
+/*
+ * Parse options.
+ */
+	inPort			= 0;
+	outPort			= 0;
+	verbose 		= 0;
+	inOutPort		= 0;
+	ifName			= NULL;
+	ifMTU			= -1;
+	background		= 0;
+	running			= 1;
+	assignAliasAddr		= 0;
+	aliasAddr.s_addr	= INADDR_NONE;
+	aliasOverhead		= 12;
+	dynamicMode		= 0;
+ 	logDropped		= 0;
+ 	logFacility		= LOG_DAEMON;
+/*
+ * Mark packet buffer empty.
+ */
+	packetSock		= -1;
+	packetDirection		= DONT_KNOW;
+
+	ParseArgs (argc, argv);
+/*
+ * Open syslog channel.
+ */
+	openlog ("natd", LOG_CONS | LOG_PID, logFacility);
+/*
+ * Check that valid aliasing address has been given.
+ */
+	if (aliasAddr.s_addr == INADDR_NONE && ifName == NULL)
+		errx (1, "aliasing address not given");
+
+	if (aliasAddr.s_addr != INADDR_NONE && ifName != NULL)
+		errx (1, "both alias address and interface "
+			 "name are not allowed");
+/*
+ * Check that valid port number is known.
+ */
+	if (inPort != 0 || outPort != 0)
+		if (inPort == 0 || outPort == 0)
+			errx (1, "both input and output ports are required");
+
+	if (inPort == 0 && outPort == 0 && inOutPort == 0)
+		ParseOption ("port", DEFAULT_SERVICE, 0);
+
+/*
+ * Check if ignored packets should be dropped.
+ */
+	dropIgnoredIncoming = PacketAliasSetMode (0, 0);
+	dropIgnoredIncoming &= PKT_ALIAS_DENY_INCOMING;
+/*
+ * Create divert sockets. Use only one socket if -p was specified
+ * on command line. Otherwise, create separate sockets for
+ * outgoing and incoming connnections.
+ */
+	if (inOutPort) {
+
+		divertInOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT);
+		if (divertInOut == -1)
+			Quit ("Unable to create divert socket.");
+
+		divertIn  = -1;
+		divertOut = -1;
+/*
+ * Bind socket.
+ */
+
+		addr.sin_family		= AF_INET;
+		addr.sin_addr.s_addr	= INADDR_ANY;
+		addr.sin_port		= inOutPort;
+
+		if (bind (divertInOut,
+			  (struct sockaddr*) &addr,
+			  sizeof addr) == -1)
+			Quit ("Unable to bind divert socket.");
+	}
+	else {
+
+		divertIn = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT);
+		if (divertIn == -1)
+			Quit ("Unable to create incoming divert socket.");
+
+		divertOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT);
+		if (divertOut == -1)
+			Quit ("Unable to create outgoing divert socket.");
+
+		divertInOut = -1;
+
+/*
+ * Bind divert sockets.
+ */
+
+		addr.sin_family		= AF_INET;
+		addr.sin_addr.s_addr	= INADDR_ANY;
+		addr.sin_port		= inPort;
+
+		if (bind (divertIn,
+			  (struct sockaddr*) &addr,
+			  sizeof addr) == -1)
+			Quit ("Unable to bind incoming divert socket.");
+
+		addr.sin_family		= AF_INET;
+		addr.sin_addr.s_addr	= INADDR_ANY;
+		addr.sin_port		= outPort;
+
+		if (bind (divertOut,
+			  (struct sockaddr*) &addr,
+			  sizeof addr) == -1)
+			Quit ("Unable to bind outgoing divert socket.");
+	}
+/*
+ * Create routing socket if interface name specified.
+ */
+	if (ifName && dynamicMode) {
+
+		routeSock = socket (PF_ROUTE, SOCK_RAW, 0);
+		if (routeSock == -1)
+			Quit ("Unable to create routing info socket.");
+	}
+	else
+		routeSock = -1;
+/*
+ * Create socket for sending ICMP messages.
+ */
+	icmpSock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
+	if (icmpSock == -1)
+		Quit ("Unable to create ICMP socket.");
+
+/*
+ * And disable reads for the socket, otherwise it slowly fills
+ * up with received icmps which we do not use.
+ */
+	shutdown(icmpSock, SHUT_RD);
+
+/*
+ * Become a daemon unless verbose mode was requested.
+ */
+	if (!verbose)
+		DaemonMode ();
+/*
+ * Catch signals to manage shutdown and
+ * refresh of interface address.
+ */
+	signal (SIGTERM, InitiateShutdown);
+	signal (SIGHUP, RefreshAddr);
+/*
+ * Set alias address if it has been given.
+ */
+	if (aliasAddr.s_addr != INADDR_NONE)
+		PacketAliasSetAddress (aliasAddr);
+/*
+ * We need largest descriptor number for select.
+ */
+
+	fdMax = -1;
+
+	if (divertIn > fdMax)
+		fdMax = divertIn;
+
+	if (divertOut > fdMax)
+		fdMax = divertOut;
+
+	if (divertInOut > fdMax)
+		fdMax = divertInOut;
+
+	if (routeSock > fdMax)
+		fdMax = routeSock;
+
+	while (running) {
+
+		if (divertInOut != -1 && !ifName && packetSock == -1) {
+/*
+ * When using only one socket, just call 
+ * DoAliasing repeatedly to process packets.
+ */
+			DoAliasing (divertInOut, DONT_KNOW);
+			continue;
+		}
+/* 
+ * Build read mask from socket descriptors to select.
+ */
+		FD_ZERO (&readMask);
+		FD_ZERO (&writeMask);
+
+/*
+ * If there is unsent packet in buffer, use select
+ * to check when socket comes writable again.
+ */
+		if (packetSock != -1) {
+
+			FD_SET (packetSock, &writeMask);
+		}
+		else {
+/*
+ * No unsent packet exists - safe to check if
+ * new ones are available.
+ */
+			if (divertIn != -1)
+				FD_SET (divertIn, &readMask);
+
+			if (divertOut != -1)
+				FD_SET (divertOut, &readMask);
+
+			if (divertInOut != -1)
+				FD_SET (divertInOut, &readMask);
+		}
+/*
+ * Routing info is processed always.
+ */
+		if (routeSock != -1)
+			FD_SET (routeSock, &readMask);
+
+		if (select (fdMax + 1,
+			    &readMask,
+			    &writeMask,
+			    NULL,
+			    NULL) == -1) {
+
+			if (errno == EINTR)
+				continue;
+
+			Quit ("Select failed.");
+		}
+
+		if (packetSock != -1)
+			if (FD_ISSET (packetSock, &writeMask))
+				FlushPacketBuffer (packetSock);
+
+		if (divertIn != -1)
+			if (FD_ISSET (divertIn, &readMask))
+				DoAliasing (divertIn, INPUT);
+
+		if (divertOut != -1)
+			if (FD_ISSET (divertOut, &readMask))
+				DoAliasing (divertOut, OUTPUT);
+
+		if (divertInOut != -1) 
+			if (FD_ISSET (divertInOut, &readMask))
+				DoAliasing (divertInOut, DONT_KNOW);
+
+		if (routeSock != -1)
+			if (FD_ISSET (routeSock, &readMask))
+				HandleRoutingInfo (routeSock);
+	}
+
+	if (background)
+		unlink (PIDFILE);
+
+	return 0;
+}
+
+static void DaemonMode ()
+{
+	FILE*	pidFile;
+
+	daemon (0, 0);
+	background = 1;
+
+	pidFile = fopen (PIDFILE, "w");
+	if (pidFile) {
+
+		fprintf (pidFile, "%d\n", getpid ());
+		fclose (pidFile);
+	}
+}
+
+static void ParseArgs (int argc, char** argv)
+{
+	int		arg;
+	char*		parm;
+	char*		opt;
+	char		parmBuf[256];
+
+	for (arg = 1; arg < argc; arg++) {
+
+		opt  = argv[arg];
+		if (*opt != '-') {
+
+			warnx ("invalid option %s", opt);
+			Usage ();
+		}
+
+		parm = NULL;
+		parmBuf[0] = '\0';
+
+		while (arg < argc - 1) {
+
+			if (argv[arg + 1][0] == '-')
+				break;
+
+			if (parm)
+				strcat (parmBuf, " ");
+
+			++arg;
+			parm = parmBuf;
+			strcat (parmBuf, argv[arg]);
+		}
+
+		ParseOption (opt + 1, parm, 1);
+	}
+}
+
+static void DoAliasing (int fd, int direction)
+{
+	int			bytes;
+	int			origBytes;
+	int			status;
+	int			addrSize;
+	struct ip*		ip;
+
+	if (assignAliasAddr) {
+
+		SetAliasAddressFromIfName (ifName);
+		assignAliasAddr = 0;
+	}
+/*
+ * Get packet from socket.
+ */
+	addrSize  = sizeof packetAddr;
+	origBytes = recvfrom (fd,
+			      packetBuf,
+			      sizeof packetBuf,
+			      0,
+			      (struct sockaddr*) &packetAddr,
+			      &addrSize);
+
+	if (origBytes == -1) {
+
+		if (errno != EINTR)
+			Warn ("read from divert socket failed");
+
+		return;
+	}
+/*
+ * This is a IP packet.
+ */
+	ip = (struct ip*) packetBuf;
+	if (direction == DONT_KNOW)
+		if (packetAddr.sin_addr.s_addr == INADDR_ANY)
+			direction = OUTPUT;
+		else
+			direction = INPUT;
+
+	if (verbose) {
+		
+/*
+ * Print packet direction and protocol type.
+ */
+		printf (direction == OUTPUT ? "Out " : "In  ");
+
+		switch (ip->ip_p) {
+		case IPPROTO_TCP:
+			printf ("[TCP]  ");
+			break;
+
+		case IPPROTO_UDP:
+			printf ("[UDP]  ");
+			break;
+
+		case IPPROTO_ICMP:
+			printf ("[ICMP] ");
+			break;
+
+		default:
+			printf ("[%d]    ", ip->ip_p);
+			break;
+		}
+/*
+ * Print addresses.
+ */
+		PrintPacket (ip);
+	}
+
+	if (direction == OUTPUT) {
+/*
+ * Outgoing packets. Do aliasing.
+ */
+		PacketAliasOut (packetBuf, IP_MAXPACKET);
+	}
+	else {
+
+/*
+ * Do aliasing.
+ */	
+		status = PacketAliasIn (packetBuf, IP_MAXPACKET);
+		if (status == PKT_ALIAS_IGNORED &&
+		    dropIgnoredIncoming) {
+
+			if (verbose)
+				printf (" dropped.\n");
+
+			if (logDropped)
+				SyslogPacket (ip, LOG_WARNING, "denied");
+
+			return;
+		}
+	}
+/*
+ * Length might have changed during aliasing.
+ */
+	bytes = ntohs (ip->ip_len);
+/*
+ * Update alias overhead size for outgoing packets.
+ */
+	if (direction == OUTPUT &&
+	    bytes - origBytes > aliasOverhead)
+		aliasOverhead = bytes - origBytes;
+
+	if (verbose) {
+		
+/*
+ * Print addresses after aliasing.
+ */
+		printf (" aliased to\n");
+		printf ("           ");
+		PrintPacket (ip);
+		printf ("\n");
+	}
+
+	packetLen  	= bytes;
+	packetSock 	= fd;
+	packetDirection = direction;
+
+	FlushPacketBuffer (fd);
+}
+
+static void FlushPacketBuffer (int fd)
+{
+	int			wrote;
+	char			msgBuf[80];
+/*
+ * Put packet back for processing.
+ */
+	wrote = sendto (fd, 
+		        packetBuf,
+	    		packetLen,
+	    		0,
+	    		(struct sockaddr*) &packetAddr,
+	    		sizeof packetAddr);
+	
+	if (wrote != packetLen) {
+/*
+ * If buffer space is not available,
+ * just return. Main loop will take care of 
+ * retrying send when space becomes available.
+ */
+		if (errno == ENOBUFS)
+			return;
+
+		if (errno == EMSGSIZE) {
+
+			if (packetDirection == OUTPUT &&
+			    ifMTU != -1)
+				SendNeedFragIcmp (icmpSock,
+						  (struct ip*) packetBuf,
+						  ifMTU - aliasOverhead);
+		}
+		else {
+
+			sprintf (msgBuf, "failed to write packet back");
+			Warn (msgBuf);
+		}
+	}
+
+	packetSock = -1;
+}
+
+static void HandleRoutingInfo (int fd)
+{
+	int			bytes;
+	struct if_msghdr	ifMsg;
+/*
+ * Get packet from socket.
+ */
+	bytes = read (fd, &ifMsg, sizeof ifMsg);
+	if (bytes == -1) {
+
+		Warn ("read from routing socket failed");
+		return;
+	}
+
+	if (ifMsg.ifm_version != RTM_VERSION) {
+
+		Warn ("unexpected packet read from routing socket");
+		return;
+	}
+
+	if (verbose)
+		printf ("Routing message %X received.\n", ifMsg.ifm_type);
+
+	if (ifMsg.ifm_type != RTM_NEWADDR)
+		return;
+
+	if (verbose && ifMsg.ifm_index == ifIndex)
+		printf ("Interface address has changed.\n");
+
+	if (ifMsg.ifm_index == ifIndex)
+		assignAliasAddr = 1;
+}
+
+static void PrintPacket (struct ip* ip)
+{
+	printf ("%s", FormatPacket (ip));
+}
+
+static void SyslogPacket (struct ip* ip, int priority, const char *label)
+{
+	syslog (priority, "%s %s", label, FormatPacket (ip));
+}
+
+static char* FormatPacket (struct ip* ip)
+{
+	static char	buf[256];
+	struct tcphdr*	tcphdr;
+	struct udphdr*	udphdr;
+	struct icmp*	icmphdr;
+	char		src[20];
+	char		dst[20];
+
+	strcpy (src, inet_ntoa (ip->ip_src));
+	strcpy (dst, inet_ntoa (ip->ip_dst));
+
+	switch (ip->ip_p) {
+	case IPPROTO_TCP:
+		tcphdr = (struct tcphdr*) ((char*) ip + (ip->ip_hl << 2));
+		sprintf (buf, "[TCP] %s:%d -> %s:%d",
+			      src,
+			      ntohs (tcphdr->th_sport),
+			      dst,
+			      ntohs (tcphdr->th_dport));
+		break;
+
+	case IPPROTO_UDP:
+		udphdr = (struct udphdr*) ((char*) ip + (ip->ip_hl << 2));
+		sprintf (buf, "[UDP] %s:%d -> %s:%d",
+			      src,
+			      ntohs (udphdr->uh_sport),
+			      dst,
+			      ntohs (udphdr->uh_dport));
+		break;
+
+	case IPPROTO_ICMP:
+		icmphdr = (struct icmp*) ((char*) ip + (ip->ip_hl << 2));
+		sprintf (buf, "[ICMP] %s -> %s %u(%u)",
+			      src,
+			      dst,
+			      icmphdr->icmp_type,
+			      icmphdr->icmp_code);
+		break;
+
+	default:
+		sprintf (buf, "[%d] %s -> %s ", ip->ip_p, src, dst);
+		break;
+	}
+
+	return buf;
+}
+
+static void SetAliasAddressFromIfName (char* ifn)
+{
+	struct ifconf		cf;
+	struct ifreq		buf[32];
+	char			msg[80];
+	struct ifreq*		ifPtr;
+	int			extra;
+	int			helperSock;
+	int			bytes;
+	struct sockaddr_in*	addr;
+	int			found;
+	struct ifreq		req;
+	char			last[10];
+/*
+ * Create a dummy socket to access interface information.
+ */
+	helperSock = socket (AF_INET, SOCK_DGRAM, 0);
+	if (helperSock == -1) {
+
+		Quit ("Failed to create helper socket.");
+		exit (1);
+	}
+
+	cf.ifc_len = sizeof (buf);
+	cf.ifc_req = buf;
+/*
+ * Get interface data.
+ */
+	if (ioctl (helperSock, SIOCGIFCONF, &cf) == -1) {
+
+		Quit ("Ioctl SIOCGIFCONF failed.");
+		exit (1);
+	}
+
+	ifIndex	= 0;
+	ifPtr	= buf;
+	bytes	= cf.ifc_len;
+	found   = 0;
+	last[0] = '\0';
+/*
+ * Loop through interfaces until one with
+ * given name is found. This is done to
+ * find correct interface index for routing
+ * message processing.
+ */
+	while (bytes) {
+
+		if (ifPtr->ifr_addr.sa_family == AF_INET &&
+                    !strcmp (ifPtr->ifr_name, ifn)) {
+
+			found = 1;
+			break;
+		}
+
+		if (strcmp (last, ifPtr->ifr_name)) {
+
+			strcpy (last, ifPtr->ifr_name);
+			++ifIndex;
+		}
+
+		extra = ifPtr->ifr_addr.sa_len - sizeof (struct sockaddr);
+
+		ifPtr++;
+		ifPtr = (struct ifreq*) ((char*) ifPtr + extra);
+		bytes -= sizeof (struct ifreq) + extra;
+	}
+
+	if (!found) {
+
+		close (helperSock);
+		sprintf (msg, "Unknown interface name %s.\n", ifn);
+		Quit (msg);
+	}
+/*
+ * Get MTU size.
+ */
+	strcpy (req.ifr_name, ifn);
+
+	if (ioctl (helperSock, SIOCGIFMTU, &req) == -1)
+		Quit ("Cannot get interface mtu size.");
+
+	ifMTU = req.ifr_mtu;
+/*
+ * Get interface address.
+ */
+	if (ioctl (helperSock, SIOCGIFADDR, &req) == -1)
+		Quit ("Cannot get interface address.");
+
+	addr = (struct sockaddr_in*) &req.ifr_addr;
+	PacketAliasSetAddress (addr->sin_addr);
+	syslog (LOG_INFO, "Aliasing to %s, mtu %d bytes",
+			  inet_ntoa (addr->sin_addr),
+			  ifMTU);
+
+	close (helperSock);
+}
+
+void Quit (const char* msg)
+{
+	Warn (msg);
+	exit (1);
+}
+
+void Warn (const char* msg)
+{
+	if (background)
+		syslog (LOG_ALERT, "%s (%m)", msg);
+	else
+		warn (msg);
+}
+
+static void RefreshAddr (int sig)
+{
+	signal (SIGHUP, RefreshAddr);
+	if (ifName)
+		assignAliasAddr = 1;
+}
+
+static void InitiateShutdown (int sig)
+{
+/*
+ * Start timer to allow kernel gracefully
+ * shutdown existing connections when system
+ * is shut down.
+ */
+	signal (SIGALRM, Shutdown);
+	alarm (10);
+}
+
+static void Shutdown (int sig)
+{
+	running = 0;
+}
+
+/* 
+ * Different options recognized by this program.
+ */
+
+enum Option {
+
+	PacketAliasOption,
+	Verbose,
+	InPort,
+	OutPort,
+	Port,
+	AliasAddress,
+	InterfaceName,
+	RedirectPort,
+	RedirectAddress,
+	ConfigFile,
+	DynamicMode,
+	PptpAlias,
+	ProxyRule,
+ 	LogDenied,
+ 	LogFacility
+};
+
+enum Param {
+	
+	YesNo,
+	Numeric,
+	String,
+	None,
+	Address,
+	Service
+};
+
+/*
+ * Option information structure (used by ParseOption).
+ */
+
+struct OptionInfo {
+	
+	enum Option		type;
+	int			packetAliasOpt;
+	enum Param		parm;
+	const char*		parmDescription;
+	const char*		description;
+	const char*		name; 
+	const char*		shortName;
+};
+
+/*
+ * Table of known options.
+ */
+
+static struct OptionInfo optionTable[] = {
+
+	{ PacketAliasOption,
+		PKT_ALIAS_UNREGISTERED_ONLY,
+		YesNo,
+		"[yes|no]",
+		"alias only unregistered addresses",
+		"unregistered_only",
+		"u" },
+
+	{ PacketAliasOption,
+		PKT_ALIAS_LOG,
+		YesNo,
+		"[yes|no]",
+		"enable logging",
+		"log",
+		"l" },
+
+	{ PacketAliasOption,
+		PKT_ALIAS_PROXY_ONLY,
+		YesNo,
+		"[yes|no]",
+		"proxy only",
+		"proxy_only",
+		NULL },
+
+	{ PacketAliasOption,
+		PKT_ALIAS_REVERSE,
+		YesNo,
+		"[yes|no]",
+		"operate in reverse mode",
+		"reverse",
+		NULL },
+
+	{ PacketAliasOption,
+		PKT_ALIAS_DENY_INCOMING,
+		YesNo,
+		"[yes|no]",
+		"allow incoming connections",
+		"deny_incoming",
+		"d" },
+
+	{ PacketAliasOption,
+		PKT_ALIAS_USE_SOCKETS,
+		YesNo,
+		"[yes|no]",
+		"use sockets to inhibit port conflict",
+		"use_sockets",
+		"s" },
+
+	{ PacketAliasOption,
+		PKT_ALIAS_SAME_PORTS,
+		YesNo,
+		"[yes|no]",
+		"try to keep original port numbers for connections",
+		"same_ports",
+		"m" },
+
+	{ Verbose,
+		0,
+		YesNo,
+		"[yes|no]",
+		"verbose mode, dump packet information",
+		"verbose",
+		"v" },
+	
+	{ DynamicMode,
+		0,
+		YesNo,
+		"[yes|no]",
+		"dynamic mode, automatically detect interface address changes",
+		"dynamic",
+		NULL },
+	
+	{ InPort,
+		0,
+		Service,
+		"number|service_name",
+		"set port for incoming packets",
+		"in_port",
+		"i" },
+	
+	{ OutPort,
+		0,
+		Service,
+		"number|service_name",
+		"set port for outgoing packets",
+		"out_port",
+		"o" },
+	
+	{ Port,
+		0,
+		Service,
+		"number|service_name",
+		"set port (defaults to natd/divert)",
+		"port",
+		"p" },
+	
+	{ AliasAddress,
+		0,
+		Address,
+		"x.x.x.x",
+		"address to use for aliasing",
+		"alias_address",
+		"a" },
+	
+	{ InterfaceName,
+		0,
+		String,
+	        "network_if_name",
+		"take aliasing address from interface",
+		"interface",
+		"n" },
+
+	{ ProxyRule,
+		0,
+		String,
+	        "[type encode_ip_hdr|encode_tcp_stream] port xxxx server "
+		"a.b.c.d:yyyy",
+		"add transparent proxying / destination NAT",
+		"proxy_rule",
+		NULL },
+
+	{ RedirectPort,
+		0,
+		String,
+	        "tcp|udp local_addr:local_port_range [public_addr:]public_port_range"
+	 	" [remote_addr[:remote_port_range]]",
+		"redirect a port (or ports) for incoming traffic",
+		"redirect_port",
+		NULL },
+
+	{ RedirectAddress,
+		0,
+		String,
+	        "local_addr public_addr",
+		"define mapping between local and public addresses",
+		"redirect_address",
+		NULL },
+
+       { PptpAlias,
+		0,
+		String,
+		"src",
+		"define inside machine for PPTP traffic",
+		"pptpalias",
+		NULL },
+
+	{ ConfigFile,
+		0,
+		String,
+		"file_name",
+		"read options from configuration file",
+		"config",
+		"f" },
+
+	{ LogDenied,
+		0,
+		YesNo,
+	        "[yes|no]",
+		"enable logging of denied incoming packets",
+		"log_denied",
+		NULL },
+
+	{ LogFacility,
+		0,
+		String,
+	        "facility",
+		"name of syslog facility to use for logging",
+		"log_facility",
+		NULL }
+
+};
+	
+static void ParseOption (const char* option, const char* parms, int cmdLine)
+{
+	int			i;
+	struct OptionInfo*	info;
+	int			yesNoValue;
+	int			aliasValue;
+	int			numValue;
+	u_short			uNumValue;
+	const char*		strValue;
+	struct in_addr		addrValue;
+	int			max;
+	char*			end;
+	CODE* 			fac_record = NULL;
+/*
+ * Find option from table.
+ */
+	max = sizeof (optionTable) / sizeof (struct OptionInfo);
+	for (i = 0, info = optionTable; i < max; i++, info++) {
+
+		if (!strcmp (info->name, option))
+			break;
+
+		if (info->shortName)
+			if (!strcmp (info->shortName, option))
+				break;
+	}
+
+	if (i >= max) {
+
+		warnx ("unknown option %s", option);
+		Usage ();
+	}
+
+	uNumValue	= 0;
+	yesNoValue	= 0;
+	numValue	= 0;
+	strValue	= NULL;
+/*
+ * Check parameters.
+ */
+	switch (info->parm) {
+	case YesNo:
+		if (!parms)
+			parms = "yes";
+
+		if (!strcmp (parms, "yes"))
+			yesNoValue = 1;
+		else
+			if (!strcmp (parms, "no"))
+				yesNoValue = 0;
+			else
+				errx (1, "%s needs yes/no parameter", option);
+		break;
+
+	case Service:
+		if (!parms)
+			errx (1, "%s needs service name or "
+				 "port number parameter",
+				 option);
+
+		uNumValue = StrToPort (parms, "divert");
+		break;
+
+	case Numeric:
+		if (parms)
+			numValue = strtol (parms, &end, 10);
+		else
+			end = NULL;
+
+		if (end == parms)
+			errx (1, "%s needs numeric parameter", option);
+		break;
+
+	case String:
+		strValue = parms;
+		if (!strValue)
+			errx (1, "%s needs parameter", option);
+		break;
+
+	case None:
+		if (parms)
+			errx (1, "%s does not take parameters", option);
+		break;
+
+	case Address:
+		if (!parms)
+			errx (1, "%s needs address/host parameter", option);
+
+		StrToAddr (parms, &addrValue);
+		break;
+	}
+
+	switch (info->type) {
+	case PacketAliasOption:
+	
+		aliasValue = yesNoValue ? info->packetAliasOpt : 0;
+		PacketAliasSetMode (aliasValue, info->packetAliasOpt);
+		break;
+
+	case Verbose:
+		verbose = yesNoValue;
+		break;
+
+	case DynamicMode:
+		dynamicMode = yesNoValue;
+		break;
+
+	case InPort:
+		inPort = uNumValue;
+		break;
+
+	case OutPort:
+		outPort = uNumValue;
+		break;
+
+	case Port:
+		inOutPort = uNumValue;
+		break;
+
+	case AliasAddress:
+		memcpy (&aliasAddr, &addrValue, sizeof (struct in_addr));
+		break;
+
+	case RedirectPort:
+		SetupPortRedirect (strValue);
+		break;
+
+	case RedirectAddress:
+		SetupAddressRedirect (strValue);
+		break;
+
+	case PptpAlias:
+		SetupPptpAlias (strValue);
+		break;
+
+	case ProxyRule:
+		PacketAliasProxyRule (strValue);
+		break;
+
+	case InterfaceName:
+		if (ifName)
+			free (ifName);
+
+		ifName = strdup (strValue);
+		assignAliasAddr = 1;
+		break;
+
+	case ConfigFile:
+		ReadConfigFile (strValue);
+		break;
+
+	case LogDenied:
+		logDropped = 1;
+		break;
+
+	case LogFacility:
+
+		fac_record = facilitynames;
+		while (fac_record->c_name != NULL) {
+
+			if (!strcmp (fac_record->c_name, strValue)) {
+
+				logFacility = fac_record->c_val;
+				break;
+
+			}
+			else
+				fac_record++;
+		}
+
+		if(fac_record->c_name == NULL)
+			errx(1, "Unknown log facility name: %s", strValue);	
+
+		break;
+	}
+}
+
+void ReadConfigFile (const char* fileName)
+{
+	FILE*	file;
+	char	buf[128];
+	char*	ptr;
+	char*	option;
+
+	file = fopen (fileName, "r");
+	if (!file) {
+
+		sprintf (buf, "Cannot open config file %s.\n", fileName);
+		Quit (buf);
+	}
+
+	while (fgets (buf, sizeof (buf), file)) {
+
+		ptr = strchr (buf, '\n');
+		if (!ptr)
+			errx (1, "config line too long: %s", buf);
+
+		*ptr = '\0';
+		if (buf[0] == '#')
+			continue;
+
+		ptr = buf;
+/*
+ * Skip white space at beginning of line.
+ */
+		while (*ptr && isspace (*ptr))
+			++ptr;
+
+		if (*ptr == '\0')
+			continue;
+/*
+ * Extract option name.
+ */
+		option = ptr;
+		while (*ptr && !isspace (*ptr))
+			++ptr;
+
+		if (*ptr != '\0') {
+
+			*ptr = '\0';
+			++ptr;
+		}
+/*
+ * Skip white space between name and parms.
+ */
+		while (*ptr && isspace (*ptr))
+			++ptr;
+
+		ParseOption (option, *ptr ? ptr : NULL, 0);
+	}
+
+	fclose (file);
+}
+
+static void Usage ()
+{
+	int			i;
+	int			max;
+	struct OptionInfo*	info;
+
+	fprintf (stderr, "Recognized options:\n\n");
+
+	max = sizeof (optionTable) / sizeof (struct OptionInfo);
+	for (i = 0, info = optionTable; i < max; i++, info++) {
+
+		fprintf (stderr, "-%-20s %s\n", info->name,
+						info->parmDescription);
+
+		if (info->shortName)
+			fprintf (stderr, "-%-20s %s\n", info->shortName,
+							info->parmDescription);
+
+		fprintf (stderr, "      %s\n\n", info->description);
+	}
+
+	exit (1);
+}
+
+void SetupPptpAlias (const char* parms)
+{
+	char		buf[128];
+	char*		ptr;
+	struct in_addr	srcAddr;
+
+	strcpy (buf, parms);
+
+/*
+ * Extract source address.
+ */
+	ptr = strtok (buf, " \t");
+	if (!ptr)
+		errx(1, "pptpalias: missing src address");
+
+	StrToAddr (ptr, &srcAddr);
+	PacketAliasPptp (srcAddr);
+}
+
+void SetupPortRedirect (const char* parms)
+{
+	char		buf[128];
+	char*		ptr;
+	struct in_addr	localAddr;
+	struct in_addr	publicAddr;
+	struct in_addr	remoteAddr;
+	port_range      portRange;
+	u_short         localPort      = 0;
+	u_short         publicPort     = 0;
+	u_short         remotePort     = 0;
+	u_short         numLocalPorts  = 0;
+	u_short         numPublicPorts = 0;
+	u_short         numRemotePorts = 0;
+	int		proto;
+	char*		protoName;
+	char*		separator;
+	int             i;
+
+	strcpy (buf, parms);
+/*
+ * Extract protocol.
+ */
+	protoName = strtok (buf, " \t");
+	if (!protoName)
+		errx (1, "redirect_port: missing protocol");
+
+	proto = StrToProto (protoName);
+/*
+ * Extract local address.
+ */
+	ptr = strtok (NULL, " \t");
+	if (!ptr)
+		errx (1, "redirect_port: missing local address");
+
+	if ( StrToAddrAndPortRange (ptr, &localAddr, protoName, &portRange) != 0 )
+	        errx (1, "redirect_port: invalid local port range");
+
+	localPort     = GETLOPORT(portRange);
+	numLocalPorts = GETNUMPORTS(portRange);
+
+/*
+ * Extract public port and optinally address.
+ */
+	ptr = strtok (NULL, " \t");
+	if (!ptr)
+		errx (1, "redirect_port: missing public port");
+
+	separator = strchr (ptr, ':');
+	if (separator) {
+	        if (StrToAddrAndPortRange (ptr, &publicAddr, protoName, &portRange) != 0 )
+		        errx (1, "redirect_port: invalid public port range");
+	}
+	else {
+		publicAddr.s_addr = INADDR_ANY;
+		if (StrToPortRange (ptr, protoName, &portRange) != 0)
+		        errx (1, "redirect_port: invalid public port range");
+	}
+
+	publicPort     = GETLOPORT(portRange);
+	numPublicPorts = GETNUMPORTS(portRange);
+
+/*
+ * Extract remote address and optionally port.
+ */
+	ptr = strtok (NULL, " \t");
+	if (ptr) {
+		separator = strchr (ptr, ':');
+		if (separator)
+		        if (StrToAddrAndPortRange (ptr, &remoteAddr, protoName, &portRange) != 0)
+			        errx (1, "redirect_port: invalid remote port range");
+		else {
+		        SETLOPORT(portRange, 0);
+			SETNUMPORTS(portRange, 1);
+			StrToAddr (ptr, &remoteAddr);
+		}
+	}
+	else {
+	        SETLOPORT(portRange, 0);
+		SETNUMPORTS(portRange, 1);
+		remoteAddr.s_addr = INADDR_ANY;
+	}
+
+	remotePort     = GETLOPORT(portRange);
+	numRemotePorts = GETNUMPORTS(portRange);
+
+/*
+ * Make sure port ranges match up, then add the redirect ports.
+ */
+	if (numLocalPorts != numPublicPorts)
+	        errx (1, "redirect_port: port ranges must be equal in size");
+
+	/* Remote port range is allowed to be '0' which means all ports. */
+	if (numRemotePorts != numLocalPorts && numRemotePorts != 1 && remotePort != 0)
+	        errx (1, "redirect_port: remote port must be 0 or equal to local port range in size");
+
+	for (i = 0 ; i < numPublicPorts ; ++i) {
+	        /* If remotePort is all ports, set it to 0. */
+	        u_short remotePortCopy = remotePort + i;
+	        if (numRemotePorts == 1 && remotePort == 0)
+		        remotePortCopy = 0;
+
+	        PacketAliasRedirectPort (localAddr,
+					 htons(localPort + i),
+					 remoteAddr,
+					 htons(remotePortCopy),
+					 publicAddr,
+					 htons(publicPort + i),
+					 proto);
+	}
+}
+
+void SetupAddressRedirect (const char* parms)
+{
+	char		buf[128];
+	char*		ptr;
+	struct in_addr	localAddr;
+	struct in_addr	publicAddr;
+
+	strcpy (buf, parms);
+/*
+ * Extract local address.
+ */
+	ptr = strtok (buf, " \t");
+	if (!ptr)
+		errx (1, "redirect_address: missing local address");
+
+	StrToAddr (ptr, &localAddr);
+/*
+ * Extract public address.
+ */
+	ptr = strtok (NULL, " \t");
+	if (!ptr)
+		errx (1, "redirect_address: missing public address");
+
+	StrToAddr (ptr, &publicAddr);
+	PacketAliasRedirectAddr (localAddr, publicAddr);
+}
+
+void StrToAddr (const char* str, struct in_addr* addr)
+{
+	struct hostent* hp;
+
+	if (inet_aton (str, addr))
+		return;
+
+	hp = gethostbyname (str);
+	if (!hp)
+		errx (1, "unknown host %s", str);
+
+	memcpy (addr, hp->h_addr, sizeof (struct in_addr));
+}
+
+u_short StrToPort (const char* str, const char* proto)
+{
+	u_short		port;
+	struct servent*	sp;
+	char*		end;
+
+	port = strtol (str, &end, 10);
+	if (end != str)
+		return htons (port);
+
+	sp = getservbyname (str, proto);
+	if (!sp)
+		errx (1, "unknown service %s/%s", str, proto);
+
+	return sp->s_port;
+}
+
+int StrToPortRange (const char* str, const char* proto, port_range *portRange)
+{
+	char*           sep;
+	struct servent*	sp;
+	char*		end;
+	u_short         loPort;
+	u_short         hiPort;
+	
+	/* First see if this is a service, return corresponding port if so. */
+	sp = getservbyname (str,proto);
+	if (sp) {
+	        SETLOPORT(*portRange, ntohs(sp->s_port));
+		SETNUMPORTS(*portRange, 1);
+		return 0;
+	}
+	        
+	/* Not a service, see if it's a single port or port range. */
+	sep = strchr (str, '-');
+	if (sep == NULL) {
+	        SETLOPORT(*portRange, strtol(str, &end, 10));
+		if (end != str) {
+		        /* Single port. */
+		        SETNUMPORTS(*portRange, 1);
+			return 0;
+		}
+
+		/* Error in port range field. */
+		errx (1, "unknown service %s/%s", str, proto);
+	}
+
+	/* Port range, get the values and sanity check. */
+	sscanf (str, "%hu-%hu", &loPort, &hiPort);
+	SETLOPORT(*portRange, loPort);
+	SETNUMPORTS(*portRange, 0);	/* Error by default */
+	if (loPort <= hiPort)
+	        SETNUMPORTS(*portRange, hiPort - loPort + 1);
+
+	if (GETNUMPORTS(*portRange) == 0)
+	        errx (1, "invalid port range %s", str);
+
+	return 0;
+}
+
+
+int StrToProto (const char* str)
+{
+	if (!strcmp (str, "tcp"))
+		return IPPROTO_TCP;
+
+	if (!strcmp (str, "udp"))
+		return IPPROTO_UDP;
+
+	errx (1, "unknown protocol %s. Expected tcp or udp", str);
+}
+
+int StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange)
+{
+	char*	ptr;
+
+	ptr = strchr (str, ':');
+	if (!ptr)
+		errx (1, "%s is missing port number", str);
+
+	*ptr = '\0';
+	++ptr;
+
+	StrToAddr (str, addr);
+	return StrToPortRange (ptr, proto, portRange);
+}
diff --git a/natd.tproj/natd.h b/natd.tproj/natd.h
new file mode 100644
index 0000000..f179cb5
--- /dev/null
+++ b/natd.tproj/natd.h
@@ -0,0 +1,24 @@
+/*
+ * natd - Network Address Translation Daemon for FreeBSD.
+ *
+ * This software is provided free of charge, with no 
+ * warranty of any kind, either expressed or implied.
+ * Use at your own risk.
+ * 
+ * You may copy, modify and distribute this software (natd.h) freely.
+ *
+ * Ari Suutari <suutari@iki.fi>
+ *
+ *	$Id: natd.h,v 1.1.1.1 2000/01/11 01:48:51 wsanchez Exp $
+ */
+
+#define PIDFILE	"/var/run/natd.pid"
+#define	INPUT		1
+#define	OUTPUT		2
+#define	DONT_KNOW	3
+
+extern void Quit (const char* msg);
+extern void Warn (const char* msg);
+extern int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu);
+
+
diff --git a/netstat.tproj/DERIVED_FILES b/netstat.tproj/DERIVED_FILES
new file mode 100644
index 0000000..a4fa6c9
--- /dev/null
+++ b/netstat.tproj/DERIVED_FILES
@@ -0,0 +1 @@
+unix/bsd/netiso/tp_astring.c
diff --git a/netstat.tproj/Makefile b/netstat.tproj/Makefile
new file mode 100644
index 0000000..a009e36
--- /dev/null
+++ b/netstat.tproj/Makefile
@@ -0,0 +1,54 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = netstat
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = netstat.h
+
+CFILES = data.c if.c inet.c iso.c main.c mbuf.c mroute.c route.c\
+         tp_astring.c unix.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble netstat.1\
+            DERIVED_FILES
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+HEADER_PATHS =\
+               -I$(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders/bsd/netat
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/netstat.tproj/Makefile.postamble b/netstat.tproj/Makefile.postamble
new file mode 100644
index 0000000..34d448d
--- /dev/null
+++ b/netstat.tproj/Makefile.postamble
@@ -0,0 +1,2 @@
+INSTALL_AS_USER = root
+INSTALL_PERMISSIONS =4555
diff --git a/netstat.tproj/Makefile.preamble b/netstat.tproj/Makefile.preamble
new file mode 100644
index 0000000..cc0d3d0
--- /dev/null
+++ b/netstat.tproj/Makefile.preamble
@@ -0,0 +1,4 @@
+CLEAN_ALL_SUBPROJECTS = YES
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
+vpath %.c `pwd`
diff --git a/netstat.tproj/PB.project b/netstat.tproj/PB.project
new file mode 100644
index 0000000..91d9ed6
--- /dev/null
+++ b/netstat.tproj/PB.project
@@ -0,0 +1,49 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        HEADERSEARCH = (
+            "$(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders/bsd/netat"
+        ); 
+        H_FILES = (netstat.h); 
+        LIBRARYSEARCH = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (
+            data.c, 
+            if.c, 
+            inet.c, 
+            iso.c, 
+            main.c, 
+            mbuf.c, 
+            mroute.c, 
+            route.c, 
+            tp_astring.c, 
+            unix.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, netstat.1, DERIVED_FILES); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = netstat; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/netstat.tproj/data.c b/netstat.tproj/data.c
new file mode 100644
index 0000000..9e0bbe2
--- /dev/null
+++ b/netstat.tproj/data.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* NeXT */
+#ifndef EXTERN
+#define EXTERN 
+#endif
+#include "netstat.h"
diff --git a/netstat.tproj/if.c b/netstat.tproj/if.c
new file mode 100644
index 0000000..43be850
--- /dev/null
+++ b/netstat.tproj/if.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*
+static char sccsid[] = "@(#)if.c	8.3 (Berkeley) 4/28/95";
+*/
+static const char rcsid[] =
+	"$Id: if.c,v 1.1.1.2 2000/01/11 01:48:51 wsanchez Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/ethernet.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#ifdef IPX
+#include <netipx/ipx.h>
+#include <netipx/ipx_if.h>
+#endif
+
+#ifdef NS
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#endif
+#ifdef ISO
+#include <netiso/iso.h>
+#include <netiso/iso_var.h>
+#endif
+#include <arpa/inet.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "netstat.h"
+
+#define	YES	1
+#define	NO	0
+
+static void sidewaysintpr __P((u_int, u_long));
+static void catchalarm __P((int));
+
+/*
+ * Print a description of the network interfaces.
+ */
+void
+intpr(interval, ifnetaddr)
+	int interval;
+	u_long ifnetaddr;
+{
+	struct ifnet ifnet;
+	struct ifnethead ifnethead;
+	union {
+		struct ifaddr ifa;
+		struct in_ifaddr in;
+#ifdef IPX
+		struct ipx_ifaddr ipx;
+#endif
+#ifdef NS
+		struct ns_ifaddr ns;
+#endif
+#ifdef ISO
+		struct iso_ifaddr iso;
+#endif
+	} ifaddr;
+	u_long ifaddraddr;
+	u_long ifaddrfound;
+	u_long ifnetfound;
+	struct sockaddr *sa;
+	char name[32], tname[16];
+
+	if (ifnetaddr == 0) {
+		printf("ifnet: symbol not defined\n");
+		return;
+	}
+	if (interval) {
+		sidewaysintpr((unsigned)interval, ifnetaddr);
+		return;
+	}
+	if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead))
+		return;
+	ifnetaddr = (u_long)ifnethead.tqh_first;
+	if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
+		return;
+
+	printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
+		"Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
+	if (bflag)
+		printf(" %10.10s","Ibytes");
+	printf(" %8.8s %5.5s", "Opkts", "Oerrs");
+	if (bflag)
+		printf(" %10.10s","Obytes");
+	printf(" %5s", "Coll");
+	if (tflag)
+		printf(" %s", "Time");
+	if (dflag)
+		printf(" %s", "Drop");
+	putchar('\n');
+	ifaddraddr = 0;
+	while (ifnetaddr || ifaddraddr) {
+		struct sockaddr_in *sin;
+		register char *cp;
+		int n, m;
+
+		if (ifaddraddr == 0) {
+			ifnetfound = ifnetaddr;
+			if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) ||
+			    kread((u_long)ifnet.if_name, tname, 16))
+				return;
+			tname[15] = '\0';
+			ifnetaddr = (u_long)ifnet.if_link.tqe_next;
+			snprintf(name, 32, "%s%d", tname, ifnet.if_unit);
+			if (interface != 0 && (strcmp(name, interface) != 0))
+				continue;
+			cp = index(name, '\0');
+			if ((ifnet.if_flags&IFF_UP) == 0)
+				*cp++ = '*';
+			*cp = '\0';
+			ifaddraddr = (u_long)ifnet.if_addrhead.tqh_first;
+		}
+		printf("%-5.5s %-5lu ", name, ifnet.if_mtu);
+		ifaddrfound = ifaddraddr;
+		if (ifaddraddr == 0) {
+			printf("%-13.13s ", "none");
+			printf("%-15.15s ", "none");
+		} else {
+			if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
+				ifaddraddr = 0;
+				continue;
+			}
+#define CP(x) ((char *)(x))
+			cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
+				CP(&ifaddr); sa = (struct sockaddr *)cp;
+			switch (sa->sa_family) {
+			case AF_UNSPEC:
+				printf("%-13.13s ", "none");
+				printf("%-15.15s ", "none");
+				break;
+			case AF_INET:
+				sin = (struct sockaddr_in *)sa;
+#ifdef notdef
+				/* can't use inet_makeaddr because kernel
+				 * keeps nets unshifted.
+				 */
+				in = inet_makeaddr(ifaddr.in.ia_subnet,
+					INADDR_ANY);
+				printf("%-13.13s ", netname(in.s_addr,
+				    ifaddr.in.ia_subnetmask));
+#else
+				printf("%-13.13s ",
+				    netname(htonl(ifaddr.in.ia_subnet),
+				    ifaddr.in.ia_subnetmask));
+#endif
+				printf("%-15.15s ",
+				    routename(sin->sin_addr.s_addr));
+				break;
+#ifdef IPX
+
+			case AF_IPX:
+				{
+				struct sockaddr_ipx *sipx =
+					(struct sockaddr_ipx *)sa;
+				u_long net;
+				char netnum[10];
+
+				*(union ipx_net *) &net = sipx->sipx_addr.x_net;
+				sprintf(netnum, "%lx", (u_long)ntohl(net));
+				printf("ipx:%-8s ", netnum);
+/*				printf("ipx:%-8s ", netname(net, 0L)); */
+				printf("%-15s ",
+				    ipx_phost((struct sockaddr *)sipx));
+				}
+				break;
+#endif
+#if 0
+			case AF_APPLETALK:
+				printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
+				printf("%-9.9s  ",atalk_print(sa,0x0b) );
+				break;
+#endif
+#ifdef NS
+			case AF_NS:
+				{
+				struct sockaddr_ns *sns =
+					(struct sockaddr_ns *)sa;
+				u_long net;
+				char netnum[10];
+
+				*(union ns_net *) &net = sns->sns_addr.x_net;
+				sprintf(netnum, "%lxH", ntohl(net));
+				upHex(netnum);
+				printf("ns:%-8s ", netnum);
+				printf("%-15s ",
+				    ns_phost((struct sockaddr *)sns));
+				}
+				break;
+#endif
+			case AF_LINK:
+				{
+				struct sockaddr_dl *sdl =
+					(struct sockaddr_dl *)sa;
+				    cp = (char *)LLADDR(sdl);
+				    n = sdl->sdl_alen;
+				}
+				m = printf("%-11.11s ", "<Link>");
+				goto hexprint;
+			default:
+				m = printf("(%d)", sa->sa_family);
+				for (cp = sa->sa_len + (char *)sa;
+					--cp > sa->sa_data && (*cp == 0);) {}
+				n = cp - sa->sa_data + 1;
+				cp = sa->sa_data;
+			hexprint:
+				while (--n >= 0)
+					m += printf("%02x%c", *cp++ & 0xff,
+						    n > 0 ? '.' : ' ');
+				m = 30 - m;
+				while (m-- > 0)
+					putchar(' ');
+				break;
+			}
+			ifaddraddr = (u_long)ifaddr.ifa.ifa_link.tqe_next;
+		}
+		printf("%8lu %5lu ",
+		    ifnet.if_ipackets, ifnet.if_ierrors);
+		if (bflag)
+			printf("%10lu ", ifnet.if_ibytes);
+		printf("%8lu %5lu ",
+		    ifnet.if_opackets, ifnet.if_oerrors);
+		if (bflag)
+			printf("%10lu ", ifnet.if_obytes);
+		printf("%5lu", ifnet.if_collisions);
+		if (tflag)
+			printf(" %3d", ifnet.if_timer);
+		if (dflag)
+			printf(" %3d", ifnet.if_snd.ifq_drops);
+		putchar('\n');
+		if (aflag && ifaddrfound) {
+			/*
+			 * Print family's multicast addresses
+			 */
+			u_long multiaddr;
+			struct ifmultiaddr ifma;
+			union {
+				struct sockaddr sa;
+				struct sockaddr_in in;
+				struct sockaddr_dl dl;
+			} msa;
+			const char *fmt;
+
+			for(multiaddr = (u_long)ifnet.if_multiaddrs.lh_first;
+			    multiaddr;
+			    multiaddr = (u_long)ifma.ifma_link.le_next) {
+				if (kread(multiaddr, (char *)&ifma,
+					  sizeof ifma))
+					break;
+				if (kread((u_long)ifma.ifma_addr, (char *)&msa,
+					  sizeof msa))
+					break;
+				if (msa.sa.sa_family != sa->sa_family)
+					continue;
+				
+				fmt = 0;
+				switch (msa.sa.sa_family) {
+				case AF_INET:
+					fmt = routename(msa.in.sin_addr.s_addr);
+					break;
+
+				case AF_LINK:
+					switch (ifnet.if_type) {
+					case IFT_ETHER:
+					case IFT_FDDI:
+						fmt = ether_ntoa(
+							(struct ether_addr *)
+							LLADDR(&msa.dl));
+						break;
+					}
+					break;
+				}
+				if (fmt)
+					printf("%23s %s\n", "", fmt);
+			}
+		}
+	}
+}
+
+#define	MAXIF	10
+struct	iftot {
+	char	ift_name[16];		/* interface name */
+	u_int	ift_ip;			/* input packets */
+	u_int	ift_ie;			/* input errors */
+	u_int	ift_op;			/* output packets */
+	u_int	ift_oe;			/* output errors */
+	u_int	ift_co;			/* collisions */
+	u_int	ift_dr;			/* drops */
+	u_int	ift_ib;			/* input bytes */
+	u_int	ift_ob;			/* output bytes */
+} iftot[MAXIF];
+
+u_char	signalled;			/* set if alarm goes off "early" */
+
+/*
+ * Print a running summary of interface statistics.
+ * Repeat display every interval seconds, showing statistics
+ * collected over that interval.  Assumes that interval is non-zero.
+ * First line printed at top of screen is always cumulative.
+ * XXX - should be rewritten to use ifmib(4).
+ */
+static void
+sidewaysintpr(interval, off)
+	unsigned interval;
+	u_long off;
+{
+	struct ifnet ifnet;
+	u_long firstifnet;
+	struct ifnethead ifnethead;
+	register struct iftot *ip, *total;
+	register int line;
+	struct iftot *lastif, *sum, *interesting;
+	int oldmask, first;
+	u_long interesting_off;
+
+	if (kread(off, (char *)&ifnethead, sizeof ifnethead))
+		return;
+	firstifnet = (u_long)ifnethead.tqh_first;
+
+	lastif = iftot;
+	sum = iftot + MAXIF - 1;
+	total = sum - 1;
+	interesting = NULL;
+	interesting_off = 0;
+	for (off = firstifnet, ip = iftot; off;) {
+		char name[16], tname[16];
+
+		if (kread(off, (char *)&ifnet, sizeof ifnet))
+			break;
+		if (kread((u_long)ifnet.if_name, tname, 16))
+			break;
+		tname[15] = '\0';
+		snprintf(name, 16, "%s%d", tname, ifnet.if_unit);
+		if (interface && strcmp(name, interface) == 0) {
+			interesting = ip;
+			interesting_off = off;
+		}
+		snprintf(ip->ift_name, 16, "(%s)", name);;
+		ip++;
+		if (ip >= iftot + MAXIF - 2)
+			break;
+		off = (u_long) ifnet.if_link.tqe_next;
+	}
+	lastif = ip;
+
+	(void)signal(SIGALRM, catchalarm);
+	signalled = NO;
+	(void)alarm(interval);
+	for (ip = iftot; ip < iftot + MAXIF; ip++) {
+		ip->ift_ip = 0;
+		ip->ift_ie = 0;
+		ip->ift_ib = 0;
+		ip->ift_op = 0;
+		ip->ift_oe = 0;
+		ip->ift_ob = 0;
+		ip->ift_co = 0;
+		ip->ift_dr = 0;
+	}
+	first = 1;
+banner:
+	printf("%17s %14s %16s", "input",
+	    interesting ? interesting->ift_name : "(Total)", "output");
+	putchar('\n');
+	printf("%10s %5s %10s %10s %5s %10s %5s",
+	    "packets", "errs", "bytes", "packets", "errs", "bytes", "colls");
+	if (dflag)
+		printf(" %5.5s", "drops");
+	putchar('\n');
+	fflush(stdout);
+	line = 0;
+loop:
+	if (interesting != NULL) {
+		ip = interesting;
+		if (kread(interesting_off, (char *)&ifnet, sizeof ifnet)) {
+			printf("???\n");
+			exit(1);
+		};
+		if (!first) {
+			printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
+				ifnet.if_ipackets - ip->ift_ip,
+				ifnet.if_ierrors - ip->ift_ie,
+				ifnet.if_ibytes - ip->ift_ib,
+				ifnet.if_opackets - ip->ift_op,
+				ifnet.if_oerrors - ip->ift_oe,
+				ifnet.if_obytes - ip->ift_ob,
+				ifnet.if_collisions - ip->ift_co);
+			if (dflag)
+				printf(" %5u", ifnet.if_snd.ifq_drops - ip->ift_dr);
+		}
+		ip->ift_ip = ifnet.if_ipackets;
+		ip->ift_ie = ifnet.if_ierrors;
+		ip->ift_ib = ifnet.if_ibytes;
+		ip->ift_op = ifnet.if_opackets;
+		ip->ift_oe = ifnet.if_oerrors;
+		ip->ift_ob = ifnet.if_obytes;
+		ip->ift_co = ifnet.if_collisions;
+		ip->ift_dr = ifnet.if_snd.ifq_drops;
+	} else {
+		sum->ift_ip = 0;
+		sum->ift_ie = 0;
+		sum->ift_ib = 0;
+		sum->ift_op = 0;
+		sum->ift_oe = 0;
+		sum->ift_ob = 0;
+		sum->ift_co = 0;
+		sum->ift_dr = 0;
+		for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
+			if (kread(off, (char *)&ifnet, sizeof ifnet)) {
+				off = 0;
+				continue;
+			}
+			sum->ift_ip += ifnet.if_ipackets;
+			sum->ift_ie += ifnet.if_ierrors;
+			sum->ift_ib += ifnet.if_ibytes;
+			sum->ift_op += ifnet.if_opackets;
+			sum->ift_oe += ifnet.if_oerrors;
+			sum->ift_ob += ifnet.if_obytes;
+			sum->ift_co += ifnet.if_collisions;
+			sum->ift_dr += ifnet.if_snd.ifq_drops;
+			off = (u_long) ifnet.if_link.tqe_next;
+		}
+		if (!first) {
+			printf("%10u %5u %10u %10u %5u %10u %5u",
+				sum->ift_ip - total->ift_ip,
+				sum->ift_ie - total->ift_ie,
+				sum->ift_ib - total->ift_ib,
+				sum->ift_op - total->ift_op,
+				sum->ift_oe - total->ift_oe,
+				sum->ift_ob - total->ift_ob,
+				sum->ift_co - total->ift_co);
+			if (dflag)
+				printf(" %5u", sum->ift_dr - total->ift_dr);
+		}
+		*total = *sum;
+	}
+	if (!first)
+		putchar('\n');
+	fflush(stdout);
+	oldmask = sigblock(sigmask(SIGALRM));
+	if (! signalled) {
+		sigpause(0);
+	}
+	sigsetmask(oldmask);
+	signalled = NO;
+	(void)alarm(interval);
+	line++;
+	first = 0;
+	if (line == 21)
+		goto banner;
+	else
+		goto loop;
+	/*NOTREACHED*/
+}
+
+/*
+ * Called if an interval expires before sidewaysintpr has completed a loop.
+ * Sets a flag to not wait for the alarm.
+ */
+static void
+catchalarm(signo)
+	int signo;
+{
+	signalled = YES;
+}
diff --git a/netstat.tproj/inet.c b/netstat.tproj/inet.c
new file mode 100644
index 0000000..0c2250a
--- /dev/null
+++ b/netstat.tproj/inet.c
@@ -0,0 +1,616 @@
+/*
+ * Copyright (c) 1983, 1988, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*
+static char sccsid[] = "@(#)inet.c	8.5 (Berkeley) 5/24/95";
+*/
+static const char rcsid[] =
+	"$Id: inet.c,v 1.1.1.2 2000/01/11 01:48:52 wsanchez Exp $";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/sysctl.h>
+#include <sys/protosw.h>
+
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/icmp_var.h>
+#include <netinet/igmp_var.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include <netinet/tcp_seq.h>
+#define TCPSTATES
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_debug.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include <arpa/inet.h>
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "netstat.h"
+
+char	*inetname __P((struct in_addr *));
+void	inetprint __P((struct in_addr *, int, char *, int));
+
+/*
+ * Print a summary of connections related to an Internet
+ * protocol.  For TCP, also give state of connection.
+ * Listening processes (aflag) are suppressed unless the
+ * -a (all) flag is specified.
+ */
+void
+protopr(proto, name)
+	u_long proto;		/* for sysctl version we pass proto # */
+	char *name;
+{
+	int istcp;
+	static int first = 1;
+	char *buf;
+	const char *mibvar;
+	struct tcpcb *tp;
+	struct inpcb *inp;
+	struct xinpgen *xig, *oxig;
+	struct xsocket *so;
+	size_t len;
+
+	istcp = 0;
+	switch (proto) {
+	case IPPROTO_TCP:
+		istcp = 1;
+		mibvar = "net.inet.tcp.pcblist";
+		break;
+	case IPPROTO_UDP:
+		mibvar = "net.inet.udp.pcblist";
+		break;
+	case IPPROTO_DIVERT:
+		mibvar = "net.inet.divert.pcblist";
+		break;
+	default:
+		mibvar = "net.inet.raw.pcblist";
+		break;
+	}
+	len = 0;
+	if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
+		if (errno != ENOENT)
+			warn("sysctl: %s", mibvar);
+		return;
+	}
+	if ((buf = malloc(len)) == 0) {
+		warn("malloc %lu bytes", (u_long)len);
+		return;
+	}
+	if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
+		warn("sysctl: %s", mibvar);
+		free(buf);
+		return;
+	}
+
+	oxig = xig = (struct xinpgen *)buf;
+	for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
+	     xig->xig_len > sizeof(struct xinpgen);
+	     xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
+		if (istcp) {
+			tp = &((struct xtcpcb *)xig)->xt_tp;
+			inp = &((struct xtcpcb *)xig)->xt_inp;
+			so = &((struct xtcpcb *)xig)->xt_socket;
+		} else {
+			inp = &((struct xinpcb *)xig)->xi_inp;
+			so = &((struct xinpcb *)xig)->xi_socket;
+		}
+
+		/* Ignore sockets for protocols other than the desired one. */
+		if (so->xso_protocol != proto)
+			continue;
+
+		/* Ignore PCBs which were freed during copyout. */
+		if (inp->inp_gencnt > oxig->xig_gen)
+			continue;
+
+		if (!aflag && inet_lnaof(inp->inp_laddr) == INADDR_ANY)
+			continue;
+
+		if (first) {
+			printf("Active Internet connections");
+			if (aflag)
+				printf(" (including servers)");
+			putchar('\n');
+			if (Aflag)
+				printf("%-8.8s ", "Socket");
+			printf(Aflag ?
+				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
+				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
+				"Proto", "Recv-Q", "Send-Q",
+				"Local Address", "Foreign Address", "(state)");
+			first = 0;
+		}
+		if (Aflag) {
+			if (istcp)
+				printf("%8lx ", (u_long)inp->inp_ppcb);
+			else
+				printf("%8lx ", (u_long)so->so_pcb);
+		}
+		printf("%-5.5s %6ld %6ld ", name, so->so_rcv.sb_cc,
+			so->so_snd.sb_cc);
+		if (nflag) {
+			inetprint(&inp->inp_laddr, (int)inp->inp_lport,
+			    name, 1);
+			inetprint(&inp->inp_faddr, (int)inp->inp_fport,
+			    name, 1);
+		} else if (inp->inp_flags & INP_ANONPORT) {
+			inetprint(&inp->inp_laddr, (int)inp->inp_lport,
+			    name, 1);
+			inetprint(&inp->inp_faddr, (int)inp->inp_fport,
+			    name, 0);
+		} else {
+			inetprint(&inp->inp_laddr, (int)inp->inp_lport,
+			    name, 0);
+			inetprint(&inp->inp_faddr, (int)inp->inp_fport,
+			    name, inp->inp_lport != inp->inp_fport);
+		}
+		if (istcp) {
+			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
+				printf(" %d", tp->t_state);
+                      else {
+				printf(" %s", tcpstates[tp->t_state]);
+#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
+                              /* Show T/TCP `hidden state' */
+                              if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
+                                      putchar('*');
+#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
+                      }
+		}
+		putchar('\n');
+	}
+	if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
+		if (oxig->xig_count > xig->xig_count) {
+			printf("Some %s sockets may have been deleted.\n",
+			       name);
+		} else if (oxig->xig_count < xig->xig_count) {
+			printf("Some %s sockets may have been created.\n",
+			       name);
+		} else {
+			printf("Some %s sockets may have been created or deleted",
+			       name);
+		}
+	}
+	free(buf);
+}
+
+/*
+ * Dump TCP statistics structure.
+ */
+void
+tcp_stats(off, name)
+	u_long off;
+	char *name;
+{
+	struct tcpstat tcpstat;
+	size_t len = sizeof tcpstat;
+	
+	if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, 0, 0) < 0) {
+		warn("sysctl: net.inet.tcp.stats");
+		return;
+	}
+
+	printf ("%s:\n", name);
+
+#define	p(f, m) if (tcpstat.f || sflag <= 1) \
+    printf(m, tcpstat.f, plural(tcpstat.f))
+#define	p1a(f, m) if (tcpstat.f || sflag <= 1) \
+    printf(m, tcpstat.f)
+#define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
+    printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
+#define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
+    printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
+#define	p3(f, m) if (tcpstat.f || sflag <= 1) \
+    printf(m, tcpstat.f, plurales(tcpstat.f))
+
+	p(tcps_sndtotal, "\t%lu packet%s sent\n");
+	p2(tcps_sndpack,tcps_sndbyte,
+		"\t\t%lu data packet%s (%lu byte%s)\n");
+	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
+		"\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
+	p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n");
+	p2a(tcps_sndacks, tcps_delack,
+		"\t\t%lu ack-only packet%s (%lu delayed)\n");
+	p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
+	p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
+	p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
+	p(tcps_sndctrl, "\t\t%lu control packet%s\n");
+	p(tcps_rcvtotal, "\t%lu packet%s received\n");
+	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n");
+	p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
+	p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
+	p2(tcps_rcvpack, tcps_rcvbyte,
+		"\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
+	p2(tcps_rcvduppack, tcps_rcvdupbyte,
+		"\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
+	p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
+	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
+		"\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
+	p2(tcps_rcvoopack, tcps_rcvoobyte,
+		"\t\t%lu out-of-order packet%s (%lu byte%s)\n");
+	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
+		"\t\t%lu packet%s (%lu byte%s) of data after window\n");
+	p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
+	p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
+	p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
+	p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
+	p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
+	p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
+	p(tcps_connattempt, "\t%lu connection request%s\n");
+	p(tcps_accepts, "\t%lu connection accept%s\n");
+	p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
+	p(tcps_listendrop, "\t%lu listen queue overflow%s\n");
+	p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
+	p2(tcps_closed, tcps_drops,
+		"\t%lu connection%s closed (including %lu drop%s)\n");
+	p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n");
+	p(tcps_cachedrttvar, 
+	  "\t\t%lu connection%s updated cached RTT variance on close\n");
+	p(tcps_cachedssthresh,
+	  "\t\t%lu connection%s updated cached ssthresh on close\n");
+	p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
+	p2(tcps_rttupdated, tcps_segstimed,
+		"\t%lu segment%s updated rtt (of %lu attempt%s)\n");
+	p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
+	p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
+	p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
+	p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n");
+	p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
+	p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
+	p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
+	p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
+	p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
+#undef p
+#undef p1a
+#undef p2
+#undef p2a
+#undef p3
+}
+
+/*
+ * Dump UDP statistics structure.
+ */
+void
+udp_stats(off, name)
+	u_long off;
+	char *name;
+{
+	struct udpstat udpstat;
+	size_t len = sizeof udpstat;
+	u_long delivered;
+
+	if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, 0, 0) < 0) {
+		warn("sysctl: net.inet.udp.stats");
+		return;
+	}
+
+	printf("%s:\n", name);
+#define	p(f, m) if (udpstat.f || sflag <= 1) \
+    printf(m, udpstat.f, plural(udpstat.f))
+#define	p1a(f, m) if (udpstat.f || sflag <= 1) \
+    printf(m, udpstat.f)
+	p(udps_ipackets, "\t%lu datagram%s received\n");
+	p1a(udps_hdrops, "\t%lu with incomplete header\n");
+	p1a(udps_badlen, "\t%lu with bad data length field\n");
+	p1a(udps_badsum, "\t%lu with bad checksum\n");
+	p1a(udps_noport, "\t%lu dropped due to no socket\n");
+	p(udps_noportbcast,
+	    "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
+	p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
+	p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n");
+	delivered = udpstat.udps_ipackets -
+		    udpstat.udps_hdrops -
+		    udpstat.udps_badlen -
+		    udpstat.udps_badsum -
+		    udpstat.udps_noport -
+		    udpstat.udps_noportbcast -
+		    udpstat.udps_fullsock;
+	if (delivered || sflag <= 1)
+		printf("\t%lu delivered\n", delivered);
+	p(udps_opackets, "\t%lu datagram%s output\n");
+#undef p
+#undef p1a
+}
+
+/*
+ * Dump IP statistics structure.
+ */
+void
+ip_stats(off, name)
+	u_long off;
+	char *name;
+{
+	struct ipstat ipstat;
+	size_t len = sizeof ipstat;
+
+	if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, 0, 0) < 0) {
+		warn("sysctl: net.inet.ip.stats");
+		return;
+	}
+
+	printf("%s:\n", name);
+
+#define	p(f, m) if (ipstat.f || sflag <= 1) \
+    printf(m, ipstat.f, plural(ipstat.f))
+#define	p1a(f, m) if (ipstat.f || sflag <= 1) \
+    printf(m, ipstat.f)
+
+	p(ips_total, "\t%lu total packet%s received\n");
+	p(ips_badsum, "\t%lu bad header checksum%s\n");
+	p1a(ips_toosmall, "\t%lu with size smaller than minimum\n");
+	p1a(ips_tooshort, "\t%lu with data size < data length\n");
+	p1a(ips_badhlen, "\t%lu with header length < data size\n");
+	p1a(ips_badlen, "\t%lu with data length < header length\n");
+	p1a(ips_badoptions, "\t%lu with bad options\n");
+	p1a(ips_badvers, "\t%lu with incorrect version number\n");
+	p(ips_fragments, "\t%lu fragment%s received\n");
+	p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
+	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
+	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
+	p(ips_delivered, "\t%lu packet%s for this host\n");
+	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
+	p(ips_forward, "\t%lu packet%s forwarded");
+	p(ips_fastforward, " (%lu packet%s fast forwarded)");
+	if (ipstat.ips_forward || sflag <= 1) 
+		putchar('\n');
+	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
+	p(ips_notmember,
+	  "\t%lu packet%s received for unknown multicast group\n");
+	p(ips_redirectsent, "\t%lu redirect%s sent\n");
+	p(ips_localout, "\t%lu packet%s sent from this host\n");
+	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
+	p(ips_odropped,
+	  "\t%lu output packet%s dropped due to no bufs, etc.\n");
+	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
+	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
+	p(ips_ofragments, "\t%lu fragment%s created\n");
+	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
+#undef p
+#undef p1a
+}
+
+static	char *icmpnames[] = {
+	"echo reply",
+	"#1",
+	"#2",
+	"destination unreachable",
+	"source quench",
+	"routing redirect",
+	"#6",
+	"#7",
+	"echo",
+	"router advertisement",
+	"router solicitation",
+	"time exceeded",
+	"parameter problem",
+	"time stamp",
+	"time stamp reply",
+	"information request",
+	"information request reply",
+	"address mask request",
+	"address mask reply",
+};
+
+/*
+ * Dump ICMP statistics.
+ */
+void
+icmp_stats(off, name)
+	u_long off;
+	char *name;
+{
+	struct icmpstat icmpstat;
+	int i, first;
+	int mib[4];		/* CTL_NET + PF_INET + IPPROTO_ICMP + req */
+	size_t len;
+
+	mib[0] = CTL_NET;
+	mib[1] = PF_INET;
+	mib[2] = IPPROTO_ICMP;
+	mib[3] = ICMPCTL_STATS;
+
+	len = sizeof icmpstat;
+	memset(&icmpstat, 0, len);
+	if (sysctl(mib, 4, &icmpstat, &len, (void *)0, 0) < 0)
+		return;		/* XXX should complain, but not traditional */
+
+	printf("%s:\n", name);
+
+#define	p(f, m) if (icmpstat.f || sflag <= 1) \
+    printf(m, icmpstat.f, plural(icmpstat.f))
+#define	p1a(f, m) if (icmpstat.f || sflag <= 1) \
+    printf(m, icmpstat.f)
+
+	p(icps_error, "\t%lu call%s to icmp_error\n");
+	p(icps_oldicmp,
+	    "\t%lu error%s not generated 'cuz old message was icmp\n");
+	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
+		if (icmpstat.icps_outhist[i] != 0) {
+			if (first) {
+				printf("\tOutput histogram:\n");
+				first = 0;
+			}
+			printf("\t\t%s: %lu\n", icmpnames[i],
+				icmpstat.icps_outhist[i]);
+		}
+	p(icps_badcode, "\t%lu message%s with bad code fields\n");
+	p(icps_tooshort, "\t%lu message%s < minimum length\n");
+	p(icps_checksum, "\t%lu bad checksum%s\n");
+	p(icps_badlen, "\t%lu message%s with bad length\n");
+	p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n");
+	p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n");
+	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
+		if (icmpstat.icps_inhist[i] != 0) {
+			if (first) {
+				printf("\tInput histogram:\n");
+				first = 0;
+			}
+			printf("\t\t%s: %lu\n", icmpnames[i],
+				icmpstat.icps_inhist[i]);
+		}
+	p(icps_reflect, "\t%lu message response%s generated\n");
+#undef p
+#undef p1a
+	mib[3] = ICMPCTL_MASKREPL;
+	len = sizeof i;
+	if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0)
+		return;
+	printf("\tICMP address mask responses are %sabled\n", 
+	       i ? "en" : "dis");
+}
+
+/*
+ * Dump IGMP statistics structure.
+ */
+void
+igmp_stats(off, name)
+	u_long off;
+	char *name;
+{
+	struct igmpstat igmpstat;
+	size_t len = sizeof igmpstat;
+
+	if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, 0, 0) < 0) {
+		warn("sysctl: net.inet.igmp.stats");
+		return;
+	}
+
+	printf("%s:\n", name);
+
+#define	p(f, m) if (igmpstat.f || sflag <= 1) \
+    printf(m, igmpstat.f, plural(igmpstat.f))
+#define	py(f, m) if (igmpstat.f || sflag <= 1) \
+    printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
+	p(igps_rcv_total, "\t%u message%s received\n");
+        p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
+        p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
+        py(igps_rcv_queries, "\t%u membership quer%s received\n");
+        py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n");
+        p(igps_rcv_reports, "\t%u membership report%s received\n");
+        p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n");
+        p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n");
+        p(igps_snd_reports, "\t%u membership report%s sent\n");
+#undef p
+#undef py
+}
+
+/*
+ * Pretty print an Internet address (net address + port).
+ */
+void
+inetprint(in, port, proto,numeric)
+	register struct in_addr *in;
+	int port;
+	char *proto;
+	int numeric;
+{
+	struct servent *sp = 0;
+	char line[80], *cp;
+	int width;
+
+	sprintf(line, "%.*s.", (Aflag && !numeric) ? 12 : 16, inetname(in));
+	cp = index(line, '\0');
+	if (!numeric && port)
+		sp = getservbyport((int)port, proto);
+	if (sp || port == 0)
+		sprintf(cp, "%.15s", sp ? sp->s_name : "*");
+	else
+		sprintf(cp, "%d", ntohs((u_short)port));
+	width = Aflag ? 18 : 22;
+	printf(" %-*.*s", width, width, line);
+}
+
+/*
+ * Construct an Internet address representation.
+ * If the nflag has been supplied, give
+ * numeric value, otherwise try for symbolic name.
+ */
+char *
+inetname(inp)
+	struct in_addr *inp;
+{
+	register char *cp;
+	static char line[MAXHOSTNAMELEN + 1];
+	struct hostent *hp;
+	struct netent *np;
+
+	cp = 0;
+	if (!nflag && inp->s_addr != INADDR_ANY) {
+		int net = inet_netof(*inp);
+		int lna = inet_lnaof(*inp);
+
+		if (lna == INADDR_ANY) {
+			np = getnetbyaddr(net, AF_INET);
+			if (np)
+				cp = np->n_name;
+		}
+		if (cp == 0) {
+			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
+			if (hp) {
+				cp = hp->h_name;
+				trimdomain(cp);
+			}
+		}
+	}
+	if (inp->s_addr == INADDR_ANY)
+		strcpy(line, "*");
+	else if (cp) {
+		strncpy(line, cp, sizeof(line) - 1);
+		line[sizeof(line) - 1] = '\0';
+	} else {
+		inp->s_addr = ntohl(inp->s_addr);
+#define C(x)	((u_int)((x) & 0xff))
+		sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
+		    C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
+	}
+	return (line);
+}
diff --git a/netstat.tproj/iso.c b/netstat.tproj/iso.c
new file mode 100644
index 0000000..526e790
--- /dev/null
+++ b/netstat.tproj/iso.c
@@ -0,0 +1,866 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)iso.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * $Header: /cvs/Darwin/Commands/NeXT/network_cmds/netstat.tproj/iso.c,v 1.1.1.2 2000/01/11 01:48:52 wsanchez Exp $
+ * $Source: /cvs/Darwin/Commands/NeXT/network_cmds/netstat.tproj/iso.c,v $
+ */
+/*******************************************************************************
+	          Copyright IBM Corporation 1987
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*******************************************************************************/
+
+/*
+ * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
+ */
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/time.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/queue.h>
+#include <errno.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netiso/iso.h>
+#include <netiso/iso_errno.h>
+#include <netiso/clnp.h>
+#include <netiso/esis.h>
+#include <netiso/clnp_stat.h>
+#include <netiso/argo_debug.h>
+#undef satosiso
+#include <netiso/tp_param.h>
+#include <netiso/tp_states.h>
+#include <netiso/tp_pcb.h>
+#include <netiso/tp_stat.h>
+#include <netiso/iso_pcb.h>
+#include <netiso/cltp_var.h>
+#include <netiso/cons.h>
+#ifdef IncStat
+#undef IncStat
+#endif
+#include <netiso/cons_pcb.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "netstat.h"
+
+static void tprintstat __P((struct tp_stat *, int));
+static void isonetprint __P((struct sockaddr_iso *, int));
+static void hexprint __P((int, char *, char *));
+extern void inetprint __P((struct in_addr *, int, char *));
+
+/*
+ *	Dump esis stats
+ */
+void
+esis_stats(off, name)
+	u_long	off;
+	char	*name;
+{
+	struct esis_stat esis_stat;
+
+	if (off == 0 ||
+	    kread(off, (char *)&esis_stat, sizeof (struct esis_stat)))
+		return;
+	printf("%s:\n", name);
+	printf("\t%d esh sent, %d esh received\n", esis_stat.es_eshsent,
+		esis_stat.es_eshrcvd);
+	printf("\t%d ish sent, %d ish received\n", esis_stat.es_ishsent,
+		esis_stat.es_ishrcvd);
+	printf("\t%d rd sent, %d rd received\n", esis_stat.es_rdsent,
+		esis_stat.es_rdrcvd);
+	printf("\t%d pdus not sent due to insufficient memory\n",
+		esis_stat.es_nomem);
+	printf("\t%d pdus received with bad checksum\n", esis_stat.es_badcsum);
+	printf("\t%d pdus received with bad version number\n",
+		esis_stat.es_badvers);
+	printf("\t%d pdus received with bad type field\n", esis_stat.es_badtype);
+	printf("\t%d short pdus received\n", esis_stat.es_toosmall);
+}
+
+/*
+ * Dump clnp statistics structure.
+ */
+void
+clnp_stats(off, name)
+	u_long off;
+	char *name;
+{
+	struct clnp_stat clnp_stat;
+
+	if (off == 0 ||
+	    kread(off, (char *)&clnp_stat, sizeof (clnp_stat)))
+		return;
+
+	printf("%s:\n\t%d total packets sent\n", name, clnp_stat.cns_sent);
+	printf("\t%d total fragments sent\n", clnp_stat.cns_fragments);
+	printf("\t%d total packets received\n", clnp_stat.cns_total);
+	printf("\t%d with fixed part of header too small\n",
+		clnp_stat.cns_toosmall);
+	printf("\t%d with header length not reasonable\n", clnp_stat.cns_badhlen);
+	printf("\t%d incorrect checksum%s\n",
+		clnp_stat.cns_badcsum, plural(clnp_stat.cns_badcsum));
+	printf("\t%d with unreasonable address lengths\n", clnp_stat.cns_badaddr);
+	printf("\t%d with forgotten segmentation information\n",
+		clnp_stat.cns_noseg);
+	printf("\t%d with an incorrect protocol identifier\n", clnp_stat.cns_noproto);
+	printf("\t%d with an incorrect version\n", clnp_stat.cns_badvers);
+	printf("\t%d dropped because the ttl has expired\n",
+		clnp_stat.cns_ttlexpired);
+	printf("\t%d clnp cache misses\n", clnp_stat.cns_cachemiss);
+	printf("\t%d clnp congestion experience bits set\n",
+		clnp_stat.cns_congest_set);
+	printf("\t%d clnp congestion experience bits received\n",
+		clnp_stat.cns_congest_rcvd);
+}
+/*
+ * Dump CLTP statistics structure.
+ */
+void
+cltp_stats(off, name)
+	u_long off;
+	char *name;
+{
+	struct cltpstat cltpstat;
+
+	if (off == 0 ||
+	    kread(off, (char *)&cltpstat, sizeof (cltpstat)))
+		return;
+	printf("%s:\n\t%u incomplete header%s\n", name,
+		cltpstat.cltps_hdrops, plural(cltpstat.cltps_hdrops));
+	printf("\t%u bad data length field%s\n",
+		cltpstat.cltps_badlen, plural(cltpstat.cltps_badlen));
+	printf("\t%u bad checksum%s\n",
+		cltpstat.cltps_badsum, plural(cltpstat.cltps_badsum));
+}
+
+struct	tp_pcb tpcb;
+struct	isopcb isopcb;
+static struct	socket sockb;
+union	{
+	struct sockaddr_iso	siso;
+	char	data[128];
+} laddr, faddr;
+#define kget(o, p) \
+	(kread((u_long)(o), (char *)&p, sizeof (p)))
+
+static	int first = 1;
+
+/*
+ * Print a summary of connections related to an Internet
+ * protocol.  For TP, also give state of connection.
+ * Listening processes (aflag) are suppressed unless the
+ * -a (all) flag is specified.
+ */
+void
+iso_protopr(off, name)
+	u_long off;
+	char *name;
+{
+	struct isopcb cb;
+	register struct isopcb *prev, *next;
+
+	if (off == 0) {
+		printf("%s control block: symbol not in namelist\n", name);
+		return;
+	}
+	if (strcmp(name, "tp") == 0) {
+		tp_protopr(off, name);
+		return;
+	}
+	if (kread(off, (char *)&cb, sizeof(cb)))
+		return;
+	isopcb = cb;
+	prev = (struct isopcb *)off;
+	if (isopcb.isop_next == (struct isopcb *)off)
+		return;
+	while (isopcb.isop_next != (struct isopcb *)off) {
+		next = isopcb.isop_next;
+		kget(next, isopcb);
+		if (isopcb.isop_prev != prev) {
+			printf("prev 0x%x next 0x%x isop_prev 0x%x isop_next 0x%x???\n",
+				prev, next, isopcb.isop_prev, isopcb.isop_next);
+			break;
+		}
+		kget(isopcb.isop_socket, sockb);
+		iso_protopr1((u_long)next, 0);
+		putchar('\n');
+		prev = next;
+	}
+}
+
+void
+iso_protopr1(kern_addr, istp)
+	u_long kern_addr;
+	int istp;
+{
+	if (first) {
+		printf("Active ISO net connections");
+		if (aflag)
+			printf(" (including servers)");
+		putchar('\n');
+		if (Aflag)
+			printf("%-8.8s ", "PCB");
+		printf(Aflag ?
+			"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
+			"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
+			"Proto", "Recv-Q", "Send-Q",
+			"Local Address", "Foreign Address", "(state)");
+		first = 0;
+	}
+	if (Aflag)
+			printf("%8x ",
+					(sockb.so_pcb ? (void *)sockb.so_pcb : (void *)kern_addr));
+	printf("%-5.5s %6d %6d ", "tp", sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc);
+	if (istp && tpcb.tp_lsuffixlen) {
+			hexprint(tpcb.tp_lsuffixlen, tpcb.tp_lsuffix, "()");
+			printf("\t");
+	} else if (isopcb.isop_laddr == 0)
+			printf("*.*\t");
+	else {
+			if ((char *)isopcb.isop_laddr == ((char *)kern_addr) +
+					_offsetof(struct isopcb, isop_sladdr))
+					laddr.siso = isopcb.isop_sladdr;
+			else
+					kget(isopcb.isop_laddr, laddr);
+			isonetprint((struct sockaddr_iso *)&laddr, 1);
+	}
+	if (istp && tpcb.tp_fsuffixlen) {
+			hexprint(tpcb.tp_fsuffixlen, tpcb.tp_fsuffix, "()");
+			printf("\t");
+	} else if (isopcb.isop_faddr == 0)
+		printf("*.*\t");
+	else {
+		if ((char *)isopcb.isop_faddr == ((char *)kern_addr) +
+			_offsetof(struct isopcb, isop_sfaddr))
+			faddr.siso = isopcb.isop_sfaddr;
+		else
+			kget(isopcb.isop_faddr, faddr);
+		isonetprint((struct sockaddr_iso *)&faddr, 0);
+	}
+}
+
+void
+tp_protopr(off, name)
+	u_long off;
+	char *name;
+{
+	extern char *tp_sstring[];
+	struct tp_ref *tpr, *tpr_base;
+	struct tp_refinfo tpkerninfo;
+	int size;
+
+	kget(off, tpkerninfo);
+	size = tpkerninfo.tpr_size * sizeof (*tpr);
+	tpr_base = (struct tp_ref *)malloc(size);
+	if (tpr_base == 0)
+		return;
+	kread((u_long)(tpkerninfo.tpr_base), (char *)tpr_base, size);
+	for (tpr = tpr_base; tpr < tpr_base + tpkerninfo.tpr_size; tpr++) {
+		if (tpr->tpr_pcb == 0)
+			continue;
+		kget(tpr->tpr_pcb, tpcb);
+		if (tpcb.tp_state == ST_ERROR)
+			printf("undefined tpcb state: 0x%x\n", tpr->tpr_pcb);
+		if (!aflag &&
+			(tpcb.tp_state == TP_LISTENING ||
+			 tpcb.tp_state == TP_CLOSED ||
+			 tpcb.tp_state == TP_REFWAIT)) {
+			continue;
+		}
+		kget(tpcb.tp_sock, sockb);
+		if (tpcb.tp_npcb) switch(tpcb.tp_netservice) {
+			case IN_CLNS:
+				tp_inproto((u_long)tpkerninfo.tpr_base);
+				break;
+			default:
+				kget(tpcb.tp_npcb, isopcb);
+				iso_protopr1((u_long)tpcb.tp_npcb, 1);
+				break;
+		}
+		if (tpcb.tp_state >= tp_NSTATES)
+			printf(" %d", tpcb.tp_state);
+		else
+			printf(" %-12.12s", tp_sstring[tpcb.tp_state]);
+		putchar('\n');
+	}
+}
+
+void
+tp_inproto(pcb)
+	u_long pcb;
+{
+	struct inpcb inpcb;
+	kget(tpcb.tp_npcb, inpcb);
+	if (!aflag && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY)
+		return;
+	if (Aflag)
+		printf("%8x ", pcb);
+	printf("%-5.5s %6d %6d ", "tpip",
+	    sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc);
+	inetprint(&inpcb.inp_laddr, inpcb.inp_lport, "tp");
+	inetprint(&inpcb.inp_faddr, inpcb.inp_fport, "tp");
+}
+
+/*
+ * Pretty print an iso address (net address + port).
+ * If the nflag was specified, use numbers instead of names.
+ */
+
+#ifdef notdef
+char *
+isonetname(iso)
+	register struct iso_addr *iso;
+{
+	struct sockaddr_iso sa;
+	struct iso_hostent *ihe = 0;
+	struct iso_hostent *iso_gethostentrybyaddr();
+	struct iso_hostent *iso_getserventrybytsel();
+	struct iso_hostent Ihe;
+	static char line[80];
+
+	bzero(line, sizeof(line));
+	if( iso->isoa_afi ) {
+		sa.siso_family = AF_ISO;
+		sa.siso_addr = *iso;
+		sa.siso_tsuffix = 0;
+
+		if (!nflag )
+			ihe = iso_gethostentrybyaddr( &sa, 0, 0 );
+		if( ihe ) {
+			Ihe = *ihe;
+			ihe = &Ihe;
+			sprintf(line, "%s", ihe->isoh_hname);
+		} else {
+			sprintf(line, "%s", iso_ntoa(iso));
+		}
+	} else {
+		sprintf(line, "*");
+	}
+	return line;
+}
+
+static void
+isonetprint(iso, sufx, sufxlen, islocal)
+	register struct iso_addr *iso;
+	char *sufx;
+	u_short	sufxlen;
+	int islocal;
+{
+	struct iso_hostent *iso_getserventrybytsel(), *ihe;
+	struct iso_hostent Ihe;
+	char *line, *cp;
+	int Alen = Aflag?18:22;
+
+	line =  isonetname(iso);
+	cp = index(line, '\0');
+	ihe = (struct iso_hostent *)0;
+
+	if( islocal )
+		islocal = 20;
+	else
+		islocal = 22 + Alen;
+
+	if(Aflag)
+		islocal += 10 ;
+
+	if(!nflag) {
+		if( (cp -line)>10 ) {
+			cp = line+10;
+			bzero(cp, sizeof(line)-10);
+		}
+	}
+
+	*cp++ = '.';
+	if(sufxlen) {
+		if( !Aflag && !nflag && (ihe=iso_getserventrybytsel(sufx, sufxlen))) {
+			Ihe = *ihe;
+			ihe = &Ihe;
+		}
+		if( ihe && (strlen(ihe->isoh_aname)>0) ) {
+			sprintf(cp, "%s", ihe->isoh_aname);
+		} else  {
+			iso_sprinttsel(cp, sufx, sufxlen);
+		}
+	} else
+		sprintf(cp, "*");
+	/*
+	fprintf(stdout, Aflag?" %-18.18s":" %-22.22s", line);
+	*/
+
+	if( strlen(line) > Alen ) {
+		fprintf(stdout, " %s", line);
+		fprintf(stdout, "\n %*.s", islocal+Alen," ");
+	} else {
+		fprintf(stdout, " %-*.*s", Alen, Alen,line);
+	}
+}
+#endif
+
+#ifdef notdef
+static void
+x25_protopr(off, name)
+	u_long off;
+	char *name;
+{
+	static char *xpcb_states[] = {
+		"CLOSED",
+		"LISTENING",
+		"CLOSING",
+		"CONNECTING",
+		"ACKWAIT",
+		"OPEN",
+	};
+	register struct isopcb *prev, *next;
+	struct x25_pcb xpcb;
+
+	if (off == 0) {
+		printf("%s control block: symbol not in namelist\n", name);
+		return;
+	}
+	kread(off, &xpcb, sizeof (struct x25_pcb));
+	prev = (struct isopcb *)off;
+	if (xpcb.x_next == (struct isopcb *)off)
+		return;
+	while (xpcb.x_next != (struct isopcb *)off) {
+		next = isopcb.isop_next;
+		kread((u_long)next, &xpcb, sizeof (struct x25_pcb));
+		if (xpcb.x_prev != prev) {
+			printf("???\n");
+			break;
+		}
+		kread((u_long)xpcb.x_socket, &sockb, sizeof (sockb));
+
+		if (!aflag &&
+			xpcb.x_state == LISTENING ||
+			xpcb.x_state == TP_CLOSED ) {
+			prev = next;
+			continue;
+		}
+		if (first) {
+			printf("Active X25 net connections");
+			if (aflag)
+				printf(" (including servers)");
+			putchar('\n');
+			if (Aflag)
+				printf("%-8.8s ", "PCB");
+			printf(Aflag ?
+				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
+				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
+				"Proto", "Recv-Q", "Send-Q",
+				"Local Address", "Foreign Address", "(state)");
+			first = 0;
+		}
+		printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc,
+			sockb.so_snd.sb_cc);
+		isonetprint(&xpcb.x_laddr.siso_addr, &xpcb.x_lport,
+			sizeof(xpcb.x_lport), 1);
+		isonetprint(&xpcb.x_faddr.siso_addr, &xpcb.x_fport,
+			sizeof(xpcb.x_lport), 0);
+		if (xpcb.x_state < 0 || xpcb.x_state >= x25_NSTATES)
+			printf(" 0x0x0x0x0x0x0x0x0x%x", xpcb.x_state);
+		else
+			printf(" %-12.12s", xpcb_states[xpcb.x_state]);
+		putchar('\n');
+		prev = next;
+	}
+}
+#endif
+
+struct	tp_stat tp_stat;
+
+void
+tp_stats(off, name)
+	caddr_t off, name;
+{
+	if (off == 0) {
+		printf("TP not configured\n\n");
+		return;
+	}
+	printf("%s:\n", name);
+	kget(off, tp_stat);
+	tprintstat(&tp_stat, 8);
+}
+
+#define OUT stdout
+
+static void
+tprintstat(s, indent)
+	register struct tp_stat *s;
+	int indent;
+{
+	fprintf(OUT,
+		"%*sReceiving:\n",indent," ");
+	fprintf(OUT,
+		"\t%*s%d variable parameter%s ignored\n", indent," ",
+		s->ts_param_ignored ,plural(s->ts_param_ignored));
+	fprintf(OUT,
+		"\t%*s%d invalid parameter code%s\n", indent, " ",
+		s->ts_inv_pcode ,plural(s->ts_inv_pcode));
+	fprintf(OUT,
+		"\t%*s%d invalid parameter value%s\n", indent, " ",
+		s->ts_inv_pval ,plural(s->ts_inv_pval));
+	fprintf(OUT,
+		"\t%*s%d invalid dutype%s\n", indent, " ",
+		s->ts_inv_dutype ,plural(s->ts_inv_dutype));
+	fprintf(OUT,
+		"\t%*s%d negotiation failure%s\n", indent, " ",
+		s->ts_negotfailed ,plural(s->ts_negotfailed));
+	fprintf(OUT,
+		"\t%*s%d invalid destination reference%s\n", indent, " ",
+		s->ts_inv_dref ,plural(s->ts_inv_dref));
+	fprintf(OUT,
+		"\t%*s%d invalid suffix parameter%s\n", indent, " ",
+		s->ts_inv_sufx ,plural(s->ts_inv_sufx));
+	fprintf(OUT,
+		"\t%*s%d invalid length\n",indent, " ", s->ts_inv_length);
+	fprintf(OUT,
+		"\t%*s%d invalid checksum%s\n", indent, " ",
+		s->ts_bad_csum ,plural(s->ts_bad_csum));
+	fprintf(OUT,
+		"\t%*s%d DT%s out of order\n", indent, " ",
+		s->ts_dt_ooo ,plural(s->ts_dt_ooo));
+	fprintf(OUT,
+		"\t%*s%d DT%s not in window\n", indent, " ",
+		s->ts_dt_niw ,plural(s->ts_dt_niw));
+	fprintf(OUT,
+		"\t%*s%d duplicate DT%s\n", indent, " ",
+		s->ts_dt_dup ,plural(s->ts_dt_dup));
+	fprintf(OUT,
+			"\t%*s%d XPD%s not in window\n", indent, " ",
+			s->ts_xpd_niw ,plural(s->ts_xpd_niw));
+		fprintf(OUT,
+			"\t%*s%d XPD%s w/o credit to stash\n", indent, " ",
+		s->ts_xpd_dup ,plural(s->ts_xpd_dup));
+	fprintf(OUT,
+		"\t%*s%d time%s local credit reneged\n", indent, " ",
+		s->ts_lcdt_reduced ,plural(s->ts_lcdt_reduced));
+	fprintf(OUT,
+		"\t%*s%d concatenated TPDU%s\n", indent, " ",
+		s->ts_concat_rcvd ,plural(s->ts_concat_rcvd));
+	fprintf(OUT,
+		"%*sSending:\n", indent, " ");
+	fprintf(OUT,
+		"\t%*s%d XPD mark%s discarded\n", indent, " ",
+		s->ts_xpdmark_del ,plural(s->ts_xpdmark_del));
+	fprintf(OUT,
+		"\t%*sXPD stopped data flow %d time%s\n", indent, " ",
+		s->ts_xpd_intheway ,plural(s->ts_xpd_intheway));
+	fprintf(OUT,
+		"\t%*s%d time%s foreign window closed\n", indent, " ",
+		s->ts_zfcdt ,plural(s->ts_zfcdt));
+	fprintf(OUT,
+		"%*sMiscellaneous:\n", indent, " ");
+	fprintf(OUT,
+		"\t%*s%d small mbuf%s\n", indent, " ",
+		s->ts_mb_small ,plural(s->ts_mb_small));
+	fprintf(OUT,
+		"\t%*s%d cluster%s\n", indent, " ",
+		s->ts_mb_cluster, plural(s->ts_mb_cluster));
+	fprintf(OUT,
+		"\t%*s%d source quench \n",indent, " ",
+		s->ts_quench);
+	fprintf(OUT,
+		"\t%*s%d dec bit%s\n", indent, " ",
+		s->ts_rcvdecbit, plural(s->ts_rcvdecbit));
+	fprintf(OUT,
+		"\t%*sM:L ( M mbuf chains of length L)\n", indent, " ");
+	{
+		register int j;
+
+		fprintf(OUT, "\t%*s%d: over 16\n", indent, " ",
+		s->ts_mb_len_distr[0]);
+		for( j=1; j<=8; j++) {
+			fprintf(OUT,
+				"\t%*s%d: %d\t\t%d: %d\n", indent, " ",
+				s->ts_mb_len_distr[j],j,
+				s->ts_mb_len_distr[j<<1],j<<1
+				);
+		}
+	}
+	fprintf(OUT,
+		"\t%*s%d EOT rcvd\n",  indent, " ", s->ts_eot_input);
+	fprintf(OUT,
+		"\t%*s%d EOT sent\n",  indent, " ", s->ts_EOT_sent);
+	fprintf(OUT,
+		"\t%*s%d EOT indication%s\n",  indent, " ",
+		s->ts_eot_user ,plural(s->ts_eot_user));
+
+	fprintf(OUT,
+		"%*sConnections:\n", indent, " ");
+	fprintf(OUT,
+		"\t%*s%d connection%s used extended format\n",  indent, " ",
+		s->ts_xtd_fmt ,plural(s->ts_xtd_fmt));
+	fprintf(OUT,
+		"\t%*s%d connection%s allowed transport expedited data\n",  indent, " ",
+		s->ts_use_txpd ,plural(s->ts_use_txpd));
+	fprintf(OUT,
+		"\t%*s%d connection%s turned off checksumming\n",  indent, " ",
+		s->ts_csum_off ,plural(s->ts_csum_off));
+	fprintf(OUT,
+		"\t%*s%d connection%s dropped due to retrans limit\n",  indent, " ",
+		s->ts_conn_gaveup ,plural(s->ts_conn_gaveup));
+	fprintf(OUT,
+		"\t%*s%d tp 4 connection%s\n",  indent, " ",
+		s->ts_tp4_conn ,plural(s->ts_tp4_conn));
+	fprintf(OUT,
+		"\t%*s%d tp 0 connection%s\n",  indent, " ",
+		s->ts_tp0_conn ,plural(s->ts_tp0_conn));
+    {
+		register int j;
+		static char *name[]= {
+			"~LOCAL, PDN",
+			"~LOCAL,~PDN",
+			" LOCAL,~PDN",
+			" LOCAL, PDN"
+		};
+
+		fprintf(OUT,
+			"\n%*sRound trip times, listed in ticks:\n", indent, " ");
+		fprintf(OUT,
+			"\t%*s%11.11s  %12.12s | %12.12s | %s\n", indent, " ",
+				"Category",
+				"Smoothed avg", "Deviation", "Deviation/Avg");
+		for (j = 0; j <= 3; j++) {
+			fprintf(OUT,
+				"\t%*s%11.11s: %-11d | %-11d | %-11d | %-11d\n", indent, " ",
+				name[j],
+				s->ts_rtt[j],
+				s->ts_rtt[j],
+				s->ts_rtv[j],
+				s->ts_rtv[j]);
+		}
+	}
+	fprintf(OUT,
+"\n%*sTpdus RECVD [%d valid, %3.6f %% of total (%d); %d dropped]\n",indent," ",
+		s->ts_tpdu_rcvd ,
+		((s->ts_pkt_rcvd > 0) ?
+			((100 * (float)s->ts_tpdu_rcvd)/(float)s->ts_pkt_rcvd)
+			: 0),
+		s->ts_pkt_rcvd,
+		s->ts_recv_drop );
+
+	fprintf(OUT,
+		"\t%*sDT  %6d   AK  %6d   DR  %4d   CR  %4d \n", indent, " ",
+		s->ts_DT_rcvd, s->ts_AK_rcvd, s->ts_DR_rcvd, s->ts_CR_rcvd);
+	fprintf(OUT,
+		"\t%*sXPD %6d   XAK %6d   DC  %4d   CC  %4d   ER  %4d\n",  indent, " ",
+		s->ts_XPD_rcvd, s->ts_XAK_rcvd, s->ts_DC_rcvd, s->ts_CC_rcvd,
+		s->ts_ER_rcvd);
+	fprintf(OUT,
+		"\n%*sTpdus SENT [%d total, %d dropped]\n",  indent, " ",
+		s->ts_tpdu_sent, s->ts_send_drop);
+
+	fprintf(OUT,
+		"\t%*sDT  %6d   AK  %6d   DR  %4d   CR  %4d \n", indent, " ",
+		s->ts_DT_sent, s->ts_AK_sent, s->ts_DR_sent, s->ts_CR_sent);
+	fprintf(OUT,
+		"\t%*sXPD %6d   XAK %6d   DC  %4d   CC  %4d   ER  %4d\n",  indent, " ",
+		s->ts_XPD_sent, s->ts_XAK_sent, s->ts_DC_sent, s->ts_CC_sent,
+		s->ts_ER_sent);
+
+	fprintf(OUT,
+		"\n%*sRetransmissions:\n", indent, " ");
+#define PERCENT(X,Y) (((Y)>0)?((100 *(float)(X)) / (float) (Y)):0)
+
+	fprintf(OUT,
+	"\t%*sCR  %6d   CC  %6d   DR  %6d \n", indent, " ",
+		s->ts_retrans_cr, s->ts_retrans_cc, s->ts_retrans_dr);
+	fprintf(OUT,
+	"\t%*sDT  %6d (%5.2f%%)\n", indent, " ",
+		s->ts_retrans_dt,
+		PERCENT(s->ts_retrans_dt, s->ts_DT_sent));
+	fprintf(OUT,
+	"\t%*sXPD %6d (%5.2f%%)\n",  indent, " ",
+		s->ts_retrans_xpd,
+		PERCENT(s->ts_retrans_xpd, s->ts_XPD_sent));
+
+
+	fprintf(OUT,
+		"\n%*sE Timers: [%6d ticks]\n", indent, " ", s->ts_Eticks);
+	fprintf(OUT,
+		"%*s%6d timer%s set \t%6d timer%s expired \t%6d timer%s cancelled\n",indent, " ",
+		s->ts_Eset ,plural(s->ts_Eset),
+		s->ts_Eexpired ,plural(s->ts_Eexpired),
+		s->ts_Ecan_act ,plural(s->ts_Ecan_act));
+
+	fprintf(OUT,
+		"\n%*sC Timers: [%6d ticks]\n",  indent, " ",s->ts_Cticks);
+	fprintf(OUT,
+	"%*s%6d timer%s set \t%6d timer%s expired \t%6d timer%s cancelled\n",
+		indent, " ",
+		s->ts_Cset ,plural(s->ts_Cset),
+		s->ts_Cexpired ,plural(s->ts_Cexpired),
+		s->ts_Ccan_act ,plural(s->ts_Ccan_act));
+	fprintf(OUT,
+		"%*s%6d inactive timer%s cancelled\n", indent, " ",
+		s->ts_Ccan_inact ,plural(s->ts_Ccan_inact));
+
+	fprintf(OUT,
+		"\n%*sPathological debugging activity:\n", indent, " ");
+	fprintf(OUT,
+		"\t%*s%6d CC%s sent to zero dref\n", indent, " ",
+		s->ts_zdebug ,plural(s->ts_zdebug));
+	/* SAME LINE AS ABOVE */
+	fprintf(OUT,
+		"\t%*s%6d random DT%s dropped\n", indent, " ",
+		s->ts_ydebug ,plural(s->ts_ydebug));
+	fprintf(OUT,
+		"\t%*s%6d illegally large XPD TPDU%s\n", indent, " ",
+		s->ts_vdebug ,plural(s->ts_vdebug));
+	fprintf(OUT,
+		"\t%*s%6d faked reneging of cdt\n", indent, " ",
+		s->ts_ldebug );
+
+	fprintf(OUT,
+		"\n%*sACK reasons:\n", indent, " ");
+	fprintf(OUT, "\t%*s%6d not acked immediately\n", indent, " ",
+		s->ts_ackreason[_ACK_DONT_] );
+	fprintf(OUT, "\t%*s%6d strategy==each\n", indent, " ",
+		s->ts_ackreason[_ACK_STRAT_EACH_] );
+	fprintf(OUT, "\t%*s%6d strategy==fullwindow\n", indent, " ",
+		s->ts_ackreason[_ACK_STRAT_FULLWIN_] );
+	fprintf(OUT, "\t%*s%6d duplicate DT\n", indent, " ",
+		s->ts_ackreason[_ACK_DUP_] );
+	fprintf(OUT, "\t%*s%6d EOTSDU\n", indent, " ",
+		s->ts_ackreason[_ACK_EOT_] );
+	fprintf(OUT, "\t%*s%6d reordered DT\n", indent, " ",
+		s->ts_ackreason[_ACK_REORDER_] );
+	fprintf(OUT, "\t%*s%6d user rcvd\n", indent, " ",
+		s->ts_ackreason[_ACK_USRRCV_] );
+	fprintf(OUT, "\t%*s%6d fcc reqd\n", indent, " ",
+		s->ts_ackreason[_ACK_FCC_] );
+}
+#ifndef SSEL
+#define SSEL(s) ((s)->siso_tlen + TSEL(s))
+#define PSEL(s) ((s)->siso_slen + SSEL(s))
+#endif
+
+static void
+isonetprint(siso, islocal)
+	register struct sockaddr_iso *siso;
+	int islocal;
+{
+	hexprint(siso->siso_nlen, siso->siso_addr.isoa_genaddr, "{}");
+	if (siso->siso_tlen || siso->siso_slen || siso->siso_plen)
+		hexprint(siso->siso_tlen, TSEL(siso), "()");
+	if (siso->siso_slen || siso->siso_plen)
+		hexprint(siso->siso_slen, SSEL(siso), "[]");
+	if (siso->siso_plen)
+		hexprint(siso->siso_plen, PSEL(siso), "<>");
+	putchar(' ');
+}
+
+static char hexlist[] = "0123456789abcdef", obuf[128];
+
+static void
+hexprint(n, buf, delim)
+	int n;
+	char *buf, *delim;
+{
+	register u_char *in = (u_char *)buf, *top = in + n;
+	register char *out = obuf;
+	register int i;
+
+	if (n == 0)
+		return;
+	while (in < top) {
+		i = *in++;
+		*out++ = '.';
+		if (i > 0xf) {
+			out[1] = hexlist[i & 0xf];
+			i >>= 4;
+			out[0] = hexlist[i];
+			out += 2;
+		} else
+			*out++ = hexlist[i];
+	}
+	*obuf = *delim; *out++ = delim[1]; *out = 0;
+	printf("%s", obuf);
+}
diff --git a/netstat.tproj/main.c b/netstat.tproj/main.c
new file mode 100644
index 0000000..8ca3a72
--- /dev/null
+++ b/netstat.tproj/main.c
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char const copyright[] =
+"@(#) Copyright (c) 1983, 1988, 1993\n\
+	Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)main.c	8.4 (Berkeley) 3/1/94";
+#endif
+static const char rcsid[] =
+	"$Id: main.c,v 1.2 2000/06/16 03:37:29 lindak Exp $";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <kvm.h>
+#include <limits.h>
+#include <netdb.h>
+#include <nlist.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "netstat.h"
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $Id: main.c,v 1.2 2000/06/16 03:37:29 lindak Exp $
+ *
+ */
+
+
+static struct nlist nl[] = {
+#define	N_IFNET		0
+	{ "_ifnet" },
+#define	N_IMP		1
+	{ "_imp_softc" },
+#define	N_RTSTAT	2
+	{ "_rtstat" },
+#define	N_UNIXSW	3
+	{ "_localsw" },
+#define N_IDP		4
+	{ "_nspcb"},
+#define N_IDPSTAT	5
+	{ "_idpstat"},
+#define N_SPPSTAT	6
+	{ "_spp_istat"},
+#define N_NSERR		7
+	{ "_ns_errstat"},
+#define	N_CLNPSTAT	8
+	{ "_clnp_stat"},
+#define	IN_NOTUSED	9
+	{ "_tp_inpcb" },
+#define	ISO_TP		10
+	{ "_tp_refinfo" },
+#define	N_TPSTAT	11
+	{ "_tp_stat" },
+#define	N_ESISSTAT	12
+	{ "_esis_stat"},
+#define N_NIMP		13
+	{ "_nimp"},
+#define N_RTREE		14
+	{ "_rt_tables"},
+#define N_CLTP		15
+	{ "_cltb"},
+#define N_CLTPSTAT	16
+	{ "_cltpstat"},
+#define	N_NFILE		17
+	{ "_nfile" },
+#define	N_FILE		18
+	{ "_file" },
+#define N_MRTSTAT	19
+	{ "_mrtstat" },
+#define N_MFCTABLE	20
+	{ "_mfctable" },
+#define N_VIFTABLE	21
+	{ "_viftable" },
+#define N_IPX		22
+	{ "_ipxpcb"},
+#define N_IPXSTAT	23
+	{ "_ipxstat"},
+#define N_SPXSTAT	24
+	{ "_spx_istat"},
+#define N_DDPSTAT	25
+	{ "_ddpstat"},
+#define N_DDPCB		26
+	{ "_ddpcb"},
+#define N_MBSTAT	27
+	{"_mbstat"},
+	{ "" },
+};
+
+
+
+struct protox {
+	u_char	pr_index;		/* index into nlist of cb head */
+	u_char	pr_sindex;		/* index into nlist of stat block */
+	u_char	pr_wanted;		/* 1 if wanted, 0 otherwise */
+	void	(*pr_cblocks)();	/* control blocks printing routine */
+	void	(*pr_stats)();		/* statistics printing routine */
+	char	*pr_name;		/* well-known name */
+	int	pr_usesysctl;		/* true if we use sysctl, not kvm */
+} protox[] = {
+	{ -1,		-1,		1,	protopr,
+	  tcp_stats,	"tcp",		IPPROTO_TCP },
+	{ -1,		-1,		1,	protopr,
+	  udp_stats,	"udp",		IPPROTO_UDP },
+	{ -1,		-1,		1,	protopr,
+	  NULL,		"divert",	IPPROTO_DIVERT },
+	{ -1,		-1,		1,	protopr,
+	  ip_stats,	"ip",		IPPROTO_RAW },
+	{ -1,		-1,		1,	protopr,
+	  icmp_stats,	"icmp",		IPPROTO_ICMP },
+	{ -1,		-1,		1,	protopr,
+	  igmp_stats,	"igmp",		IPPROTO_IGMP },
+	{ -1,		-1,		0,	0,
+	  0,		0 }
+};
+
+#ifdef UNIX_ATALK
+struct protox atalkprotox[] = {
+	{ N_DDPCB,	N_DDPSTAT,	1,	atalkprotopr,
+	  ddp_stats,	"ddp" },
+	{ -1,		-1,		0,	0,
+	  0,		0 }
+};
+#endif
+
+#ifdef IPX
+struct protox ipxprotox[] = {
+	{ N_IPX,	N_IPXSTAT,	1,	ipxprotopr,
+	  ipx_stats,	"ipx",		0 },
+	{ N_IPX,	N_SPXSTAT,	1,	ipxprotopr,
+	  spx_stats,	"spx",		0 },
+	{ -1,		-1,		0,	0,
+	  0,		0,		0 }
+};
+#endif
+
+#ifdef NS
+struct protox nsprotox[] = {
+	{ N_IDP,	N_IDPSTAT,	1,	nsprotopr,
+	  idp_stats,	"idp" },
+	{ N_IDP,	N_SPPSTAT,	1,	nsprotopr,
+	  spp_stats,	"spp" },
+	{ -1,		N_NSERR,	1,	0,
+	  nserr_stats,	"ns_err" },
+	{ -1,		-1,		0,	0,
+	  0,		0 }
+};
+#endif
+
+#ifdef ISO
+struct protox isoprotox[] = {
+	{ ISO_TP,	N_TPSTAT,	1,	iso_protopr,
+	  tp_stats,	"tp" },
+	{ N_CLTP,	N_CLTPSTAT,	1,	iso_protopr,
+	  cltp_stats,	"cltp" },
+	{ -1,		N_CLNPSTAT,	1,	 0,
+	  clnp_stats,	"clnp"},
+	{ -1,		N_ESISSTAT,	1,	 0,
+	  esis_stats,	"esis"},
+	{ -1,		-1,		0,	0,
+	  0,		0 }
+};
+#endif
+
+struct protox *protoprotox[] = { protox, 
+
+#ifdef IPX
+ipxprotox, 
+#endif
+
+#ifdef UNIX_ATALK
+atalkprotox,
+#endif
+
+#ifdef NS
+					 nsprotox, 
+#endif
+#ifdef ISO
+					 isoprotox, 
+#endif
+					 NULL };
+
+static void printproto __P((struct protox *, char *));
+static void usage __P((void));
+static struct protox *name2protox __P((char *));
+static struct protox *knownname __P((char *));
+
+static kvm_t *kvmd;
+char *nlistf = NULL, *memf = NULL;
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register struct protoent *p;
+	register struct protox *tp;	/* for printing cblocks & stats */
+	int ch;
+
+	af = AF_UNSPEC;
+
+	while ((ch = getopt(argc, argv, "Aabdf:ghI:iM:mN:np:rstuw:")) != -1)
+		switch(ch) {
+		case 'A':
+			Aflag = 1;
+			break;
+		case 'a':
+			aflag = 1;
+			break;
+		case 'b':
+			bflag = 1;
+			break;
+		case 'd':
+			dflag = 1;
+			break;
+		case 'f':
+#ifdef NS
+			if (strcmp(optarg, "ns") == 0)
+				af = AF_NS;
+			else
+#endif
+			if (strcmp(optarg, "ipx") == 0)
+				af = AF_IPX;
+			else if (strcmp(optarg, "inet") == 0)
+				af = AF_INET;
+			else if (strcmp(optarg, "unix") == 0)
+				af = AF_UNIX;
+			else if (strcmp(optarg, "local") == 0)
+				af = AF_LOCAL;
+			else if (strcmp(optarg, "atalk") == 0)
+				af = AF_APPLETALK;
+#ifdef ISO
+			else if (strcmp(optarg, "iso") == 0)
+				af = AF_ISO;
+#endif
+			else {
+				errx(1, "%s: unknown address family", optarg);
+			}
+			break;
+		case 'g':
+			gflag = 1;
+			break;
+		case 'I': {
+			char *cp;
+
+			iflag = 1;
+			for (cp = interface = optarg; isalpha(*cp); cp++)
+				continue;
+			unit = atoi(cp);
+			break;
+		}
+		case 'i':
+			iflag = 1;
+			break;
+		case 'M':
+			memf = optarg;
+			break;
+		case 'm':
+			mflag = 1;
+			break;
+		case 'N':
+			nlistf = optarg;
+			break;
+		case 'n':
+			nflag = 1;
+			break;
+		case 'p':
+			if ((tp = name2protox(optarg)) == NULL) {
+				errx(1, 
+				     "%s: unknown or uninstrumented protocol",
+				     optarg);
+			}
+			pflag = 1;
+			break;
+		case 'r':
+			rflag = 1;
+			break;
+		case 's':
+			++sflag;
+			break;
+		case 't':
+			tflag = 1;
+			break;
+		case 'u':
+			af = AF_UNIX;
+			break;
+		case 'w':
+			interval = atoi(optarg);
+			iflag = 1;
+			break;
+		case '?':
+		default:
+			usage();
+		}
+	argv += optind;
+	argc -= optind;
+
+#define	BACKWARD_COMPATIBILITY
+#ifdef	BACKWARD_COMPATIBILITY
+	if (*argv) {
+		if (isdigit(**argv)) {
+			interval = atoi(*argv);
+			if (interval <= 0)
+				usage();
+			++argv;
+			iflag = 1;
+		}
+		if (*argv) {
+			nlistf = *argv;
+			if (*++argv)
+				memf = *argv;
+		}
+	}
+#endif
+
+	/*
+	 * Discard setgid privileges if not the running kernel so that bad
+	 * guys can't print interesting stuff from kernel memory.
+	 */
+	if (nlistf != NULL || memf != NULL)
+		setgid(getgid());
+
+	if (mflag) {
+		kread(0,0,0);
+		mbpr(nl[N_MBSTAT].n_value);
+		exit(0);
+	}
+	if (pflag) {
+		if (!tp->pr_stats) {
+			printf("%s: no stats routine\n", tp->pr_name);
+			exit(0);
+		}
+		if (tp->pr_usesysctl) {
+			(*tp->pr_stats)(tp->pr_usesysctl, tp->pr_name);
+		} else {
+			kread(0, 0, 0);
+			(*tp->pr_stats)(nl[tp->pr_sindex].n_value,
+					tp->pr_name);
+		}
+		exit(0);
+	}
+#if 0
+	/*
+	 * Keep file descriptors open to avoid overhead
+	 * of open/close on each call to get* routines.
+	 */
+	sethostent(1);
+	setnetent(1);
+#else
+	/*
+	 * This does not make sense any more with DNS being default over
+	 * the files.  Doing a setXXXXent(1) causes a tcp connection to be
+	 * used for the queries, which is slower.
+	 */
+#endif
+	if (iflag) {
+		kread(0, 0, 0);
+		intpr(interval, nl[N_IFNET].n_value);
+		exit(0);
+	}
+	if (rflag) {
+		kread(0, 0, 0);
+		if (sflag)
+			rt_stats(nl[N_RTSTAT].n_value);
+		else
+			routepr(nl[N_RTREE].n_value);
+		exit(0);
+	}
+	if (gflag) {
+		kread(0, 0, 0);
+		if (sflag)
+			mrt_stats(nl[N_MRTSTAT].n_value);
+		else
+			mroutepr(nl[N_MFCTABLE].n_value,
+			    nl[N_VIFTABLE].n_value);
+		exit(0);
+	}
+	if (af == AF_INET || af == AF_UNSPEC) {
+		setprotoent(1);
+		setservent(1);
+		/* ugh, this is O(MN) ... why do we do this? */
+		while ((p = getprotoent())) {
+			for (tp = protox; tp->pr_name; tp++)
+				if (strcmp(tp->pr_name, p->p_name) == 0)
+					break;
+			if (tp->pr_name == 0 || tp->pr_wanted == 0)
+				continue;
+			printproto(tp, p->p_name);
+		}
+		endprotoent();
+	}
+
+#ifdef IPX
+	if (af == AF_IPX || af == AF_UNSPEC) {
+		kread(0, 0, 0);
+		for (tp = ipxprotox; tp->pr_name; tp++)
+			printproto(tp, tp->pr_name);
+	}
+#endif
+#ifdef UNIX_ATALK
+	if (af == AF_APPLETALK || af == AF_UNSPEC)
+		for (tp = atalkprotox; tp->pr_name; tp++)
+			printproto(tp, tp->pr_name);
+#endif
+#ifdef NS
+	if (af == AF_NS || af == AF_UNSPEC)
+		for (tp = nsprotox; tp->pr_name; tp++)
+			printproto(tp, tp->pr_name);
+#endif
+#ifdef ISO
+	if (af == AF_ISO || af == AF_UNSPEC)
+		for (tp = isoprotox; tp->pr_name; tp++)
+			printproto(tp, tp->pr_name);
+#endif
+	if ((af == AF_UNIX || af == AF_LOCAL || af == AF_UNSPEC) && !sflag)
+		unixpr();
+	exit(0);
+}
+
+/*
+ * Print out protocol statistics or control blocks (per sflag).
+ * If the interface was not specifically requested, and the symbol
+ * is not in the namelist, ignore this one.
+ */
+static void
+printproto(tp, name)
+	register struct protox *tp;
+	char *name;
+{
+	void (*pr)();
+	u_long off;
+
+	if (sflag) {
+		pr = tp->pr_stats;
+		off = tp->pr_usesysctl ? tp->pr_usesysctl 
+			: nl[tp->pr_sindex].n_value;
+	} else {
+		pr = tp->pr_cblocks;
+		off = tp->pr_usesysctl ? tp->pr_usesysctl
+			: nl[tp->pr_index].n_value;
+	}
+	if (pr != NULL && (off || af != AF_UNSPEC))
+		(*pr)(off, name);
+}
+
+/*
+ * Read kernel memory, return 0 on success.
+ */
+int
+kread(addr, buf, size)
+	u_long addr;
+	char *buf;
+	int size;
+{
+	if (kvmd == 0) {
+		/*
+		 * XXX.
+		 */
+		kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf);
+		if (kvmd != NULL) {
+			if (kvm_nlist(kvmd, nl) < 0) {
+				if(nlistf)
+					errx(1, "%s: kvm_nlist: %s", nlistf,
+					     kvm_geterr(kvmd));
+				else
+					errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
+			}
+
+			if (nl[0].n_type == 0) {
+				if(nlistf)
+					errx(1, "%s: no namelist", nlistf);
+				else
+					errx(1, "no namelist");
+			}
+		} else {
+			warnx("kvm not available");
+			return(-1);
+		}
+	}
+	if (!buf)
+		return (0);
+	if (kvm_read(kvmd, addr, buf, size) != size) {
+		warnx("%s", kvm_geterr(kvmd));
+		return (-1);
+	}
+	return (0);
+}
+
+char *
+plural(n)
+	int n;
+{
+	return (n != 1 ? "s" : "");
+}
+
+char *
+plurales(n)
+	int n;
+{
+	return (n != 1 ? "es" : "");
+}
+
+/*
+ * Find the protox for the given "well-known" name.
+ */
+static struct protox *
+knownname(name)
+	char *name;
+{
+	struct protox **tpp, *tp;
+
+	for (tpp = protoprotox; *tpp; tpp++)
+		for (tp = *tpp; tp->pr_name; tp++)
+			if (strcmp(tp->pr_name, name) == 0)
+				return (tp);
+	return (NULL);
+}
+
+/*
+ * Find the protox corresponding to name.
+ */
+static struct protox *
+name2protox(name)
+	char *name;
+{
+	struct protox *tp;
+	char **alias;			/* alias from p->aliases */
+	struct protoent *p;
+
+	/*
+	 * Try to find the name in the list of "well-known" names. If that
+	 * fails, check if name is an alias for an Internet protocol.
+	 */
+	if ((tp = knownname(name)))
+		return (tp);
+
+	setprotoent(1);			/* make protocol lookup cheaper */
+	while ((p = getprotoent())) {
+		/* assert: name not same as p->name */
+		for (alias = p->p_aliases; *alias; alias++)
+			if (strcmp(name, *alias) == 0) {
+				endprotoent();
+				return (knownname(p->p_name));
+			}
+	}
+	endprotoent();
+	return (NULL);
+}
+
+static void
+usage()
+{
+	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
+"usage: netstat [-Aan] [-f address_family] [-M core] [-N system]",
+"       netstat [-bdghimnrs] [-f address_family] [-M core] [-N system]",
+"       netstat [-bdn] [-I interface] [-M core] [-N system] [-w wait]",
+"       netstat [-M core] [-N system] [-p protocol]");
+	exit(1);
+}
+
+void
+trimdomain(cp)
+	char *cp;
+{
+	static char domain[MAXHOSTNAMELEN + 1];
+	static int first = 1;
+	char *s;
+
+	if (first) {
+		first = 0;
+		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
+		    (s = strchr(domain, '.')))
+			(void) strcpy(domain, s + 1);
+		else
+			domain[0] = 0;
+	}
+
+	if (domain[0]) {
+		while ((cp = strchr(cp, '.'))) {
+			if (!strcasecmp(cp + 1, domain)) {
+				*cp = 0;	/* hit it */
+				break;
+			} else {
+				cp++;
+			}
+		}
+	}
+}
+
diff --git a/netstat.tproj/mbuf.c b/netstat.tproj/mbuf.c
new file mode 100644
index 0000000..95f81b4
--- /dev/null
+++ b/netstat.tproj/mbuf.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/mbuf.h>
+
+#include <stdio.h>
+#include "netstat.h"
+#include <netat/sysglue.h>    /* To get Appletalk message/mbuf types */
+
+#define	YES	1
+typedef int bool;
+
+struct	mbstat mbstat;
+
+static struct mbtypes {
+	int	mt_type;
+	char	*mt_name;
+} mbtypes[] = {
+	{ MT_DATA,	"data" },
+	{ MT_OOBDATA,	"oob data" },
+	{ MT_CONTROL,	"ancillary data" },
+	{ MT_HEADER,	"packet headers" },
+	{ MT_SOCKET,	"socket structures" },			/* XXX */
+	{ MT_PCB,	"protocol control blocks" },		/* XXX */
+	{ MT_RTABLE,	"routing table entries" },		/* XXX */
+	{ MT_HTABLE,	"IMP host table entries" },		/* XXX */
+	{ MT_ATABLE,	"address resolution tables" },
+	{ MT_FTABLE,	"fragment reassembly queue headers" },	/* XXX */
+	{ MT_SONAME,	"socket names and addresses" },
+	{ MT_SOOPTS,	"socket options" },
+	{ MT_RIGHTS,	"access rights" },
+	{ MT_IFADDR,	"interface addresses" },		/* XXX */
+	{ MSG_DATA,	"Appletalk data blocks"},
+	{ MSG_PROTO,	"Appletalk internal msgs"},
+	{ MSG_IOCTL,	"Appletalk ioctl requests"},
+	{ MSG_ERROR,	"Appletalk error indicators"},
+	{ MSG_HANGUP,	"Appletalk termination requests"},
+	{ MSG_IOCACK,	"Appletalk ioctl acks"},
+	{ MSG_IOCNAK,	"Appletalk ioctl failure indicators"},
+	{ MSG_CTL,	"Appletalk control msgs"},
+	{ 0, 0 }
+};
+
+int nmbtypes = sizeof(mbstat.m_mtypes) / sizeof(short);
+bool seen[256];			/* "have we seen this type yet?" */
+
+/*
+ * Print mbuf statistics.
+ */
+void
+mbpr(mbaddr)
+	u_long mbaddr;
+{
+	register int totmem, totfree, totmbufs;
+	register int i;
+	register struct mbtypes *mp;
+
+	if (nmbtypes != 256) {
+		fprintf(stderr,
+		    "netstat: unexpected change to mbstat; check source\n");
+		return;
+	}
+	if (mbaddr == 0) {
+		fprintf(stderr, "netstat: mbstat: symbol not in namelist\n");
+		return;
+	}
+	if (kread(mbaddr, (char *)&mbstat, sizeof (mbstat)))
+		return;
+
+	totmbufs = 0;
+	for (mp = mbtypes; mp->mt_name; mp++)
+		totmbufs += mbstat.m_mtypes[mp->mt_type];
+	printf("%u mbufs in use:\n", totmbufs);
+	for (mp = mbtypes; mp->mt_name; mp++)
+		if (mbstat.m_mtypes[mp->mt_type]) {
+			seen[mp->mt_type] = YES;
+			printf("\t%u mbufs allocated to %s\n",
+			    mbstat.m_mtypes[mp->mt_type], mp->mt_name);
+		}
+	seen[MT_FREE] = YES;
+	for (i = 0; i < nmbtypes; i++)
+		if (!seen[i] && mbstat.m_mtypes[i]) {
+			printf("\t%u mbufs allocated to <mbuf type %d>\n",
+			    mbstat.m_mtypes[i], i);
+		}
+	printf("%u/%u mbuf clusters in use\n",
+	       (unsigned int)(mbstat.m_clusters - mbstat.m_clfree),
+	       (unsigned int)mbstat.m_clusters);
+	totmem = totmbufs * MSIZE + mbstat.m_clusters * MCLBYTES;
+	totfree = mbstat.m_clfree * MCLBYTES;
+	printf("%u Kbytes allocated to network (%d%% in use)\n",
+		totmem / 1024, (totmem - totfree) * 100 / totmem);
+	printf("%u requests for memory denied\n",
+	       (unsigned int)mbstat.m_drops);
+	printf("%u requests for memory delayed\n", (unsigned int)mbstat.m_wait);
+	printf("%u calls to protocol drain routines\n",
+	       (unsigned int)mbstat.m_drain);
+}
diff --git a/netstat.tproj/mroute.c b/netstat.tproj/mroute.c
new file mode 100644
index 0000000..03e47cc
--- /dev/null
+++ b/netstat.tproj/mroute.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989 Stephen Deering
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Stephen Deering of Stanford University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)mroute.c	8.2 (Berkeley) 4/28/95
+ */
+
+/*
+ * Print DVMRP multicast routing structures and statistics.
+ *
+ * MROUTING 1.0
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/mbuf.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/igmp.h>
+#include <net/route.h>
+#include <netinet/ip_mroute.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "netstat.h"
+
+void
+mroutepr(mfcaddr, vifaddr)
+	u_long mfcaddr, vifaddr;
+{
+	u_int mrtproto;
+	struct mfc *mfctable[MFCTBLSIZ];
+	struct vif viftable[MAXVIFS];
+	struct mfc mfc, *m;
+	register struct vif *v;
+	register vifi_t vifi;
+	register int i;
+	register int banner_printed;
+	register int saved_nflag;
+	vifi_t maxvif = 0;
+
+	if (mfcaddr == 0 || vifaddr == 0) {
+		printf("No multicast routing compiled into this system.\n");
+		return;
+	}
+
+	saved_nflag = nflag;
+	nflag = 1;
+
+	kread(vifaddr, (char *)&viftable, sizeof(viftable));
+	banner_printed = 0;
+	for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) {
+		if (v->v_lcl_addr.s_addr == 0)
+			continue;
+
+		maxvif = vifi;
+		if (!banner_printed) {
+			printf("\nVirtual Interface Table\n"
+			       " Vif   Thresh   Rate   Local-Address   "
+			       "Remote-Address    Pkts-In   Pkts-Out\n");
+			banner_printed = 1;
+		}
+
+		printf(" %2u    %6u   %4d   %-15.15s",
+					/* opposite math of add_vif() */
+		    vifi, v->v_threshold, v->v_rate_limit * 1000 / 1024, 
+		    routename(v->v_lcl_addr.s_addr));
+		printf(" %-15.15s", (v->v_flags & VIFF_TUNNEL) ?
+		    routename(v->v_rmt_addr.s_addr) : "");
+
+		printf(" %9lu  %9lu\n", v->v_pkt_in, v->v_pkt_out);
+	}
+	if (!banner_printed)
+		printf("\nVirtual Interface Table is empty\n");
+
+	kread(mfcaddr, (char *)&mfctable, sizeof(mfctable));
+	banner_printed = 0;
+	for (i = 0; i < MFCTBLSIZ; ++i) {
+		m = mfctable[i];
+		while(m) {
+			kread((u_long)m, (char *)&mfc, sizeof mfc);
+
+			if (!banner_printed) {
+				printf("\nMulticast Forwarding Cache\n"
+				       " Origin          Group            "
+				       " Packets In-Vif  Out-Vifs:Ttls\n");
+				banner_printed = 1;
+			}
+
+			printf(" %-15.15s", routename(mfc.mfc_origin.s_addr));
+			printf(" %-15.15s", routename(mfc.mfc_mcastgrp.s_addr));
+			printf(" %9lu", mfc.mfc_pkt_cnt);
+			printf("  %3d   ", mfc.mfc_parent);
+			for (vifi = 0; vifi <= maxvif; vifi++) {
+				if (mfc.mfc_ttls[vifi] > 0)
+					printf(" %u:%u", vifi, 
+					       mfc.mfc_ttls[vifi]);
+			}
+			printf("\n");
+			m = mfc.mfc_next;
+		}
+	}
+	if (!banner_printed)
+		printf("\nMulticast Routing Table is empty\n");
+
+	printf("\n");
+	nflag = saved_nflag;
+}
+
+
+void
+mrt_stats(mstaddr)
+	u_long mstaddr;
+{
+	struct mrtstat mrtstat;
+
+	if (mstaddr == 0) {
+		printf("No multicast routing compiled into this system.\n");
+		return;
+	}
+
+	kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));
+	printf("multicast forwarding:\n");
+	printf(" %10lu multicast forwarding cache lookup%s\n",
+	  mrtstat.mrts_mfc_lookups, plural(mrtstat.mrts_mfc_lookups));
+	printf(" %10lu multicast forwarding cache miss%s\n",
+	  mrtstat.mrts_mfc_misses, plurales(mrtstat.mrts_mfc_misses));
+	printf(" %10lu upcall%s to mrouted\n",
+	  mrtstat.mrts_upcalls, plural(mrtstat.mrts_upcalls));
+	printf(" %10lu upcall queue overflow%s\n",
+	  mrtstat.mrts_upq_ovflw, plural(mrtstat.mrts_upq_ovflw));
+	printf(" %10lu upcall%s dropped due to full socket buffer\n",
+	  mrtstat.mrts_upq_sockfull, plural(mrtstat.mrts_upq_sockfull));
+	printf(" %10lu cache cleanup%s\n",
+	  mrtstat.mrts_cache_cleanups, plural(mrtstat.mrts_cache_cleanups));
+	printf(" %10lu datagram%s with no route for origin\n",
+	  mrtstat.mrts_no_route, plural(mrtstat.mrts_no_route));
+	printf(" %10lu datagram%s arrived with bad tunneling\n",
+	  mrtstat.mrts_bad_tunnel, plural(mrtstat.mrts_bad_tunnel));
+	printf(" %10lu datagram%s could not be tunneled\n",
+	  mrtstat.mrts_cant_tunnel, plural(mrtstat.mrts_cant_tunnel));
+	printf(" %10lu datagram%s arrived on wrong interface\n",
+	  mrtstat.mrts_wrong_if, plural(mrtstat.mrts_wrong_if));
+	printf(" %10lu datagram%s selectively dropped\n",
+	  mrtstat.mrts_drop_sel, plural(mrtstat.mrts_drop_sel));
+	printf(" %10lu datagram%s dropped due to queue overflow\n",
+	  mrtstat.mrts_q_overflow, plural(mrtstat.mrts_q_overflow));
+	printf(" %10lu datagram%s dropped for being too large\n",
+	  mrtstat.mrts_pkt2large, plural(mrtstat.mrts_pkt2large));
+}
diff --git a/netstat.tproj/netstat.1 b/netstat.tproj/netstat.1
new file mode 100644
index 0000000..fc0d303
--- /dev/null
+++ b/netstat.tproj/netstat.1
@@ -0,0 +1,289 @@
+.\" Copyright (c) 1983, 1990, 1992, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)netstat.1	8.8 (Berkeley) 4/18/94
+.\"
+.Dd April 18, 1994
+.Dt NETSTAT 1
+.Os BSD 4.2
+.Sh NAME
+.Nm netstat
+.Nd show network status
+.Sh SYNOPSIS
+.Nm netstat
+.Op Fl Aan
+.Op Fl f Ar address_family
+.Op Fl M Ar core
+.Op Fl N Ar system
+.Nm netstat
+.Op Fl dghimnrs
+.Op Fl f Ar address_family
+.Op Fl M Ar core
+.Op Fl N Ar system
+.Nm netstat
+.Op Fl dn
+.Op Fl I Ar interface
+.Op Fl M Ar core
+.Op Fl N Ar system
+.Op Fl w Ar wait
+.Nm netstat
+.Op Fl p Ar protocol
+.Op Fl M Ar core
+.Op Fl N Ar system
+.Sh DESCRIPTION
+The
+.Nm netstat
+command symbolically displays the contents of various network-related
+data structures.
+There are a number of output formats,
+depending on the options for the information presented.
+The first form of the command displays a list of active sockets for
+each protocol.
+The second form presents the contents of one of the other network
+data structures according to the option selected.
+Using the third form, with a
+.Ar wait
+interval specified,
+.Nm netstat
+will continuously display the information regarding packet
+traffic on the configured network interfaces.
+The fourth form displays statistics about the named protocol.
+.Pp
+The options have the following meaning:
+.Bl -tag -width flag
+.It Fl A
+With the default display,
+show the address of any protocol control blocks associated with sockets; used
+for debugging.
+.It Fl a
+With the default display,
+show the state of all sockets; normally sockets used by
+server processes are not shown.
+.It Fl d
+With either interface display (option
+.Fl i
+or an interval, as described below),
+show the number of dropped packets.
+.It Fl f Ar address_family 
+Limit statistics or address control block reports to those
+of the specified
+.Ar address family  .
+The following address families
+are recognized:
+.Ar inet  ,
+for
+.Dv AF_INET  ,
+.Ar ns ,
+for
+.Dv AF_NS  ,
+.Ar iso ,
+for
+.Dv AF_ISO ,
+and
+.Ar unix  ,
+for
+.Dv AF_UNIX  .
+.It Fl g
+Show information related to multicast (group address) routing.
+By default, show the IP Multicast virtual-interface and routing tables.
+If the
+.Fl s
+option is also present, show multicast routing statistics.
+.It Fl h
+Show the state of the
+.Tn IMP
+host table (obsolete).
+.It Fl I Ar interface 
+Show information about the specified interface;
+used with a
+.Ar wait
+interval as described below.
+.It Fl i
+Show the state of interfaces which have been auto-configured
+(interfaces statically configured into a system, but not
+located at boot time are not shown).
+If the
+.Fl a
+options is also present, multicast addresses currently in use are shown
+for each Ethernet interface and for each IP interface address.
+Multicast addresses are shown on separate lines following the interface
+address with which they are associated.
+.It Fl M
+Extract values associated with the name list from the specified core
+instead of the default
+.Pa /dev/kmem .
+.It Fl m
+Show statistics recorded by the memory management routines
+(the network manages a private pool of memory buffers).
+.It Fl N
+Extract the name list from the specified system instead of the default
+.Pa /vmunix .
+.It Fl n
+Show network addresses as numbers (normally
+.Nm netstat
+interprets addresses and attempts to display them
+symbolically).
+This option may be used with any of the display formats.
+.It Fl p Ar protocol 
+Show statistics about
+.Ar protocol  ,
+which is either a well-known name for a protocol or an alias for it.  Some
+protocol names and aliases are listed in the file
+.Pa /etc/protocols .
+A null response typically means that there are no interesting numbers to
+report.
+The program will complain if
+.Ar protocol
+is unknown or if there is no statistics routine for it.
+.It Fl s
+Show per-protocol statistics.
+If this option is repeated, counters with a value of zero are suppressed.
+.It Fl r
+Show the routing tables.
+When
+.Fl s
+is also present, show routing statistics instead.
+.It Fl w Ar wait
+Show network interface statistics at intervals of
+.Ar wait
+seconds.
+.El
+.Pp
+The default display, for active sockets, shows the local
+and remote addresses, send and receive queue sizes (in bytes), protocol,
+and the internal state of the protocol.
+Address formats are of the form ``host.port'' or ``network.port''
+if a socket's address specifies a network but no specific host address.
+When known the host and network addresses are displayed symbolically
+according to the data bases
+.Pa /etc/hosts
+and
+.Pa /etc/networks ,
+respectively.  If a symbolic name for an address is unknown, or if
+the
+.Fl n
+option is specified, the address is printed numerically, according
+to the address family.
+For more information regarding
+the Internet ``dot format,''
+refer to
+.Xr inet 3 ) .
+Unspecified,
+or ``wildcard'', addresses and ports appear as ``*''.
+.Pp
+The interface display provides a table of cumulative
+statistics regarding packets transferred, errors, and collisions.
+The network addresses of the interface
+and the maximum transmission unit (``mtu'') are also displayed.
+.Pp
+The routing table display indicates the available routes and
+their status.  Each route consists of a destination host or network
+and a gateway to use in forwarding packets.  The flags field shows
+a collection of information about the route stored as
+binary choices.  The individual flags are discussed in more
+detail in the
+.Xr route 8
+and
+.Xr route 4
+manual pages.
+The mapping between letters and flags is:
+.Bl -column XXXX RTF_BLACKHOLE
+1	RTF_PROTO2	Protocol specific routing flag #1 
+2	RTF_PROTO1	Protocol specific routing flag #2 
+B	RTF_BLACKHOLE	Just discard pkts (during updates) 
+C	RTF_CLONING	Generate new routes on use 
+D	RTF_DYNAMIC	Created dynamically (by redirect) 
+G	RTF_GATEWAY	Destination requires forwarding by intermediary
+H	RTF_HOST	Host entry (net otherwise) 
+L	RTF_LLINFO	Valid protocol to link address translation.
+M	RTF_MODIFIED	Modified dynamically (by redirect) 
+R	RTF_REJECT	Host or net unreachable 
+S	RTF_STATIC	Manually added 
+U	RTF_UP	Route usable 
+X	RTF_XRESOLVE	External daemon translates proto to link address
+.El
+.Pp
+Direct routes are created for each
+interface attached to the local host;
+the gateway field for such entries shows the address of the outgoing interface.
+The refcnt field gives the
+current number of active uses of the route.  Connection oriented
+protocols normally hold on to a single route for the duration of
+a connection while connectionless protocols obtain a route while sending
+to the same destination.
+The use field provides a count of the number of packets
+sent using that route.  The interface entry indicates the network
+interface utilized for the route.
+.Pp
+When
+.Nm netstat
+is invoked with the
+.Fl w
+option and a
+.Ar wait
+interval argument, it displays a running count of statistics related to
+network interfaces.
+An obsolescent version of this option used a numeric parameter
+with no option, and is currently supported for backward compatibility.
+This display consists of a column for the primary interface (the first
+interface found during autoconfiguration) and a column summarizing
+information for all interfaces.
+The primary interface may be replaced with another interface with the
+.Fl I
+option.
+The first line of each screen of information contains a summary since the
+system was last rebooted.  Subsequent lines of output show values
+accumulated over the preceding interval.
+.Sh SEE ALSO
+.Xr iostat 1 ,
+.Xr nfsstat 1 ,
+.Xr ps 1 ,
+.Xr vmstat 1 ,
+.Xr hosts 5 ,
+.Xr networks 5 ,
+.Xr protocols 5 ,
+.Xr services 5 ,
+.Xr trpt 8 ,
+.Xr trsp 8
+.Sh HISTORY
+The
+.Nm netstat
+command appeared in
+.Bx 4.2 .
+.\" .Sh FILES
+.\" .Bl -tag -width /dev/kmem -compact
+.\" .It Pa /vmunix
+.\" default kernel namelist
+.\" .It Pa /dev/kmem
+.\" default memory file
+.\" .El
+.Sh BUGS
+The notion of errors is ill-defined.
diff --git a/netstat.tproj/netstat.h b/netstat.tproj/netstat.h
new file mode 100644
index 0000000..8a70629
--- /dev/null
+++ b/netstat.tproj/netstat.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993
+ *	Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)netstat.h	8.2 (Berkeley) 1/4/94
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+EXTERN int	Aflag;		/* show addresses of protocol control block */
+EXTERN int	aflag;		/* show all sockets (including servers) */
+EXTERN int	bflag;		/* show i/f total bytes in/out */
+EXTERN int	dflag;		/* show i/f dropped packets */
+EXTERN int	gflag;		/* show group (multicast) routing or stats */
+EXTERN int	iflag;		/* show static interfaces */
+EXTERN int	mflag;		/* show memory stats */
+EXTERN int	nflag;		/* show addresses numerically */
+EXTERN int	pflag;		/* show given protocol */
+EXTERN int	rflag;		/* show routing tables (or routing stats) */
+EXTERN int	sflag;		/* show protocol statistics */
+EXTERN int	tflag;		/* show i/f watchdog timers */
+
+EXTERN int	interval;	/* repeat interval for i/f stats */
+
+EXTERN char	*interface;	/* desired i/f for stats, or NULL for all i/fs */
+EXTERN int	unit;		/* unit number for above */
+
+EXTERN int	af;		/* address family */
+
+int	kread __P((u_long addr, char *buf, int size));
+char	*plural __P((int));
+char	*plurales __P((int));
+void	trimdomain __P((char *));
+
+void	protopr __P((u_long, char *));
+void	tcp_stats __P((u_long, char *));
+void	udp_stats __P((u_long, char *));
+void	ip_stats __P((u_long, char *));
+void	icmp_stats __P((u_long, char *));
+void	igmp_stats __P((u_long, char *));
+void	protopr __P((u_long, char *));
+
+void	mbpr __P((u_long));
+
+void	hostpr __P((u_long, u_long));
+void	impstats __P((u_long, u_long));
+
+void	intpr __P((int, u_long));
+
+void	pr_rthdr __P(());
+void	pr_family __P((int));
+void	rt_stats __P((u_long));
+char	*ipx_pnet __P((struct sockaddr *));
+char	*ipx_phost __P((struct sockaddr *));
+char	*ns_phost __P((struct sockaddr *));
+void	upHex __P((char *));
+
+char	*routename __P((u_long));
+char	*netname __P((u_long, u_long));
+char	*atalk_print __P((struct sockaddr *, int));
+char	*atalk_print2 __P((struct sockaddr *, struct sockaddr *, int));
+char	*ipx_print __P((struct sockaddr *));
+char	*ns_print __P((struct sockaddr *));
+void	routepr __P((u_long));
+
+void	ipxprotopr __P((u_long, char *));
+void	spx_stats __P((u_long, char *));
+void	ipx_stats __P((u_long, char *));
+void	ipxerr_stats __P((u_long, char *));
+
+void	nsprotopr __P((u_long, char *));
+void	spp_stats __P((u_long, char *));
+void	idp_stats __P((u_long, char *));
+void	nserr_stats __P((u_long, char *));
+
+void	atalkprotopr __P((u_long, char *));
+void	ddp_stats __P((u_long, char *));
+
+void	intpr __P((int, u_long));
+
+void	unixpr __P((void));
+
+void	esis_stats __P((u_long, char *));
+void	clnp_stats __P((u_long, char *));
+void	cltp_stats __P((u_long, char *));
+void	iso_protopr __P((u_long, char *));
+void	iso_protopr1 __P((u_long, int));
+void	tp_protopr __P((u_long, char *));
+void	tp_inproto __P((u_long));
+void	tp_stats __P((caddr_t, caddr_t));
+
+void	mroutepr __P((u_long, u_long));
+void	mrt_stats __P((u_long));
+
diff --git a/netstat.tproj/route.c b/netstat.tproj/route.c
new file mode 100644
index 0000000..84b945a
--- /dev/null
+++ b/netstat.tproj/route.c
@@ -0,0 +1,918 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "From: @(#)route.c	8.6 (Berkeley) 4/28/95";
+#endif
+static const char rcsid[] =
+	"$Id: route.c,v 1.1.1.2 2000/01/11 01:48:53 wsanchez Exp $";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+
+#ifdef IPX
+#include <netipx/ipx.h>
+#include <netatalk/at.h>
+#endif
+
+#ifdef NS
+#include <netns/ns.h>
+#endif
+
+#include <sys/sysctl.h>
+
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <err.h>
+#include <time.h>
+#include "netstat.h"
+
+#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d)))
+
+/*
+ * Definitions for showing gateway flags.
+ */
+struct bits {
+	u_long	b_mask;
+	char	b_val;
+} bits[] = {
+	{ RTF_UP,	'U' },
+	{ RTF_GATEWAY,	'G' },
+	{ RTF_HOST,	'H' },
+	{ RTF_REJECT,	'R' },
+	{ RTF_DYNAMIC,	'D' },
+	{ RTF_MODIFIED,	'M' },
+	{ RTF_DONE,	'd' }, /* Completed -- for routing messages only */
+	{ RTF_CLONING,	'C' },
+	{ RTF_XRESOLVE,	'X' },
+	{ RTF_LLINFO,	'L' },
+	{ RTF_STATIC,	'S' },
+	{ RTF_PROTO1,	'1' },
+	{ RTF_PROTO2,	'2' },
+	{ RTF_WASCLONED,'W' },
+	{ RTF_PRCLONING,'c' },
+	{ RTF_PROTO3,	'3' },
+	{ RTF_BLACKHOLE,'B' },
+	{ RTF_BROADCAST,'b' },
+	{ 0 }
+};
+
+typedef union {
+	long	dummy;		/* Helps align structure. */
+	struct	sockaddr u_sa;
+	u_short	u_data[128];
+} sa_u;
+
+static sa_u pt_u;
+
+int	do_rtent = 0;
+struct	rtentry rtentry;
+struct	radix_node rnode;
+struct	radix_mask rmask;
+struct	radix_node_head *rt_tables[AF_MAX+1];
+
+int	NewTree = 0;
+
+static struct sockaddr *kgetsa __P((struct sockaddr *));
+static void p_tree __P((struct radix_node *));
+static void p_rtnode __P((void));
+static void ntreestuff __P((void));
+static void np_rtentry __P((struct rt_msghdr *));
+static void p_sockaddr __P((struct sockaddr *, struct sockaddr *, int, int));
+static void p_flags __P((int, char *));
+static void p_rtentry __P((struct rtentry *));
+static u_long forgemask __P((u_long));
+static void domask __P((char *, u_long, u_long));
+
+/*
+ * Print routing tables.
+ */
+void
+routepr(rtree)
+	u_long rtree;
+{
+	struct radix_node_head *rnh, head;
+	int i;
+
+	printf("Routing tables\n");
+
+	if (Aflag == 0 && NewTree)
+		ntreestuff();
+	else {
+		if (rtree == 0) {
+			printf("rt_tables: symbol not in namelist\n");
+			return;
+		}
+
+		kget(rtree, rt_tables);
+		for (i = 0; i <= AF_MAX; i++) {
+			if ((rnh = rt_tables[i]) == 0)
+				continue;
+			kget(rnh, head);
+			if (i == AF_UNSPEC) {
+				if (Aflag && af == 0) {
+					printf("Netmasks:\n");
+					p_tree(head.rnh_treetop);
+				}
+			} else if (af == AF_UNSPEC || af == i) {
+				pr_family(i);
+				do_rtent = 1;
+				pr_rthdr();
+				p_tree(head.rnh_treetop);
+			}
+		}
+	}
+}
+
+/*
+ * Print address family header before a section of the routing table.
+ */
+void
+pr_family(af)
+	int af;
+{
+	char *afname;
+
+	switch (af) {
+	case AF_INET:
+		afname = "Internet";
+		break;
+
+#ifdef IPX
+	case AF_IPX:
+		afname = "IPX";
+		break;
+#endif
+
+#ifdef NS
+	case AF_NS:
+		afname = "XNS";
+		break;
+#endif
+	case AF_ISO:
+		afname = "ISO";
+		break;
+	case AF_APPLETALK:
+		afname = "AppleTalk";
+		break;
+	case AF_CCITT:
+		afname = "X.25";
+		break;
+	default:
+		afname = NULL;
+		break;
+	}
+	if (afname)
+		printf("\n%s:\n", afname);
+	else
+		printf("\nProtocol Family %d:\n", af);
+}
+
+/* column widths; each followed by one space */
+#define	WID_DST		18	/* width of destination column */
+#define	WID_GW		18	/* width of gateway column */
+
+/*
+ * Print header for routing table columns.
+ */
+void
+pr_rthdr()
+{
+	if (Aflag)
+		printf("%-8.8s ","Address");
+	printf("%-*.*s %-*.*s %-6.6s  %6.6s%8.8s  %8.8s %6s\n",
+		WID_DST, WID_DST, "Destination",
+		WID_GW, WID_GW, "Gateway",
+		"Flags", "Refs", "Use", "Netif", "Expire");
+}
+
+static struct sockaddr *
+kgetsa(dst)
+	register struct sockaddr *dst;
+{
+
+	kget(dst, pt_u.u_sa);
+	if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa))
+		kread((u_long)dst, (char *)pt_u.u_data, pt_u.u_sa.sa_len);
+	return (&pt_u.u_sa);
+}
+
+static void
+p_tree(rn)
+	struct radix_node *rn;
+{
+
+again:
+	kget(rn, rnode);
+	if (rnode.rn_b < 0) {
+		if (Aflag)
+			printf("%-8.8lx ", (u_long)rn);
+		if (rnode.rn_flags & RNF_ROOT) {
+			if (Aflag)
+				printf("(root node)%s",
+				    rnode.rn_dupedkey ? " =>\n" : "\n");
+		} else if (do_rtent) {
+			kget(rn, rtentry);
+			p_rtentry(&rtentry);
+			if (Aflag)
+				p_rtnode();
+		} else {
+			p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key),
+				   NULL, 0, 44);
+			putchar('\n');
+		}
+		if ((rn = rnode.rn_dupedkey))
+			goto again;
+	} else {
+		if (Aflag && do_rtent) {
+			printf("%-8.8lx ", (u_long)rn);
+			p_rtnode();
+		}
+		rn = rnode.rn_r;
+		p_tree(rnode.rn_l);
+		p_tree(rn);
+	}
+}
+
+char	nbuf[20];
+
+static void
+p_rtnode()
+{
+	struct radix_mask *rm = rnode.rn_mklist;
+
+	if (rnode.rn_b < 0) {
+		if (rnode.rn_mask) {
+			printf("\t  mask ");
+			p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask),
+				   NULL, 0, -1);
+		} else if (rm == 0)
+			return;
+	} else {
+		sprintf(nbuf, "(%d)", rnode.rn_b);
+		printf("%6.6s %8.8lx : %8.8lx", nbuf, (u_long)rnode.rn_l, (u_long)rnode.rn_r);
+	}
+	while (rm) {
+		kget(rm, rmask);
+		sprintf(nbuf, " %d refs, ", rmask.rm_refs);
+		printf(" mk = %8.8lx {(%d),%s",
+			(u_long)rm, -1 - rmask.rm_b, rmask.rm_refs ? nbuf : " ");
+		if (rmask.rm_flags & RNF_NORMAL) {
+			struct radix_node rnode_aux;
+			printf(" <normal>, ");
+			kget(rmask.rm_leaf, rnode_aux);
+			p_sockaddr(kgetsa((struct sockaddr *)rnode_aux.rn_mask),
+				    NULL, 0, -1);
+		} else
+		    p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask),
+				NULL, 0, -1);
+		putchar('}');
+		if ((rm = rmask.rm_mklist))
+			printf(" ->");
+	}
+	putchar('\n');
+}
+
+static void
+ntreestuff()
+{
+	size_t needed;
+	int mib[6];
+	char *buf, *next, *lim;
+	register struct rt_msghdr *rtm;
+
+	mib[0] = CTL_NET;
+	mib[1] = PF_ROUTE;
+	mib[2] = 0;
+	mib[3] = 0;
+	mib[4] = NET_RT_DUMP;
+	mib[5] = 0;
+	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
+		err(1, "sysctl: net.route.0.0.dump estimate");
+	}
+
+	if ((buf = malloc(needed)) == 0) {
+		err(2, "malloc(%lu)", (unsigned long)needed);
+	}
+	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+		err(1, "sysctl: net.route.0.0.dump");
+	}
+	lim  = buf + needed;
+	for (next = buf; next < lim; next += rtm->rtm_msglen) {
+		rtm = (struct rt_msghdr *)next;
+		np_rtentry(rtm);
+	}
+}
+
+static void
+np_rtentry(rtm)
+	register struct rt_msghdr *rtm;
+{
+	register struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
+#ifdef notdef
+	static int masks_done, banner_printed;
+#endif
+	static int old_af;
+	int af = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST;
+
+#ifdef notdef
+	/* for the moment, netmasks are skipped over */
+	if (!banner_printed) {
+		printf("Netmasks:\n");
+		banner_printed = 1;
+	}
+	if (masks_done == 0) {
+		if (rtm->rtm_addrs != RTA_DST ) {
+			masks_done = 1;
+			af = sa->sa_family;
+		}
+	} else
+#endif
+		af = sa->sa_family;
+	if (af != old_af) {
+		pr_family(af);
+		old_af = af;
+	}
+	if (rtm->rtm_addrs == RTA_DST)
+		p_sockaddr(sa, NULL, 0, 36);
+	else {
+		p_sockaddr(sa, NULL, rtm->rtm_flags, 16);
+		if (sa->sa_len == 0)
+			sa->sa_len = sizeof(long);
+		sa = (struct sockaddr *)(sa->sa_len + (char *)sa);
+		p_sockaddr(sa, NULL, 0, 18);
+	}
+	p_flags(rtm->rtm_flags & interesting, "%-6.6s ");
+	putchar('\n');
+}
+
+static void
+p_sockaddr(sa, mask, flags, width)
+	struct sockaddr *sa, *mask;
+	int flags, width;
+{
+	char workbuf[128], *cplim;
+	register char *cp = workbuf;
+
+	switch(sa->sa_family) {
+	case AF_INET:
+	    {
+		register struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+		if (sin->sin_addr.s_addr == INADDR_ANY)
+			cp = "default";
+		else if (flags & RTF_HOST)
+			cp = routename(sin->sin_addr.s_addr);
+		else if (mask)
+			cp = netname(sin->sin_addr.s_addr,
+				     ntohl(((struct sockaddr_in *)mask)
+					   ->sin_addr.s_addr));
+		else
+			cp = netname(sin->sin_addr.s_addr, 0L);
+		break;
+	    }
+#ifdef IPX
+	case AF_IPX:
+	    {
+		struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr;
+		if (ipx_nullnet(satoipx_addr(work)))
+			cp = "default";
+		else
+			cp = ipx_print(sa);
+		break;
+	    }
+#endif
+
+#if 0
+	case AF_APPLETALK:
+	    {
+		if (!(flags & RTF_HOST) && mask)
+			cp = atalk_print2(sa,mask,9);
+		else
+			cp = atalk_print(sa,11);
+		break;
+	    }
+#endif
+
+#ifdef NS
+	case AF_NS:
+		cp = ns_print(sa);
+		break;
+#endif
+
+	case AF_LINK:
+	    {
+		register struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
+
+		if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 &&
+		    sdl->sdl_slen == 0)
+			(void) sprintf(workbuf, "link#%d", sdl->sdl_index);
+		else
+			switch (sdl->sdl_type) {
+
+			case IFT_ETHER:
+			    {
+				register int i;
+				register u_char *lla = (u_char *)sdl->sdl_data +
+				    sdl->sdl_nlen;
+
+				cplim = "";
+				for (i = 0; i < sdl->sdl_alen; i++, lla++) {
+					cp += sprintf(cp, "%s%x", cplim, *lla);
+					cplim = ":";
+				}
+				cp = workbuf;
+				break;
+			    }
+
+			default:
+				cp = link_ntoa(sdl);
+				break;
+			}
+		break;
+	    }
+
+	default:
+	    {
+		register u_char *s = (u_char *)sa->sa_data, *slim;
+
+		slim =  sa->sa_len + (u_char *) sa;
+		cplim = cp + sizeof(workbuf) - 6;
+		cp += sprintf(cp, "(%d)", sa->sa_family);
+		while (s < slim && cp < cplim) {
+			cp += sprintf(cp, " %02x", *s++);
+			if (s < slim)
+			    cp += sprintf(cp, "%02x", *s++);
+		}
+		cp = workbuf;
+	    }
+	}
+	if (width < 0 )
+		printf("%s ", cp);
+	else {
+		if (nflag)
+			printf("%-*s ", width, cp);
+		else
+			printf("%-*.*s ", width, width, cp);
+	}
+}
+
+static void
+p_flags(f, format)
+	register int f;
+	char *format;
+{
+	char name[33], *flags;
+	register struct bits *p = bits;
+
+	for (flags = name; p->b_mask; p++)
+		if (p->b_mask & f)
+			*flags++ = p->b_val;
+	*flags = '\0';
+	printf(format, name);
+}
+
+static void
+p_rtentry(rt)
+	register struct rtentry *rt;
+{
+	static struct ifnet ifnet, *lastif;
+	static char name[16];
+	static char prettyname[9];
+	struct sockaddr *sa;
+	sa_u addr, mask;
+
+	/*
+	 * Don't print protocol-cloned routes unless -a.
+	 */
+	if (rt->rt_parent && !aflag)
+		return;
+
+	bzero(&addr, sizeof(addr));
+	if ((sa = kgetsa(rt_key(rt))))
+		bcopy(sa, &addr, sa->sa_len);
+	bzero(&mask, sizeof(mask));
+	if (rt_mask(rt) && (sa = kgetsa(rt_mask(rt))))
+		bcopy(sa, &mask, sa->sa_len);
+	p_sockaddr(&addr.u_sa, &mask.u_sa, rt->rt_flags, WID_DST);
+	p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST, WID_GW);
+	p_flags(rt->rt_flags, "%-6.6s ");
+	printf("%6d %8ld ", rt->rt_refcnt, rt->rt_use);
+	if (rt->rt_ifp) {
+		if (rt->rt_ifp != lastif) {
+			kget(rt->rt_ifp, ifnet);
+			kread((u_long)ifnet.if_name, name, 16);
+			lastif = rt->rt_ifp;
+			snprintf(prettyname, sizeof prettyname,
+				 "%.6s%d", name, ifnet.if_unit);
+		}
+		printf("%8.8s", prettyname);
+		if (rt->rt_rmx.rmx_expire) {
+			time_t expire_time;
+
+			if ((expire_time =
+			    rt->rt_rmx.rmx_expire - time((time_t *)0)) > 0)
+				printf(" %6d%s", (int)expire_time,
+				    rt->rt_nodes[0].rn_dupedkey ? " =>" : "");
+		} else if (rt->rt_nodes[0].rn_dupedkey) {
+			printf(" =>");
+		}
+
+	}
+	putchar('\n');
+}
+
+char *
+routename(in)
+	u_long in;
+{
+	register char *cp;
+	static char line[MAXHOSTNAMELEN + 1];
+	struct hostent *hp;
+
+	cp = 0;
+	if (!nflag) {
+		hp = gethostbyaddr((char *)&in, sizeof (struct in_addr),
+			AF_INET);
+		if (hp) {
+			cp = hp->h_name;
+			trimdomain(cp);
+		}
+	}
+	if (cp) {
+		strncpy(line, cp, sizeof(line) - 1);
+		line[sizeof(line) - 1] = '\0';
+	} else {
+#define C(x)	((x) & 0xff)
+		in = ntohl(in);
+		sprintf(line, "%lu.%lu.%lu.%lu",
+		    C(in >> 24), C(in >> 16), C(in >> 8), C(in));
+	}
+	return (line);
+}
+
+static u_long
+forgemask(a)
+	u_long a;
+{
+	u_long m;
+
+	if (IN_CLASSA(a))
+		m = IN_CLASSA_NET;
+	else if (IN_CLASSB(a))
+		m = IN_CLASSB_NET;
+	else
+		m = IN_CLASSC_NET;
+	return (m);
+}
+
+static void
+domask(dst, addr, mask)
+	char *dst;
+	u_long addr, mask;
+{
+	register int b, i;
+
+	if (!mask || (forgemask(addr) == mask)) {
+		*dst = '\0';
+		return;
+	}
+	i = 0;
+	for (b = 0; b < 32; b++)
+		if (mask & (1 << b)) {
+			register int bb;
+
+			i = b;
+			for (bb = b+1; bb < 32; bb++)
+				if (!(mask & (1 << bb))) {
+					i = -1;	/* noncontig */
+					break;
+				}
+			break;
+		}
+	if (i == -1)
+		sprintf(dst, "&0x%lx", mask);
+	else
+		sprintf(dst, "/%d", 32-i);
+}
+
+/*
+ * Return the name of the network whose address is given.
+ * The address is assumed to be that of a net or subnet, not a host.
+ */
+char *
+netname(in, mask)
+	u_long in, mask;
+{
+	char *cp = 0;
+	static char line[MAXHOSTNAMELEN + 1];
+	struct netent *np = 0;
+	u_long net, omask, dmask;
+	register u_long i;
+
+	i = ntohl(in);
+	omask = mask;
+	if (!nflag && i) {
+		dmask = forgemask(i);
+		net = i & dmask;
+		if (!(np = getnetbyaddr(i, AF_INET)) && net != i)
+			np = getnetbyaddr(net, AF_INET);
+		if (np) {
+			cp = np->n_name;
+			trimdomain(cp);
+		}
+	}
+	if (cp)
+		strncpy(line, cp, sizeof(line) - 1);
+	else if ((i & 0xffffff) == 0)
+		sprintf(line, "%lu", C(i >> 24));
+	else if ((i & 0xffff) == 0)
+		sprintf(line, "%lu.%lu", C(i >> 24) , C(i >> 16));
+	else if ((i & 0xff) == 0)
+		sprintf(line, "%lu.%lu.%lu", C(i >> 24), C(i >> 16), C(i >> 8));
+	else
+		sprintf(line, "%lu.%lu.%lu.%lu", C(i >> 24),
+			C(i >> 16), C(i >> 8), C(i));
+	domask(line+strlen(line), i, omask);
+	return (line);
+}
+
+/*
+ * Print routing statistics
+ */
+void
+rt_stats(off)
+	u_long off;
+{
+	struct rtstat rtstat;
+
+	if (off == 0) {
+		printf("rtstat: symbol not in namelist\n");
+		return;
+	}
+	kread(off, (char *)&rtstat, sizeof (rtstat));
+	printf("routing:\n");
+	printf("\t%u bad routing redirect%s\n",
+		rtstat.rts_badredirect, plural(rtstat.rts_badredirect));
+	printf("\t%u dynamically created route%s\n",
+		rtstat.rts_dynamic, plural(rtstat.rts_dynamic));
+	printf("\t%u new gateway%s due to redirects\n",
+		rtstat.rts_newgateway, plural(rtstat.rts_newgateway));
+	printf("\t%u destination%s found unreachable\n",
+		rtstat.rts_unreach, plural(rtstat.rts_unreach));
+	printf("\t%u use%s of a wildcard route\n",
+		rtstat.rts_wildcard, plural(rtstat.rts_wildcard));
+}
+
+#ifdef IPX
+
+char *
+ipx_print(sa)
+	register struct sockaddr *sa;
+{
+	u_short port;
+	struct servent *sp = 0;
+	char *net = "", *host = "";
+	register char *p;
+	register u_char *q;
+	struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr;
+	static char mybuf[50];
+	char cport[10], chost[15], cnet[15];
+
+	port = ntohs(work.x_port);
+
+	if (ipx_nullnet(work) && ipx_nullhost(work)) {
+
+		if (port) {
+			if (sp)
+				sprintf(mybuf, "*.%s", sp->s_name);
+			else
+				sprintf(mybuf, "*.%x", port);
+		} else
+			sprintf(mybuf, "*.*");
+
+		return (mybuf);
+	}
+
+	if (ipx_wildnet(work))
+		net = "any";
+	else if (ipx_nullnet(work))
+		net = "*";
+	else {
+		q = work.x_net.c_net;
+		sprintf(cnet, "%02x%02x%02x%02x",
+			q[0], q[1], q[2], q[3]);
+		for (p = cnet; *p == '0' && p < cnet + 8; p++)
+			continue;
+		net = p;
+	}
+
+	if (ipx_wildhost(work))
+		host = "any";
+	else if (ipx_nullhost(work))
+		host = "*";
+	else {
+		q = work.x_host.c_host;
+		sprintf(chost, "%02x%02x%02x%02x%02x%02x",
+			q[0], q[1], q[2], q[3], q[4], q[5]);
+		for (p = chost; *p == '0' && p < chost + 12; p++)
+			continue;
+		host = p;
+	}
+
+	if (port) {
+		if (strcmp(host, "*") == 0)
+			host = "";
+		if (sp)	
+			snprintf(cport, sizeof(cport),
+				"%s%s", *host ? "." : "", sp->s_name);
+		else	
+			snprintf(cport, sizeof(cport),
+				"%s%x", *host ? "." : "", port);
+	} else
+		*cport = 0;
+
+	snprintf(mybuf, sizeof(mybuf), "%s.%s%s", net, host, cport);
+	return(mybuf);
+}
+
+char *
+ipx_phost(sa)
+	struct sockaddr *sa;
+{
+	register struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)sa;
+	struct sockaddr_ipx work;
+	static union ipx_net ipx_zeronet;
+	char *p;
+	struct ipx_addr in;
+
+	work = *sipx;
+	in = work.sipx_addr;
+
+	work.sipx_addr.x_port = 0;
+	work.sipx_addr.x_net = ipx_zeronet;
+	p = ipx_print((struct sockaddr *)&work);
+	if (strncmp("*.", p, 2) == 0) p += 2;
+
+	return(p);
+}
+#endif
+
+#ifdef NS
+short ns_nullh[] = {0,0,0};
+short ns_bh[] = {-1,-1,-1};
+
+char *
+ns_print(sa)
+	register struct sockaddr *sa;
+{
+	register struct sockaddr_ns *sns = (struct sockaddr_ns*)sa;
+	struct ns_addr work;
+	union { union ns_net net_e; u_long long_e; } net;
+	u_short port;
+	static char mybuf[50], cport[10], chost[25];
+	char *host = "";
+	register char *p; register u_char *q;
+
+	work = sns->sns_addr;
+	port = ntohs(work.x_port);
+	work.x_port = 0;
+	net.net_e  = work.x_net;
+	if (ns_nullhost(work) && net.long_e == 0) {
+		if (port ) {
+			sprintf(mybuf, "*.%xH", port);
+			upHex(mybuf);
+		} else
+			sprintf(mybuf, "*.*");
+		return (mybuf);
+	}
+
+	if (bcmp(ns_bh, work.x_host.c_host, 6) == 0) {
+		host = "any";
+	} else if (bcmp(ns_nullh, work.x_host.c_host, 6) == 0) {
+		host = "*";
+	} else {
+		q = work.x_host.c_host;
+		sprintf(chost, "%02x%02x%02x%02x%02x%02xH",
+			q[0], q[1], q[2], q[3], q[4], q[5]);
+		for (p = chost; *p == '0' && p < chost + 12; p++)
+			continue;
+		host = p;
+	}
+	if (port)
+		sprintf(cport, ".%xH", htons(port));
+	else
+		*cport = 0;
+
+	sprintf(mybuf,"%xH.%s%s", ntohl(net.long_e), host, cport);
+	upHex(mybuf);
+	return(mybuf);
+}
+
+char *
+ns_phost(sa)
+	struct sockaddr *sa;
+{
+	register struct sockaddr_ns *sns = (struct sockaddr_ns *)sa;
+	struct sockaddr_ns work;
+	static union ns_net ns_zeronet;
+	char *p;
+
+	work = *sns;
+	work.sns_addr.x_port = 0;
+	work.sns_addr.x_net = ns_zeronet;
+
+	p = ns_print((struct sockaddr *)&work);
+	if (strncmp("0H.", p, 3) == 0)
+		p += 3;
+	return(p);
+}
+#endif
+
+void
+upHex(p0)
+	char *p0;
+{
+	register char *p = p0;
+
+	for (; *p; p++)
+		switch (*p) {
+
+		case 'a':
+		case 'b':
+		case 'c':
+		case 'd':
+		case 'e':
+		case 'f':
+			*p += ('A' - 'a');
+			break;
+		}
+}
diff --git a/netstat.tproj/tp_astring.c b/netstat.tproj/tp_astring.c
new file mode 100644
index 0000000..af08ceb
--- /dev/null
+++ b/netstat.tproj/tp_astring.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)tp_astring.c	8.1 (Berkeley) 6/10/93
+ */
+
+char *tp_sstring[] = {
+"ST_ERROR(0x0)",
+"TP_CLOSED(0x1)",
+"TP_CRSENT(0x2)",
+"TP_AKWAIT(0x3)",
+"TP_OPEN(0x4)",
+"TP_CLOSING(0x5)",
+"TP_REFWAIT(0x6)",
+"TP_LISTENING(0x7)",
+"TP_CONFIRMING(0x8)",
+};
+
+char *tp_estring[] = {
+"TM_inact(0x0)",
+"TM_retrans(0x1)",
+"TM_sendack(0x2)",
+"TM_notused(0x3)",
+"TM_reference(0x4)",
+"TM_data_retrans(0x5)",
+"ER_TPDU(0x6)",
+"CR_TPDU(0x7)",
+"DR_TPDU(0x8)",
+"DC_TPDU(0x9)",
+"CC_TPDU(0xa)",
+"AK_TPDU(0xb)",
+"DT_TPDU(0xc)",
+"XPD_TPDU(0xd)",
+"XAK_TPDU(0xe)",
+"T_CONN_req(0xf)",
+"T_DISC_req(0x10)",
+"T_LISTEN_req(0x11)",
+"T_DATA_req(0x12)",
+"T_XPD_req(0x13)",
+"T_USR_rcvd(0x14)",
+"T_USR_Xrcvd(0x15)",
+"T_DETACH(0x16)",
+"T_NETRESET(0x17)",
+"T_ACPT_req(0x18)",
+};
diff --git a/netstat.tproj/unix.c b/netstat.tproj/unix.c
new file mode 100644
index 0000000..c61c855
--- /dev/null
+++ b/netstat.tproj/unix.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)unix.c	8.1 (Berkeley) 6/6/93";
+#endif
+static const char rcsid[] =
+	"$Id: unix.c,v 1.1.1.2 2000/01/11 01:48:53 wsanchez Exp $";
+#endif /* not lint */
+
+/*
+ * Display protocol blocks in the unix domain.
+ */
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/mbuf.h>
+#include <sys/sysctl.h>
+#include <sys/un.h>
+#include <sys/unpcb.h>
+
+#include <netinet/in.h>
+
+#include <errno.h>
+#include <err.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <kvm.h>
+#include "netstat.h"
+
+static	void unixdomainpr __P((struct xunpcb *, struct xsocket *));
+
+static	const char *const socktype[] =
+    { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
+
+void
+unixpr()
+{
+	char 	*buf;
+	int	type;
+	size_t	len;
+	struct	xsocket *so;
+	struct	xunpgen *xug, *oxug;
+	struct	xunpcb *xunp;
+	char mibvar[sizeof "net.local.seqpacket.pcblist"];
+
+	for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) {
+		sprintf(mibvar, "net.local.%s.pcblist", socktype[type]);
+
+		len = 0;
+		if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
+			if (errno != ENOENT)
+				warn("sysctl: %s", mibvar);
+			continue;
+		}
+		if ((buf = malloc(len)) == 0) {
+			warn("malloc %lu bytes", (u_long)len);
+			return;
+		}
+		if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
+			warn("sysctl: %s", mibvar);
+			free(buf);
+			return;
+		}
+
+		oxug = xug = (struct xunpgen *)buf;
+		for (xug = (struct xunpgen *)((char *)xug + xug->xug_len);
+		     xug->xug_len > sizeof(struct xunpgen);
+		     xug = (struct xunpgen *)((char *)xug + xug->xug_len)) {
+			xunp = (struct xunpcb *)xug;
+			so = &xunp->xu_socket;
+
+			/* Ignore PCBs which were freed during copyout. */
+			if (xunp->xu_unp.unp_gencnt > oxug->xug_gen)
+				continue;
+			unixdomainpr(xunp, so);
+		}
+		if (xug != oxug && xug->xug_gen != oxug->xug_gen) {
+			if (oxug->xug_count > xug->xug_count) {
+				printf("Some %s sockets may have been deleted.\n",
+				       socktype[type]);
+			} else if (oxug->xug_count < xug->xug_count) {
+				printf("Some %s sockets may have been created.\n",
+			       socktype[type]);
+			} else {
+				printf("Some %s sockets may have been created or deleted",
+			       socktype[type]);
+			}
+		}
+		free(buf);
+	}
+}
+
+static void
+unixdomainpr(xunp, so)
+	struct xunpcb *xunp;
+	struct xsocket *so;
+{
+	struct unpcb *unp;
+	struct sockaddr_un *sa;
+	static int first = 1;
+
+	unp = &xunp->xu_unp;
+	if (unp->unp_addr)
+		sa = &xunp->xu_addr;
+	else
+		sa = (struct sockaddr_un *)0;
+
+	if (first) {
+		printf("Active LOCAL (UNIX) domain sockets\n");
+		printf(
+"%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n",
+		    "Address", "Type", "Recv-Q", "Send-Q",
+		    "Inode", "Conn", "Refs", "Nextref");
+		first = 0;
+	}
+	printf("%8lx %-6.6s %6ld %6ld %8lx %8lx %8lx %8lx",
+	       (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc,
+	       so->so_snd.sb_cc,
+	       (long)unp->unp_vnode, (long)unp->unp_conn,
+	       (long)unp->unp_refs.lh_first, (long)unp->unp_reflink.le_next);
+	if (sa)
+		printf(" %.*s",
+		    (int)(sa->sun_len - offsetof(struct sockaddr_un, sun_path)),
+		    sa->sun_path);
+	putchar('\n');
+}
diff --git a/newclient.tproj/Makefile b/newclient.tproj/Makefile
new file mode 100644
index 0000000..e822c95
--- /dev/null
+++ b/newclient.tproj/Makefile
@@ -0,0 +1,36 @@
+#
+#  Stubbed Legacy Makefile for the newclient script
+#
+
+NAME = newclient
+
+OTHERSRCS = Makefile Makefile.preamble newclient.csh
+
+MAKEFILEDIR = $(MAKEFILEPATH)/project
+MAKEFILE = common.make
+
+# INSTALL is already set to "install -S"
+XINSTALL = install
+
+INSTALLDIR=/usr/sbin
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
+
+all project $(NAME):
+
+install:
+	@dstdir=$(DSTROOT)`grep NEXTSTEP_INSTALLDIR PB.project | sed 's/.*= \(.*\);.*/\1/'`; \
+	if [ ! -d $$dstdir ]; then \
+	    $(MKDIRS) $$dstdir; \
+	fi; \
+	$(RM) -f $$dstdir/$(NAME); \
+	echo 	$(XINSTALL) -c -o $(INSTALL_AS_USER) -g $(INSTALL_AS_GROUP) \
+		-m 555 newclient.csh $$dstdir/$(NAME); \
+	$(XINSTALL) -c -o $(INSTALL_AS_USER) -g $(INSTALL_AS_GROUP) \
+		-m 555 newclient.csh $$dstdir/$(NAME)
diff --git a/newclient.tproj/Makefile.preamble b/newclient.tproj/Makefile.preamble
new file mode 100644
index 0000000..fe326e5
--- /dev/null
+++ b/newclient.tproj/Makefile.preamble
@@ -0,0 +1 @@
+-include ../Makefile.include
diff --git a/newclient.tproj/PB.project b/newclient.tproj/PB.project
new file mode 100644
index 0000000..08d2bf1
--- /dev/null
+++ b/newclient.tproj/PB.project
@@ -0,0 +1,34 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LINKED = (); 
+        OTHER_SOURCES = (Makefile, Makefile.preamble, newclient.csh); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = newclient; 
+    PROJECTTYPE = Legacy; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/newclient.tproj/newclient.csh b/newclient.tproj/newclient.csh
new file mode 100644
index 0000000..af24796
--- /dev/null
+++ b/newclient.tproj/newclient.csh
@@ -0,0 +1,233 @@
+#! /bin/csh -f
+##
+# Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+# 
+# "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+# Reserved.  This file contains Original Code and/or Modifications of
+# Original Code as defined in and that are subject to the Apple Public
+# Source License Version 1.0 (the 'License').  You may not use this file
+# except in compliance with the License.  Please obtain a copy of the
+# License at http://www.apple.com/publicsource and read it before using
+# this file.
+# 
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+# License for the specific language governing rights and limitations
+# under the License."
+# 
+# @APPLE_LICENSE_HEADER_END@
+##
+#
+# newclient
+#
+# NetBoot client building script.
+#
+# Copyright (c) 1988, NeXT, Inc.
+#
+# Usage:
+#	"newclient -p DISKTYPE TEMPLATE DEST" Standalone Private
+#	"newclient [-s SERVER] CLIENT-1 ... CLIENT-n" Clients
+#
+
+#
+# Constants
+#
+set path=(/bin /usr/bin /usr/ucb /usr/etc /etc)
+set TESTDIR
+set CLIENTDIR=${TESTDIR}/clients
+set template=${TESTDIR}/usr/template/client
+set HOSTFILE=${TESTDIR}/etc/hosts
+set BOOTPTAB=${TESTDIR}/etc/bootptab
+
+# We are the default server
+set server=`hostname`
+
+# Are we root?
+if ( `whoami` != root ) then
+	echo "You must be root to run $0"
+	exit(1)
+endif
+
+# Preliminary argument checkout
+if ( $#argv < 1 ) then
+	goto usage
+endif
+
+# Switches must be at argv[1]
+foreach arg ( $argv[2-] )
+	if ( x$arg =~ x-* ) then
+		goto usage
+	endif
+end
+
+# Parse the switches
+if ( $argv[1] == -p || $argv[1] == -P ) then
+	if ( $#argv != 4 ) then
+		goto usage
+	endif
+	set PrivateMode
+	set disktype=$argv[2]
+	set template=$argv[3]
+	set dest=$argv[4]
+	if ( $argv[1] == -P ) then
+		set swapsize=1b
+	else
+		set swapsize=16m
+	endif
+
+	# Check that the disk type is valid
+	if ( ! -e $template/etc/fstab.$disktype ) then
+		echo "Unknown disk type" $disktype
+		exit(1)
+	endif
+else if ( $argv[1] == -s ) then
+	if ( $#argv < 3 ) then
+		goto usage
+	endif
+	set server=$argv[2]
+	shift
+	shift
+else if ( $argv[1] =~ -* ) then
+	goto usage
+endif
+
+# Make sure we have a template to work with
+if ( ! -d $template ) then
+	echo "New client template $template does not exist"
+	exit(1)
+endif
+
+# Process the private partition if that is the mode we are in.
+if ( $?PrivateMode ) then
+	if ( -e $dest ) then
+		echo "$dest already exists"
+		exit(1)
+	endif
+
+	# Create the destination directory
+	echo -n "Creating ${dest}..."
+	mkdir $dest
+	chmod 775 $dest
+	chown root.staff $dest
+	if ( $status != 0 ) then
+		echo "failed"
+		exit(1)
+	endif
+	echo "[OK]"
+
+	# Copy the template into it
+	echo -n "Copying ${template} into ${dest}..."
+	(cd $template; tar cf - .)|(cd $dest; tar xpBf -)
+	echo "[OK]"
+
+	# Make the device files
+	echo -n "Making devices in ${dest}/dev..."
+	(cd ${dest}/dev; /usr/etc/MAKEDEV NeXT)
+	echo "[OK]"
+
+	# Customize the fstab file
+	echo -n "Installing fstab.$disktype as ${dest}/etc/fstab..."
+	cp -p $dest/etc/fstab.${disktype} $dest/etc/fstab
+	if ( $status != 0 ) then
+		echo "failed"
+		exit(1)
+	endif
+	echo "[OK]"
+
+	# Touch the first 16 Meg of the swapfile
+	echo -n "Preallocating swapfile blocks..."
+	(cd ${dest}/vm; /bin/rm -f swapfile; /usr/etc/mkfile $swapsize swapfile)
+	echo "[OK]"
+
+	exit(0)
+endif
+
+#
+# If we get here, then we are building a list of clients
+#
+
+echo $argv[*]
+foreach client ( $argv[*] )
+	if ( $server == localhost ) then
+		echo "This machine can't be a server until it is given a hostname"
+		exit(1)
+	endif
+	set dest=$CLIENTDIR/$client
+
+	if (! -f /private/tftpboot/mach) then
+		echo Installing /private/tftpboot/mach
+		cp -p /mach /private/tftpboot/mach
+	endif
+	if (! -f /private/tftpboot/boot) then
+		echo Installing /private/tftpboot/boot
+		cp -p /usr/standalone/boot /private/tftpboot/boot
+	endif
+
+	# Check for already existing client directory
+	if ( -e $dest ) then
+		echo $dest already exists
+		continue
+	endif
+
+	# Create the destination directory
+	echo -n "Creating $dest..."
+	mkdir -p -m $dest
+	chown root:staff $dest
+	if ( $status != 0 ) then
+		echo "failed"
+		exit(1)
+	endif
+	echo "[OK]"
+
+	# Copy the template into it.
+	echo -n "Copying $template into ${dest}..."
+	(cd $template; tar cf - .)|(cd $dest; tar xpBf -)
+	echo "[OK]"
+
+	# Make the device files
+	echo -n "Making devices in ${dest}/dev..."
+	(cd $dest/dev; /usr/etc/MAKEDEV NeXT)
+	echo "[OK]"
+
+	# Customize the fstab file
+	echo -n "Installing fstab.client as ${dest}/etc/fstab..."
+	cp -p $dest/etc/fstab.client $dest/etc/fstab
+	sed -e "s/SERVER/$server/g" -e "s/CLIENT/$client/g" $dest/etc/fstab.client > $dest/etc/fstab
+	if ( $status != 0 ) then
+		echo $failed
+		exit(1)
+	endif
+	echo "[OK]"
+
+	# Set up a symbolic link to the kernel
+	
+	if (-f ${dest}/tftpboot/mach) then
+		echo -n "Removing ${dest}/tftpboot/mach "
+		rm ${dest}/tftpboot/mach
+		echo "[OK]"
+	endif
+		
+	echo -n "Linking /tftpboot/mach to /sdmach "
+	ln -s /sdmach ${dest}/tftpboot/mach
+	echo "[OK]"
+
+	# Touch the first 16 Meg of the swapfile
+	echo -n "Creating swapfile..."
+	(cd ${dest}/vm; /bin/rm -f swapfile; /usr/etc/mkfile 8k swapfile)
+	echo "[OK]"
+
+end
+
+exit(0)
+
+usage:
+	echo "Usage: $0 -p DISKTYPE TEMPLATE DEST"
+	echo "       $0 [-s SERVER] CLIENT CLIENT ..."
+	exit(1)
+
+
diff --git a/nfsd.tproj/Makefile b/nfsd.tproj/Makefile
new file mode 100644
index 0000000..a765f04
--- /dev/null
+++ b/nfsd.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = nfsd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = nfsd.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.dist nfsd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /sbin
+WINDOWS_INSTALLDIR = /sbin
+PDO_UNIX_INSTALLDIR = /sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -DNFS -DMACH_USER_API
+WINDOWS_PB_CFLAGS = -DNFS -DMACH_USER_API
+PDO_UNIX_PB_CFLAGS = -DNFS -DMACH_USER_API
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/nfsd.tproj/Makefile.dist b/nfsd.tproj/Makefile.dist
new file mode 100644
index 0000000..35d0d0e
--- /dev/null
+++ b/nfsd.tproj/Makefile.dist
@@ -0,0 +1,9 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/5/93
+
+PROG=	nfsd
+CFLAGS+=-DNFS
+MAN8=	nfsd.0
+DPADD=	${LIBRPC}
+LDADD=	-lrpc
+
+.include <bsd.prog.mk>
diff --git a/nfsd.tproj/Makefile.preamble b/nfsd.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/nfsd.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/nfsd.tproj/PB.project b/nfsd.tproj/PB.project
new file mode 100644
index 0000000..f314b1d
--- /dev/null
+++ b/nfsd.tproj/PB.project
@@ -0,0 +1,32 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (nfsd.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.dist, nfsd.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_COMPILEROPTIONS = "-DNFS -DMACH_USER_API"; 
+    NEXTSTEP_INSTALLDIR = /sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = nfsd; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_COMPILEROPTIONS = "-DNFS -DMACH_USER_API"; 
+    PDO_UNIX_INSTALLDIR = /sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_MAINNIB = nfsd; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = nfsd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_COMPILEROPTIONS = "-DNFS -DMACH_USER_API"; 
+    WINDOWS_INSTALLDIR = /sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_MAINNIB = nfsd; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/nfsd.tproj/nfsd.8 b/nfsd.tproj/nfsd.8
new file mode 100644
index 0000000..e98aa13
--- /dev/null
+++ b/nfsd.tproj/nfsd.8
@@ -0,0 +1,115 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)nfsd.8	8.4 (Berkeley) 3/29/95
+.\"
+.Dd March 29, 1995
+.Dt NFSD 8
+.Os
+.Sh NAME
+.Nm nfsd
+.Nd remote
+.Tn NFS
+server
+.Sh SYNOPSIS
+.Nm nfsd
+.Op Fl rut
+.Op Fl n Ar num_servers
+.Sh DESCRIPTION
+.Nm Nfsd
+runs on a server machine to service
+.Tn NFS
+requests from client machines.
+At least one
+.Nm nfsd
+must be running for a machine to operate as a server.
+.Pp
+Unless otherwise specified, four servers for
+.Tn UDP
+transport are started.
+.Pp
+The following options are available:
+.Bl -tag -width Ds
+.It Fl r
+Register the
+.Tn NFS
+service with
+.Xr portmap 8
+without creating any servers.
+This option can be used along with the
+.Fl u
+or
+.Fl t
+options to re-register NFS if the portmap server is restarted.
+.It Fl n
+Specifies how many servers to create.
+.It Fl t
+Serve
+.Tn TCP NFS
+clients.
+.It Fl u
+Serve
+.Tn UDP NFS
+clients.
+.El
+.Pp
+For example, 
+.Dq Li "nfsd -u -t 6"
+serves
+.Tn UDP
+and
+.Tn TCP
+transports using six daemons.
+.Pp
+A server should run enough daemons to handle
+the maximum level of concurrency from its clients,
+typically four to six.
+.Pp
+.Nm Nfsd
+listens for service requests at the port indicated in the
+.Tn NFS
+server specification; see
+.%T "Network File System Protocol Specification" ,
+RFC1094 and
+.%T "NFS: Network File System Version 3 Protocol Specification" .
+.Pp
+The
+.Nm nfsd
+utility exits 0 on success, and >0 if an error occurs.
+.Sh SEE ALSO
+.Xr nfsstat 1 ,
+.Xr nfssvc 2 ,
+.Xr mountd 8 ,
+.Xr portmap 8
+.Sh HISTORY
+The
+.Nm nfsd
+utility first appeared in 4.4BSD.
diff --git a/nfsd.tproj/nfsd.c b/nfsd.tproj/nfsd.c
new file mode 100644
index 0000000..1c5acec
--- /dev/null
+++ b/nfsd.tproj/nfsd.c
@@ -0,0 +1,657 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/syslog.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/uio.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_prot.h>
+
+#ifdef ISO
+#include <netiso/iso.h>
+#endif
+#include <nfs/rpcv2.h>
+#include <nfs/nfsproto.h>
+#include <nfs/nfs.h>
+
+#ifdef NFSKERB
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#endif
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+
+/* Global defs */
+#ifdef DEBUG
+#define	syslog(e, s)	fprintf(stderr,(s))
+int	debug = 1;
+#else
+int	debug = 0;
+#endif
+
+struct	nfsd_srvargs nsd;
+char	**Argv = NULL;		/* pointer to argument vector */
+char	*LastArg = NULL;	/* end of argv */
+
+#ifdef NFSKERB
+char		lnam[ANAME_SZ];
+KTEXT_ST	kt;
+AUTH_DAT	kauth;
+char		inst[INST_SZ];
+struct nfsrpc_fullblock kin, kout;
+struct nfsrpc_fullverf kverf;
+NFSKERBKEY_T	kivec;
+struct timeval	ktv;
+NFSKERBKEYSCHED_T kerb_keysched;
+#endif
+
+void	nonfs __P((int));
+void	reapchild __P((int));
+void	setproctitle __P((char *));
+void	usage __P((void));
+
+/*
+ * Nfs server daemon mostly just a user context for nfssvc()
+ *
+ * 1 - do file descriptor and signal cleanup
+ * 2 - fork the nfsd(s)
+ * 3 - create server socket(s)
+ * 4 - register socket with portmap
+ *
+ * For connectionless protocols, just pass the socket into the kernel via.
+ * nfssvc().
+ * For connection based sockets, loop doing accepts. When you get a new
+ * socket from accept, pass the msgsock into the kernel via. nfssvc().
+ * The arguments are:
+ *	-c - support iso cltp clients
+ *	-r - reregister with portmapper
+ *	-t - support tcp nfs clients
+ *	-u - support udp nfs clients
+ * followed by "n" which is the number of nfsds' to fork off
+ */
+int
+main(argc, argv, envp)
+	int argc;
+	char *argv[], *envp[];
+{
+	extern int optind;
+	struct group *grp;
+	struct nfsd_args nfsdargs;
+	struct passwd *pwd;
+	struct ucred *cr;
+	struct sockaddr_in inetaddr, inetpeer;
+#ifdef ISO
+	struct sockaddr_iso isoaddr, isopeer;
+#endif
+	struct timeval ktv;
+	fd_set ready, sockbits;
+	int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock;
+	int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock;
+	int tp4cnt, tp4flag, tp4sock, tpipcnt, tpipflag, tpipsock, udpflag;
+	char *cp, **cpp;
+
+	/* Save start and extent of argv for setproctitle. */
+	Argv = argv;
+	if (envp == 0 || *envp == 0)
+		envp = argv;
+	while (*envp)
+		envp++;
+	LastArg = envp[-1] + strlen(envp[-1]);
+
+#define	MAXNFSDCNT	20
+#define	DEFNFSDCNT	 4
+	nfsdcnt = DEFNFSDCNT;
+	cltpflag = reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0;
+	tpipflag = udpflag = 0;
+#ifdef ISO
+#define	GETOPT	"cn:rtu"
+#define	USAGE	"[-crtu] [-n num_servers]"
+#else
+#define	GETOPT	"n:rtu"
+#define	USAGE	"[-rtu] [-n num_servers]"
+#endif
+	while ((ch = getopt(argc, argv, GETOPT)) != EOF)
+		switch (ch) {
+		case 'n':
+			nfsdcnt = atoi(optarg);
+			if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
+				warnx("nfsd count %d; reset to %d", DEFNFSDCNT);
+				nfsdcnt = DEFNFSDCNT;
+			}
+			break;
+		case 'r':
+			reregister = 1;
+			break;
+		case 't':
+			tcpflag = 1;
+			break;
+		case 'u':
+			udpflag = 1;
+			break;
+#ifdef ISO
+		case 'c':
+			cltpflag = 1;
+			break;
+#ifdef notyet
+		case 'i':
+			tp4cnt = 1;
+			break;
+		case 'p':
+			tpipcnt = 1;
+			break;
+#endif /* notyet */
+#endif /* ISO */
+		default:
+		case '?':
+			usage();
+		};
+	argv += optind;
+	argc -= optind;
+
+	/*
+	 * XXX
+	 * Backward compatibility, trailing number is the count of daemons.
+	 */
+	if (argc > 1)
+		usage();
+	if (argc == 1) {
+		nfsdcnt = atoi(argv[0]);
+		if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
+			warnx("nfsd count %d; reset to %d", DEFNFSDCNT);
+			nfsdcnt = DEFNFSDCNT;
+		}
+	}
+
+	if (debug == 0) {
+		daemon(0, 0);
+		(void)signal(SIGHUP, SIG_IGN);
+		(void)signal(SIGINT, SIG_IGN);
+		(void)signal(SIGQUIT, SIG_IGN);
+		(void)signal(SIGSYS, nonfs);
+		(void)signal(SIGTERM, SIG_IGN);
+	}
+	(void)signal(SIGCHLD, reapchild);
+
+	if (reregister) {
+		if (udpflag &&
+		    (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) ||
+		     !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)))
+			err(1, "can't register with portmap for UDP.");
+		if (tcpflag &&
+		    (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) ||
+		     !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT)))
+			err(1, "can't register with portmap for TCP.");
+		exit(0);
+	}
+	openlog("nfsd:", LOG_PID, LOG_DAEMON);
+
+	for (i = 0; i < nfsdcnt; i++) {
+		switch (fork()) {
+		case -1:
+			syslog(LOG_ERR, "fork: %m");
+			exit (1);
+		case 0:
+			break;
+		default:
+			continue;
+		}
+
+		setproctitle("server");
+		nfssvc_flag = NFSSVC_NFSD;
+		nsd.nsd_nfsd = NULL;
+#ifdef NFSKERB
+		if (sizeof (struct nfsrpc_fullverf) != RPCX_FULLVERF ||
+		    sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK)
+		    syslog(LOG_ERR, "Yikes NFSKERB structs not packed!");
+		nsd.nsd_authstr = (u_char *)&kt;
+		nsd.nsd_authlen = sizeof (kt);
+		nsd.nsd_verfstr = (u_char *)&kverf;
+		nsd.nsd_verflen = sizeof (kverf);
+#endif
+		while (nfssvc(nfssvc_flag, &nsd) < 0) {
+			if (errno != ENEEDAUTH) {
+				syslog(LOG_ERR, "nfssvc: %m");
+				exit(1);
+			}
+			nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL;
+#ifdef NFSKERB
+			/*
+			 * Get the Kerberos ticket out of the authenticator
+			 * verify it and convert the principal name to a user
+			 * name. The user name is then converted to a set of
+			 * user credentials via the password and group file.
+			 * Finally, decrypt the timestamp and validate it.
+			 * For more info see the IETF Draft "Authentication
+			 * in ONC RPC".
+			 */
+			kt.length = ntohl(kt.length);
+			if (gettimeofday(&ktv, (struct timezone *)0) == 0 &&
+			    kt.length > 0 && kt.length <=
+			    (RPCAUTH_MAXSIZ - 3 * NFSX_UNSIGNED)) {
+			    kin.w1 = NFS_KERBW1(kt);
+			    kt.mbz = 0;
+			    (void)strcpy(inst, "*");
+			    if (krb_rd_req(&kt, NFS_KERBSRV,
+				inst, nsd.nsd_haddr, &kauth, "") == RD_AP_OK &&
+				krb_kntoln(&kauth, lnam) == KSUCCESS &&
+				(pwd = getpwnam(lnam)) != NULL) {
+				cr = &nsd.nsd_cr;
+				cr->cr_uid = pwd->pw_uid;
+				cr->cr_groups[0] = pwd->pw_gid;
+				cr->cr_ngroups = 1;
+				setgrent();
+				while ((grp = getgrent()) != NULL) {
+					if (grp->gr_gid == cr->cr_groups[0])
+						continue;
+					for (cpp = grp->gr_mem;
+					    *cpp != NULL; ++cpp)
+						if (!strcmp(*cpp, lnam))
+							break;
+					if (*cpp == NULL)
+						continue;
+					cr->cr_groups[cr->cr_ngroups++]
+					    = grp->gr_gid;
+					if (cr->cr_ngroups == NGROUPS)
+						break;
+				}
+				endgrent();
+
+				/*
+				 * Get the timestamp verifier out of the
+				 * authenticator and verifier strings.
+				 */
+				kin.t1 = kverf.t1;
+				kin.t2 = kverf.t2;
+				kin.w2 = kverf.w2;
+				bzero((caddr_t)kivec, sizeof (kivec));
+				bcopy((caddr_t)kauth.session,
+				    (caddr_t)nsd.nsd_key,sizeof(kauth.session));
+
+				/*
+				 * Decrypt the timestamp verifier in CBC mode.
+				 */
+				XXX
+
+				/*
+				 * Validate the timestamp verifier, to
+				 * check that the session key is ok.
+				 */
+				nsd.nsd_timestamp.tv_sec = ntohl(kout.t1);
+				nsd.nsd_timestamp.tv_usec = ntohl(kout.t2);
+				nsd.nsd_ttl = ntohl(kout.w1);
+				if ((nsd.nsd_ttl - 1) == ntohl(kout.w2))
+				    nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN;
+			}
+#endif /* NFSKERB */
+		}
+		exit(0);
+	}
+
+	/* If we are serving udp, set up the socket. */
+	if (udpflag) {
+		if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+			syslog(LOG_ERR, "can't create udp socket");
+			exit(1);
+		}
+		inetaddr.sin_family = AF_INET;
+		inetaddr.sin_addr.s_addr = INADDR_ANY;
+		inetaddr.sin_port = htons(NFS_PORT);
+		inetaddr.sin_len = sizeof(inetaddr);
+		if (bind(sock,
+		    (struct sockaddr *)&inetaddr, sizeof(inetaddr)) < 0) {
+			syslog(LOG_ERR, "can't bind udp addr");
+			exit(1);
+		}
+		if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) ||
+		    !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)) {
+			syslog(LOG_ERR, "can't register with udp portmap");
+			exit(1);
+		}
+		nfsdargs.sock = sock;
+		nfsdargs.name = NULL;
+		nfsdargs.namelen = 0;
+		if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
+			syslog(LOG_ERR, "can't Add UDP socket");
+			exit(1);
+		}
+		(void)close(sock);
+	}
+
+#ifdef ISO
+	/* If we are serving cltp, set up the socket. */
+	if (cltpflag) {
+		if ((sock = socket(AF_ISO, SOCK_DGRAM, 0)) < 0) {
+			syslog(LOG_ERR, "can't create cltp socket");
+			exit(1);
+		}
+		memset(&isoaddr, 0, sizeof(isoaddr));
+		isoaddr.siso_family = AF_ISO;
+		isoaddr.siso_tlen = 2;
+		cp = TSEL(&isoaddr);
+		*cp++ = (NFS_PORT >> 8);
+		*cp = (NFS_PORT & 0xff);
+		isoaddr.siso_len = sizeof(isoaddr);
+		if (bind(sock,
+		    (struct sockaddr *)&isoaddr, sizeof(isoaddr)) < 0) {
+			syslog(LOG_ERR, "can't bind cltp addr");
+			exit(1);
+		}
+#ifdef notyet
+		/*
+		 * XXX
+		 * Someday this should probably use "rpcbind", the son of
+		 * portmap.
+		 */
+		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) {
+			syslog(LOG_ERR, "can't register with udp portmap");
+			exit(1);
+		}
+#endif /* notyet */
+		nfsdargs.sock = sock;
+		nfsdargs.name = NULL;
+		nfsdargs.namelen = 0;
+		if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
+			syslog(LOG_ERR, "can't add UDP socket");
+			exit(1);
+		}
+		close(sock);
+	}
+#endif /* ISO */
+
+	/* Now set up the master server socket waiting for tcp connections. */
+	on = 1;
+	FD_ZERO(&sockbits);
+	connect_type_cnt = 0;
+	if (tcpflag) {
+		if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+			syslog(LOG_ERR, "can't create tcp socket");
+			exit(1);
+		}
+		if (setsockopt(tcpsock,
+		    SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
+			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
+		inetaddr.sin_family = AF_INET;
+		inetaddr.sin_addr.s_addr = INADDR_ANY;
+		inetaddr.sin_port = htons(NFS_PORT);
+		inetaddr.sin_len = sizeof(inetaddr);
+		if (bind(tcpsock,
+		    (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) {
+			syslog(LOG_ERR, "can't bind tcp addr");
+			exit(1);
+		}
+		if (listen(tcpsock, 5) < 0) {
+			syslog(LOG_ERR, "listen failed");
+			exit(1);
+		}
+		if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) ||
+		    !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT)) {
+			syslog(LOG_ERR, "can't register tcp with portmap");
+			exit(1);
+		}
+		FD_SET(tcpsock, &sockbits);
+		maxsock = tcpsock;
+		connect_type_cnt++;
+	}
+
+#ifdef notyet
+	/* Now set up the master server socket waiting for tp4 connections. */
+	if (tp4flag) {
+		if ((tp4sock = socket(AF_ISO, SOCK_SEQPACKET, 0)) < 0) {
+			syslog(LOG_ERR, "can't create tp4 socket");
+			exit(1);
+		}
+		if (setsockopt(tp4sock,
+		    SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
+			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
+		memset(&isoaddr, 0, sizeof(isoaddr));
+		isoaddr.siso_family = AF_ISO;
+		isoaddr.siso_tlen = 2;
+		cp = TSEL(&isoaddr);
+		*cp++ = (NFS_PORT >> 8);
+		*cp = (NFS_PORT & 0xff);
+		isoaddr.siso_len = sizeof(isoaddr);
+		if (bind(tp4sock,
+		    (struct sockaddr *)&isoaddr, sizeof (isoaddr)) < 0) {
+			syslog(LOG_ERR, "can't bind tp4 addr");
+			exit(1);
+		}
+		if (listen(tp4sock, 5) < 0) {
+			syslog(LOG_ERR, "listen failed");
+			exit(1);
+		}
+		/*
+		 * XXX
+		 * Someday this should probably use "rpcbind", the son of
+		 * portmap.
+		 */
+		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
+			syslog(LOG_ERR, "can't register tcp with portmap");
+			exit(1);
+		}
+		FD_SET(tp4sock, &sockbits);
+		maxsock = tp4sock;
+		connect_type_cnt++;
+	}
+
+	/* Now set up the master server socket waiting for tpip connections. */
+	if (tpipflag) {
+		if ((tpipsock = socket(AF_INET, SOCK_SEQPACKET, 0)) < 0) {
+			syslog(LOG_ERR, "can't create tpip socket");
+			exit(1);
+		}
+		if (setsockopt(tpipsock,
+		    SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
+			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
+		inetaddr.sin_family = AF_INET;
+		inetaddr.sin_addr.s_addr = INADDR_ANY;
+		inetaddr.sin_port = htons(NFS_PORT);
+		inetaddr.sin_len = sizeof(inetaddr);
+		if (bind(tpipsock,
+		    (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) {
+			syslog(LOG_ERR, "can't bind tcp addr");
+			exit(1);
+		}
+		if (listen(tpipsock, 5) < 0) {
+			syslog(LOG_ERR, "listen failed");
+			exit(1);
+		}
+		/*
+		 * XXX
+		 * Someday this should probably use "rpcbind", the son of
+		 * portmap.
+		 */
+		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
+			syslog(LOG_ERR, "can't register tcp with portmap");
+			exit(1);
+		}
+		FD_SET(tpipsock, &sockbits);
+		maxsock = tpipsock;
+		connect_type_cnt++;
+	}
+#endif /* notyet */
+
+	if (connect_type_cnt == 0)
+		exit(0);
+
+	setproctitle("master");
+
+	/*
+	 * Loop forever accepting connections and passing the sockets
+	 * into the kernel for the mounts.
+	 */
+	for (;;) {
+		ready = sockbits;
+		if (connect_type_cnt > 1) {
+			if (select(maxsock + 1,
+			    &ready, NULL, NULL, NULL) < 1) {
+				syslog(LOG_ERR, "select failed: %m");
+				exit(1);
+			}
+		}
+		if (tcpflag && FD_ISSET(tcpsock, &ready)) {
+			len = sizeof(inetpeer);
+			if ((msgsock = accept(tcpsock,
+			    (struct sockaddr *)&inetpeer, &len)) < 0) {
+				syslog(LOG_ERR, "accept failed: %m");
+				exit(1);
+			}
+			memset(inetpeer.sin_zero, 0, sizeof(inetpeer.sin_zero));
+			if (setsockopt(msgsock, SOL_SOCKET,
+			    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
+				syslog(LOG_ERR,
+				    "setsockopt SO_KEEPALIVE: %m");
+			nfsdargs.sock = msgsock;
+			nfsdargs.name = (caddr_t)&inetpeer;
+			nfsdargs.namelen = sizeof(inetpeer);
+			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
+			(void)close(msgsock);
+		}
+#ifdef notyet
+		if (tp4flag && FD_ISSET(tp4sock, &ready)) {
+			len = sizeof(isopeer);
+			if ((msgsock = accept(tp4sock,
+			    (struct sockaddr *)&isopeer, &len)) < 0) {
+				syslog(LOG_ERR, "accept failed: %m");
+				exit(1);
+			}
+			if (setsockopt(msgsock, SOL_SOCKET,
+			    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
+				syslog(LOG_ERR,
+				    "setsockopt SO_KEEPALIVE: %m");
+			nfsdargs.sock = msgsock;
+			nfsdargs.name = (caddr_t)&isopeer;
+			nfsdargs.namelen = len;
+			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
+			(void)close(msgsock);
+		}
+		if (tpipflag && FD_ISSET(tpipsock, &ready)) {
+			len = sizeof(inetpeer);
+			if ((msgsock = accept(tpipsock,
+			    (struct sockaddr *)&inetpeer, &len)) < 0) {
+				syslog(LOG_ERR, "Accept failed: %m");
+				exit(1);
+			}
+			if (setsockopt(msgsock, SOL_SOCKET,
+			    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
+				syslog(LOG_ERR, "setsockopt SO_KEEPALIVE: %m");
+			nfsdargs.sock = msgsock;
+			nfsdargs.name = (caddr_t)&inetpeer;
+			nfsdargs.namelen = len;
+			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
+			(void)close(msgsock);
+		}
+#endif /* notyet */
+	}
+}
+
+void
+usage()
+{
+	(void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
+	exit(1);
+}
+
+void
+nonfs(signo)
+	int signo;
+{
+	syslog(LOG_ERR, "missing system call: NFS not available.");
+}
+
+void
+reapchild(signo)
+	int signo;
+{
+
+	while (wait3(NULL, WNOHANG, NULL) > 0);
+}
+
+void
+setproctitle(a)
+	char *a;
+{
+	register char *cp;
+	char buf[80];
+
+	cp = Argv[0];
+	(void)snprintf(buf, sizeof(buf), "nfsd-%s", a);
+	(void)strncpy(cp, buf, LastArg - cp);
+	cp += strlen(cp);
+	while (cp < LastArg)
+		*cp++ = '\0';
+}
diff --git a/nfsiod.tproj/Makefile b/nfsiod.tproj/Makefile
new file mode 100644
index 0000000..fa0ae2f
--- /dev/null
+++ b/nfsiod.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = nfsiod
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = nfsiod.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.dist nfsiod.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /sbin
+WINDOWS_INSTALLDIR = /sbin
+PDO_UNIX_INSTALLDIR = /sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -DNFS -DMACH_USER_API
+WINDOWS_PB_CFLAGS = -DNFS -DMACH_USER_API
+PDO_UNIX_PB_CFLAGS = -DNFS -DMACH_USER_API
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/nfsiod.tproj/Makefile.dist b/nfsiod.tproj/Makefile.dist
new file mode 100644
index 0000000..72db42b
--- /dev/null
+++ b/nfsiod.tproj/Makefile.dist
@@ -0,0 +1,7 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/5/93
+
+PROG=	nfsiod
+CFLAGS+=-DNFS
+MAN8=	nfsiod.0
+
+.include <bsd.prog.mk>
diff --git a/nfsiod.tproj/Makefile.preamble b/nfsiod.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/nfsiod.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/nfsiod.tproj/PB.project b/nfsiod.tproj/PB.project
new file mode 100644
index 0000000..8d6f93f
--- /dev/null
+++ b/nfsiod.tproj/PB.project
@@ -0,0 +1,32 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (nfsiod.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.dist, nfsiod.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_COMPILEROPTIONS = "-DNFS -DMACH_USER_API"; 
+    NEXTSTEP_INSTALLDIR = /sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = nfsiod; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_COMPILEROPTIONS = "-DNFS -DMACH_USER_API"; 
+    PDO_UNIX_INSTALLDIR = /sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_MAINNIB = nfsiod; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = nfsiod; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_COMPILEROPTIONS = "-DNFS -DMACH_USER_API"; 
+    WINDOWS_INSTALLDIR = /sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_MAINNIB = nfsiod; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/nfsiod.tproj/nfsiod.8 b/nfsiod.tproj/nfsiod.8
new file mode 100644
index 0000000..2acd365
--- /dev/null
+++ b/nfsiod.tproj/nfsiod.8
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)nfsiod.8	8.2 (Berkeley) 2/22/94
+.\"
+.Dd February 22, 1994
+.Dt NFSIOD 8
+.Os
+.Sh NAME
+.Nm nfsiod
+.Nd local
+.Tn NFS
+asynchronous I/O server
+.Sh SYNOPSIS
+.Nm nfsiod
+.Op Fl n Ar num_servers
+.Sh DESCRIPTION
+.Nm Nfsiod
+runs on an
+.Tn NFS
+client machine to service asynchronous I/O requests to its server.
+It improves performance but is not required for correct operation.
+.Pp
+Unless otherwise specified, a single server is started.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl n
+Specify how many servers are to be started.
+.El
+.Pp
+A client should run enough daemons to handle its maximum
+level of concurrency, typically four to six.
+.Pp
+The
+.Nm nfsiod
+utility exits 0 on success, and >0 if an error occurs.
+.Sh SEE ALSO
+.Xr nfsstat 1 ,
+.Xr nfssvc 2 ,
+.Xr mountd 8 ,
+.Xr portmap 8
+.Sh HISTORY
+The
+.Nm nfsiod
+utility first appeared in 4.4BSD.
diff --git a/nfsiod.tproj/nfsiod.c b/nfsiod.tproj/nfsiod.c
new file mode 100644
index 0000000..07a87ff
--- /dev/null
+++ b/nfsiod.tproj/nfsiod.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/syslog.h>
+#include <sys/ucred.h>
+#include <sys/wait.h>
+
+#include <sys/mount.h>
+#include <sys/time.h>
+#include <nfs/rpcv2.h>
+#include <nfs/nfsproto.h>
+#include <nfs/nfs.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Global defs */
+#ifdef DEBUG
+int debug = 1;
+#else
+int debug = 0;
+#endif
+
+void nonfs __P((int));
+void reapchild __P((int));
+void usage __P((void));
+
+/*
+ * Nfsiod does asynchronous buffered I/O on behalf of the NFS client.
+ * It does not have to be running for correct operation, but will
+ * improve throughput.
+ */
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int ch, num_servers;
+
+#define	MAXNFSDCNT      20
+#define	DEFNFSDCNT       1
+	num_servers = DEFNFSDCNT;
+	while ((ch = getopt(argc, argv, "n:")) != EOF)
+		switch (ch) {
+		case 'n':
+			num_servers = atoi(optarg);
+			if (num_servers < 1 || num_servers > MAXNFSDCNT) {
+				warnx("nfsiod count %d; reset to %d",
+				    DEFNFSDCNT);
+				num_servers = DEFNFSDCNT;
+			}
+			break;
+		case '?':
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	/*
+	 * XXX
+	 * Backward compatibility, trailing number is the count of daemons.
+	 */
+	if (argc > 1)
+		usage();
+	if (argc == 1) {
+		num_servers = atoi(argv[0]);
+		if (num_servers < 1 || num_servers > MAXNFSDCNT) {
+			warnx("nfsiod count %d; reset to %d", DEFNFSDCNT);
+			num_servers = DEFNFSDCNT;
+		}
+	}
+
+	if (debug == 0) {
+		daemon(0, 0);
+		(void)signal(SIGHUP, SIG_IGN);
+		(void)signal(SIGINT, SIG_IGN);
+		(void)signal(SIGQUIT, SIG_IGN);
+		(void)signal(SIGSYS, nonfs);
+	}
+	(void)signal(SIGCHLD, reapchild);
+
+	openlog("nfsiod:", LOG_PID, LOG_DAEMON);
+
+	while (num_servers--)
+		switch (fork()) {
+		case -1:
+			syslog(LOG_ERR, "fork: %m");
+			exit (1);
+		case 0:
+			if (nfssvc(NFSSVC_BIOD, NULL) < 0) {
+				syslog(LOG_ERR, "nfssvc: %m");
+				exit (1);
+			}
+			exit(0);
+		}
+	exit (0);
+}
+
+void
+nonfs(signo)
+	int signo;
+{
+	syslog(LOG_ERR, "missing system call: NFS not available.");
+}
+
+void
+reapchild(signo)
+	int signo;
+{
+
+	while (wait3(NULL, WNOHANG, NULL));
+}
+
+void
+usage()
+{
+	(void)fprintf(stderr, "usage: nfsiod [-n num_servers]\n");
+	exit(1);
+}
diff --git a/nfsstat.tproj/Makefile b/nfsstat.tproj/Makefile
new file mode 100644
index 0000000..d20d30c
--- /dev/null
+++ b/nfsstat.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = nfsstat
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = nfsstat.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble nfsstat.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -DNFS -DMACH_USER_API
+WINDOWS_PB_CFLAGS = -DNFS -DMACH_USER_API
+PDO_UNIX_PB_CFLAGS = -DNFS -DMACH_USER_API
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/nfsstat.tproj/Makefile.postamble b/nfsstat.tproj/Makefile.postamble
new file mode 100644
index 0000000..b5bfe61
--- /dev/null
+++ b/nfsstat.tproj/Makefile.postamble
@@ -0,0 +1,2 @@
+INSTALL_AS_GROUP =	kmem
+INSTALL_PERMISSIONS =2555
diff --git a/nfsstat.tproj/Makefile.preamble b/nfsstat.tproj/Makefile.preamble
new file mode 100644
index 0000000..925a5c7
--- /dev/null
+++ b/nfsstat.tproj/Makefile.preamble
@@ -0,0 +1,3 @@
+CLEAN_ALL_SUBPROJECTS = YES
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/nfsstat.tproj/PB.project b/nfsstat.tproj/PB.project
new file mode 100644
index 0000000..d4ad122
--- /dev/null
+++ b/nfsstat.tproj/PB.project
@@ -0,0 +1,31 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (nfsstat.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, nfsstat.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDTOOL = make; 
+    NEXTSTEP_COMPILEROPTIONS = "-DNFS -DMACH_USER_API"; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = make; 
+    PDO_UNIX_COMPILEROPTIONS = "-DNFS -DMACH_USER_API"; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = nfsstat; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = make; 
+    WINDOWS_COMPILEROPTIONS = "-DNFS -DMACH_USER_API"; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/nfsstat.tproj/nfsstat.1 b/nfsstat.tproj/nfsstat.1
new file mode 100644
index 0000000..3acda6c
--- /dev/null
+++ b/nfsstat.tproj/nfsstat.1
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1989, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)nfsstat.1	8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt NFSSTAT 1
+.Os BSD 4.4
+.Sh NAME
+.Nm nfsstat
+.Nd display
+.Tn NFS
+statistics
+.Sh SYNOPSIS
+.Nm nfsstat
+.Op Fl M Ar core
+.Op Fl N Ar system
+.Op Fl w Ar wait
+.Sh DESCRIPTION
+.Nm Nfsstat
+displays statistics kept about
+.Tn NFS
+client and server activity.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl M
+Extract values associated with the name list from the specified core
+instead of the default
+.Pa /dev/kmem .
+.It Fl N
+Extract the name list from the specified system instead of the default
+.Pa /vmunix .
+.It Fl w
+Display a shorter summary of
+.Tn NFS
+activity for both the client and server at
+.Ar wait
+second intervals.
+.El
+.Sh FILES
+.Bl -tag -width /dev/kmem -compact
+.It Pa /vmunix
+default kernel namelist
+.It Pa /dev/kmem
+default memory file
+.El
+.Sh SEE ALSO
+.Xr fstat 1 ,
+.Xr netstat 1 ,
+.Xr ps 1 ,
+.Xr systat 1 ,
+.Xr vmstat 1 ,
+.Xr iostat 8 ,
+.Xr pstat 8 ,
+.Sh HISTORY
+The
+.Nm nfsstat
+command appears in
+.Bx 4.4 .
diff --git a/nfsstat.tproj/nfsstat.c b/nfsstat.tproj/nfsstat.c
new file mode 100644
index 0000000..7bd1ce2
--- /dev/null
+++ b/nfsstat.tproj/nfsstat.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* 
+ * Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved
+ *
+ * Copyright (c) 1983, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *	@(#)nfsstat.c	8.2 (Berkeley) 3/31/95
+ */
+
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+#include <nfs/rpcv2.h>
+#include <nfs/nfsproto.h>
+#include <nfs/nfs.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <kvm.h>
+#include <nlist.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
+#include <err.h>
+
+#define SHOW_SERVER 0x01
+#define SHOW_CLIENT 0x02
+#define SHOW_ALL (SHOW_SERVER | SHOW_CLIENT)
+
+struct nlist nl[] = {
+#define	N_NFSSTAT	0
+	{ "_nfsstats" },
+	{""},
+};
+kvm_t *kd;
+
+static int deadkernel = 0;
+
+void intpr __P((u_long, u_int));
+void printhdr __P((void));
+void sidewaysintpr __P((u_int, u_long, u_int));
+void usage __P((void));
+
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	extern int optind;
+	extern char *optarg;
+	u_int interval;
+	u_int display = SHOW_ALL;
+	int ch;
+	char *memf, *nlistf;
+	char errbuf[80];
+
+	interval = 0;
+	memf = nlistf = NULL;
+	while ((ch = getopt(argc, argv, "M:N:w:sc")) != EOF)
+		switch(ch) {
+		case 'M':
+			memf = optarg;
+			break;
+		case 'N':
+			nlistf = optarg;
+			break;
+		case 'w':
+			interval = atoi(optarg);
+			break;
+		case 's':
+			display = SHOW_SERVER;
+			break;
+		case 'c':
+			display = SHOW_CLIENT;
+			break;
+		case '?':
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+#define	BACKWARD_COMPATIBILITY
+#ifdef	BACKWARD_COMPATIBILITY
+	if (*argv) {
+		interval = atoi(*argv);
+		if (*++argv) {
+			nlistf = *argv;
+			if (*++argv)
+				memf = *argv;
+		}
+	}
+#endif
+	/*
+	 * Discard setgid privileges if not the running kernel so that bad
+	 * guys can't print interesting stuff from kernel memory.
+	 */
+	if (nlistf != NULL || memf != NULL) {
+		setegid(getgid());
+		setgid(getgid());
+		deadkernel = 1;
+
+		if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY,
+					errbuf)) == 0) {
+			errx(1, "kvm_openfiles: %s", errbuf);
+		}
+		if (kvm_nlist(kd, nl) != 0) {
+			errx(1, "kvm_nlist: can't get names");
+		}
+	}
+
+	if (interval)
+		sidewaysintpr(interval, nl[N_NFSSTAT].n_value, display);
+	else
+		intpr(nl[N_NFSSTAT].n_value, display);
+	exit(0);
+}
+
+/*
+ * Read the nfs stats using sysctl(3) for live kernels, or kvm_read
+ * for dead ones.
+ */
+void
+readstats(stp)
+	struct nfsstats *stp;
+{
+	if(deadkernel) {
+		if(kvm_read(kd, (u_long)nl[N_NFSSTAT].n_value, stp,
+			    sizeof *stp) < 0) {
+			err(1, "kvm_read");
+		}
+	} else {
+		int name[3];
+		size_t buflen = sizeof *stp;
+		struct vfsconf vfc;
+		extern int getvfsbyname(char *, struct vfsconf *);
+
+		if (getvfsbyname("nfs", &vfc) < 0)
+			err(1, "getvfsbyname: NFS not compiled into kernel");
+		name[0] = CTL_VFS;
+		name[1] = vfc.vfc_typenum;
+		name[2] = NFS_NFSSTATS;
+		if (sysctl(name, 3, stp, &buflen, (void *)0, (size_t)0) < 0) {
+			err(1, "sysctl");
+		}
+	}
+}
+
+/*
+ * Print a description of the nfs stats.
+ */
+void
+intpr(nfsstataddr, display)
+	u_long nfsstataddr;
+	u_int display;
+{
+	struct nfsstats nfsstats;
+
+	readstats(&nfsstats);
+
+	if (display & SHOW_CLIENT) {
+		printf("Client Info:\n");
+		printf("Rpc Counts:\n");
+		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
+		       "Getattr", "Setattr", "Lookup", "Readlink", "Read",
+		       "Write", "Create", "Remove");
+		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+		       nfsstats.rpccnt[NFSPROC_GETATTR],
+		       nfsstats.rpccnt[NFSPROC_SETATTR],
+		       nfsstats.rpccnt[NFSPROC_LOOKUP],
+		       nfsstats.rpccnt[NFSPROC_READLINK],
+		       nfsstats.rpccnt[NFSPROC_READ],
+		       nfsstats.rpccnt[NFSPROC_WRITE],
+		       nfsstats.rpccnt[NFSPROC_CREATE],
+		       nfsstats.rpccnt[NFSPROC_REMOVE]);
+		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
+		       "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
+		       "Readdir", "RdirPlus", "Access");
+		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+		       nfsstats.rpccnt[NFSPROC_RENAME],
+		       nfsstats.rpccnt[NFSPROC_LINK],
+		       nfsstats.rpccnt[NFSPROC_SYMLINK],
+		       nfsstats.rpccnt[NFSPROC_MKDIR],
+		       nfsstats.rpccnt[NFSPROC_RMDIR],
+		       nfsstats.rpccnt[NFSPROC_READDIR],
+		       nfsstats.rpccnt[NFSPROC_READDIRPLUS],
+		       nfsstats.rpccnt[NFSPROC_ACCESS]);
+		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
+		       "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit",
+		       "GLease", "Vacate", "Evict");
+		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+		       nfsstats.rpccnt[NFSPROC_MKNOD],
+		       nfsstats.rpccnt[NFSPROC_FSSTAT],
+		       nfsstats.rpccnt[NFSPROC_FSINFO],
+		       nfsstats.rpccnt[NFSPROC_PATHCONF],
+		       nfsstats.rpccnt[NFSPROC_COMMIT],
+		       nfsstats.rpccnt[NQNFSPROC_GETLEASE],
+		       nfsstats.rpccnt[NQNFSPROC_VACATED],
+		       nfsstats.rpccnt[NQNFSPROC_EVICTED]);
+		printf("Rpc Info:\n");
+		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
+		       "TimedOut", "Invalid", "X Replies", "Retries", "Requests");
+		printf("%9d %9d %9d %9d %9d\n",
+		       nfsstats.rpctimeouts,
+		       nfsstats.rpcinvalid,
+		       nfsstats.rpcunexpected,
+		       nfsstats.rpcretries,
+		       nfsstats.rpcrequests);
+		printf("Cache Info:\n");
+		printf("%9.9s %9.9s %9.9s %9.9s",
+		       "Attr Hits", "Misses", "Lkup Hits", "Misses");
+		printf(" %9.9s %9.9s %9.9s %9.9s\n",
+		       "BioR Hits", "Misses", "BioW Hits", "Misses");
+		printf("%9d %9d %9d %9d",
+		       nfsstats.attrcache_hits, nfsstats.attrcache_misses,
+		       nfsstats.lookupcache_hits, nfsstats.lookupcache_misses);
+		printf(" %9d %9d %9d %9d\n",
+		       nfsstats.biocache_reads-nfsstats.read_bios,
+		       nfsstats.read_bios,
+		       nfsstats.biocache_writes-nfsstats.write_bios,
+		       nfsstats.write_bios);
+		printf("%9.9s %9.9s %9.9s %9.9s",
+		       "BioRLHits", "Misses", "BioD Hits", "Misses");
+		printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
+		printf("%9d %9d %9d %9d",
+		       nfsstats.biocache_readlinks-nfsstats.readlink_bios,
+		       nfsstats.readlink_bios,
+		       nfsstats.biocache_readdirs-nfsstats.readdir_bios,
+		       nfsstats.readdir_bios);
+		printf(" %9d %9d\n",
+		       nfsstats.direofcache_hits, nfsstats.direofcache_misses);
+        }
+	if (display & SHOW_SERVER) {
+		printf("\nServer Info:\n");
+		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
+		       "Getattr", "Setattr", "Lookup", "Readlink", "Read",
+		       "Write", "Create", "Remove");
+		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+		       nfsstats.srvrpccnt[NFSPROC_GETATTR],
+		       nfsstats.srvrpccnt[NFSPROC_SETATTR],
+		       nfsstats.srvrpccnt[NFSPROC_LOOKUP],
+		       nfsstats.srvrpccnt[NFSPROC_READLINK],
+		       nfsstats.srvrpccnt[NFSPROC_READ],
+		       nfsstats.srvrpccnt[NFSPROC_WRITE],
+		       nfsstats.srvrpccnt[NFSPROC_CREATE],
+		       nfsstats.srvrpccnt[NFSPROC_REMOVE]);
+		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
+		       "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
+		       "Readdir", "RdirPlus", "Access");
+		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+		       nfsstats.srvrpccnt[NFSPROC_RENAME],
+		       nfsstats.srvrpccnt[NFSPROC_LINK],
+		       nfsstats.srvrpccnt[NFSPROC_SYMLINK],
+		       nfsstats.srvrpccnt[NFSPROC_MKDIR],
+		       nfsstats.srvrpccnt[NFSPROC_RMDIR],
+		       nfsstats.srvrpccnt[NFSPROC_READDIR],
+		       nfsstats.srvrpccnt[NFSPROC_READDIRPLUS],
+		       nfsstats.srvrpccnt[NFSPROC_ACCESS]);
+		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
+		       "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit",
+		       "GLease", "Vacate", "Evict");
+		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+		       nfsstats.srvrpccnt[NFSPROC_MKNOD],
+		       nfsstats.srvrpccnt[NFSPROC_FSSTAT],
+		       nfsstats.srvrpccnt[NFSPROC_FSINFO],
+		       nfsstats.srvrpccnt[NFSPROC_PATHCONF],
+		       nfsstats.srvrpccnt[NFSPROC_COMMIT],
+		       nfsstats.srvrpccnt[NQNFSPROC_GETLEASE],
+		       nfsstats.srvrpccnt[NQNFSPROC_VACATED],
+		       nfsstats.srvrpccnt[NQNFSPROC_EVICTED]);
+		printf("Server Ret-Failed\n");
+		printf("%17d\n", nfsstats.srvrpc_errs);
+		printf("Server Faults\n");
+		printf("%13d\n", nfsstats.srv_errs);
+		printf("Server Cache Stats:\n");
+		printf("%9.9s %9.9s %9.9s %9.9s\n",
+		       "Inprog", "Idem", "Non-idem", "Misses");
+		printf("%9d %9d %9d %9d\n",
+		       nfsstats.srvcache_inproghits,
+		       nfsstats.srvcache_idemdonehits,
+		       nfsstats.srvcache_nonidemdonehits,
+		       nfsstats.srvcache_misses);
+		printf("Server Lease Stats:\n");
+		printf("%9.9s %9.9s %9.9s\n",
+		       "Leases", "PeakL", "GLeases");
+		printf("%9d %9d %9d\n",
+		       nfsstats.srvnqnfs_leases,
+		       nfsstats.srvnqnfs_maxleases,
+		       nfsstats.srvnqnfs_getleases);
+		printf("Server Write Gathering:\n");
+		printf("%9.9s %9.9s %9.9s\n",
+		       "WriteOps", "WriteRPC", "Opsaved");
+		printf("%9d %9d %9d\n",
+		       nfsstats.srvvop_writes,
+		       nfsstats.srvrpccnt[NFSPROC_WRITE],
+		       nfsstats.srvrpccnt[NFSPROC_WRITE] - nfsstats.srvvop_writes);
+	}
+}
+
+u_char	signalled;			/* set if alarm goes off "early" */
+
+/*
+ * Print a running summary of nfs statistics.
+ * Repeat display every interval seconds, showing statistics
+ * collected over that interval.  Assumes that interval is non-zero.
+ * First line printed at top of screen is always cumulative.
+ */
+void
+sidewaysintpr(interval, off, display)
+	u_int interval;
+	u_long off;
+	u_int display;
+{
+	struct nfsstats nfsstats, lastst;
+	int hdrcnt, oldmask;
+	void catchalarm();
+
+	(void)signal(SIGALRM, catchalarm);
+	signalled = 0;
+	(void)alarm(interval);
+	bzero((caddr_t)&lastst, sizeof(lastst));
+
+	for (hdrcnt = 1;;) {
+		if (!--hdrcnt) {
+			printhdr();
+			hdrcnt = 20;
+		}
+		readstats(&nfsstats);
+		if (display & SHOW_CLIENT)
+		  printf("Client: %8d %8d %8d %8d %8d %8d %8d %8d\n",
+		    nfsstats.rpccnt[NFSPROC_GETATTR]-lastst.rpccnt[NFSPROC_GETATTR],
+		    nfsstats.rpccnt[NFSPROC_LOOKUP]-lastst.rpccnt[NFSPROC_LOOKUP],
+		    nfsstats.rpccnt[NFSPROC_READLINK]-lastst.rpccnt[NFSPROC_READLINK],
+		    nfsstats.rpccnt[NFSPROC_READ]-lastst.rpccnt[NFSPROC_READ],
+		    nfsstats.rpccnt[NFSPROC_WRITE]-lastst.rpccnt[NFSPROC_WRITE],
+		    nfsstats.rpccnt[NFSPROC_RENAME]-lastst.rpccnt[NFSPROC_RENAME],
+		    nfsstats.rpccnt[NFSPROC_ACCESS]-lastst.rpccnt[NFSPROC_ACCESS],
+		    (nfsstats.rpccnt[NFSPROC_READDIR]-lastst.rpccnt[NFSPROC_READDIR])
+		    +(nfsstats.rpccnt[NFSPROC_READDIRPLUS]-lastst.rpccnt[NFSPROC_READDIRPLUS]));
+		if (display & SHOW_SERVER)
+		  printf("Server: %8d %8d %8d %8d %8d %8d %8d %8d\n",
+		    nfsstats.srvrpccnt[NFSPROC_GETATTR]-lastst.srvrpccnt[NFSPROC_GETATTR],
+		    nfsstats.srvrpccnt[NFSPROC_LOOKUP]-lastst.srvrpccnt[NFSPROC_LOOKUP],
+		    nfsstats.srvrpccnt[NFSPROC_READLINK]-lastst.srvrpccnt[NFSPROC_READLINK],
+		    nfsstats.srvrpccnt[NFSPROC_READ]-lastst.srvrpccnt[NFSPROC_READ],
+		    nfsstats.srvrpccnt[NFSPROC_WRITE]-lastst.srvrpccnt[NFSPROC_WRITE],
+		    nfsstats.srvrpccnt[NFSPROC_RENAME]-lastst.srvrpccnt[NFSPROC_RENAME],
+		    nfsstats.srvrpccnt[NFSPROC_ACCESS]-lastst.srvrpccnt[NFSPROC_ACCESS],
+		    (nfsstats.srvrpccnt[NFSPROC_READDIR]-lastst.srvrpccnt[NFSPROC_READDIR])
+		    +(nfsstats.srvrpccnt[NFSPROC_READDIRPLUS]-lastst.srvrpccnt[NFSPROC_READDIRPLUS]));
+		lastst = nfsstats;
+		fflush(stdout);
+		oldmask = sigblock(sigmask(SIGALRM));
+		if (!signalled)
+			sigpause(0);
+		sigsetmask(oldmask);
+		signalled = 0;
+		(void)alarm(interval);
+	}
+	/*NOTREACHED*/
+}
+
+void
+printhdr()
+{
+	printf("        %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s\n",
+	    "Getattr", "Lookup", "Readlink", "Read", "Write", "Rename",
+	    "Access", "Readdir");
+	fflush(stdout);
+}
+
+/*
+ * Called if an interval expires before sidewaysintpr has completed a loop.
+ * Sets a flag to not wait for the alarm.
+ */
+void
+catchalarm()
+{
+	signalled = 1;
+}
+
+void
+usage()
+{
+	(void)fprintf(stderr,
+	    "usage: nfsstat [-cs] [-M core] [-N system] [-w interval]\n");
+	exit(1);
+}
diff --git a/pcap/Makefile b/pcap/Makefile
new file mode 100644
index 0000000..9f3d6f9
--- /dev/null
+++ b/pcap/Makefile
@@ -0,0 +1,63 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = pcap
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Library
+
+HFILES = ethertype.h gencode.h pcap-int.h pcap-namedb.h pcap.h
+
+OTHERLINKED = grammar.y scanner.l
+
+CFILES = bpf_filter.c bpf_image.c etherent.c gencode.c inet.c\
+         nametoaddr.c optimize.c pcap-bpf.c pcap.c savefile.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+OTHERLINKEDOFILES = grammar.o scanner.o
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CURRENTLY_ACTIVE_VERSION = YES
+DEPLOY_WITH_VERSION_NAME = A
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = library.make
+NEXTSTEP_INSTALLDIR = /usr/lib
+WINDOWS_INSTALLDIR = LOCAL_DEVELOPER_DIR/Libraries
+PDO_UNIX_INSTALLDIR = /usr/lib
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -traditional-cpp
+PROJECT_HEADERS = pcap.h pcap-namedb.h
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/$(USER)/BUILD
+
+WINDOWS_PUBLIC_HEADERS_DIR = LOCAL_DEVELOPER_DIR/Headers/$(NAME)
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/pcap/Makefile.postamble b/pcap/Makefile.postamble
new file mode 100644
index 0000000..36381d4
--- /dev/null
+++ b/pcap/Makefile.postamble
@@ -0,0 +1,122 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
diff --git a/pcap/Makefile.preamble b/pcap/Makefile.preamble
new file mode 100644
index 0000000..0e03ce1
--- /dev/null
+++ b/pcap/Makefile.preamble
@@ -0,0 +1,130 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS += -seg1addr 0x59400000
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES =
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
diff --git a/pcap/PB.project b/pcap/PB.project
new file mode 100644
index 0000000..cb13890
--- /dev/null
+++ b/pcap/PB.project
@@ -0,0 +1,48 @@
+{
+    CURRENTLY_ACTIVE_VERSION = YES; 
+    DEPLOY_WITH_VERSION_NAME = A; 
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        CLASSES = (); 
+        FRAMEWORKS = (); 
+        H_FILES = (ethertype.h, gencode.h, "pcap-int.h", "pcap-namedb.h", pcap.h); 
+        OTHER_LINKED = (
+            bpf_filter.c, 
+            bpf_image.c, 
+            etherent.c, 
+            gencode.c, 
+            grammar.y, 
+            inet.c, 
+            nametoaddr.c, 
+            optimize.c, 
+            "pcap-bpf.c", 
+            pcap.c, 
+            savefile.c, 
+            scanner.l
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        PROJECT_HEADERS = (pcap.h, "pcap-namedb.h"); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDDIR = "/tmp/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-traditional-cpp"; 
+    NEXTSTEP_INSTALLDIR = /usr/lib; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = /bin/gnumake; 
+    PDO_UNIX_INSTALLDIR = /usr/lib; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = pcap; 
+    PROJECTTYPE = Library; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = LOCAL_DEVELOPER_DIR/Libraries; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+    WINDOWS_PUBLICHEADERSDIR = "LOCAL_DEVELOPER_DIR/Headers/$(NAME)"; 
+}
diff --git a/pcap/bpf_filter.c b/pcap/bpf_filter.c
new file mode 100644
index 0000000..dca0d0a
--- /dev/null
+++ b/pcap/bpf_filter.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#if defined(sparc) || defined(hppa)
+#define BPF_ALIGN
+#endif
+
+#ifndef BPF_ALIGN
+#define EXTRACT_SHORT(p)	((u_short)ntohs(*(u_short *)p))
+#define EXTRACT_LONG(p)		(ntohl(*(u_int32_t *)p))
+#else
+#define EXTRACT_SHORT(p)\
+	((u_short)\
+		((u_short)*((u_char *)p+0)<<8|\
+		 (u_short)*((u_char *)p+1)<<0))
+#define EXTRACT_LONG(p)\
+		((u_int32_t)*((u_char *)p+0)<<24|\
+		 (u_int32_t)*((u_char *)p+1)<<16|\
+		 (u_int32_t)*((u_char *)p+2)<<8|\
+		 (u_int32_t)*((u_char *)p+3)<<0)
+#endif
+
+#ifdef KERNEL
+#include <sys/mbuf.h>
+#define MINDEX(m, k) \
+{ \
+	register int len = m->m_len; \
+ \
+	while (k >= len) { \
+		k -= len; \
+		m = m->m_next; \
+		if (m == 0) \
+			return 0; \
+		len = m->m_len; \
+	} \
+}
+
+static int
+m_xword(m, k, err)
+	register struct mbuf *m;
+	register int k, *err;
+{
+	register int len;
+	register u_char *cp, *np;
+	register struct mbuf *m0;
+
+	len = m->m_len;
+	while (k >= len) {
+		k -= len;
+		m = m->m_next;
+		if (m == 0)
+			goto bad;
+		len = m->m_len;
+	}
+	cp = mtod(m, u_char *) + k;
+	if (len - k >= 4) {
+		*err = 0;
+		return EXTRACT_LONG(cp);
+	}
+	m0 = m->m_next;
+	if (m0 == 0 || m0->m_len + len - k < 4)
+		goto bad;
+	*err = 0;
+	np = mtod(m0, u_char *);
+	switch (len - k) {
+
+	case 1:
+		return (cp[k] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
+
+	case 2:
+		return (cp[k] << 24) | (cp[k + 1] << 16) | (np[0] << 8) | 
+			np[1];
+
+	default:
+		return (cp[k] << 24) | (cp[k + 1] << 16) | (cp[k + 2] << 8) |
+			np[0];
+	}
+    bad:
+	*err = 1;
+	return 0;
+}
+
+static int
+m_xhalf(m, k, err)
+	register struct mbuf *m;
+	register int k, *err;
+{
+	register int len;
+	register u_char *cp;
+	register struct mbuf *m0;
+
+	len = m->m_len;
+	while (k >= len) {
+		k -= len;
+		m = m->m_next;
+		if (m == 0)
+			goto bad;
+		len = m->m_len;
+	}
+	cp = mtod(m, u_char *) + k;
+	if (len - k >= 2) {
+		*err = 0;
+		return EXTRACT_SHORT(cp);
+	}
+	m0 = m->m_next;
+	if (m0 == 0)
+		goto bad;
+	*err = 0;
+	return (cp[k] << 8) | mtod(m0, u_char *)[0];
+ bad:
+	*err = 1;
+	return 0;
+}
+#endif
+
+#include <net/bpf.h>
+
+/*
+ * Execute the filter program starting at pc on the packet p
+ * wirelen is the length of the original packet
+ * buflen is the amount of data present
+ */
+u_int
+bpf_filter(pc, p, wirelen, buflen)
+	register struct bpf_insn *pc;
+	register u_char *p;
+	u_int wirelen;
+	register u_int buflen;
+{
+	register u_int32_t A, X;
+	register int k;
+	int32_t mem[BPF_MEMWORDS];
+
+	if (pc == 0)
+		/*
+		 * No filter means accept all.
+		 */
+		return (u_int)-1;
+#ifdef lint
+	A = 0;
+	X = 0;
+#endif
+	--pc;
+	while (1) {
+		++pc;
+		switch (pc->code) {
+
+		default:
+#ifdef KERNEL
+			return 0;
+#else
+			abort();
+#endif			
+		case BPF_RET|BPF_K:
+			return (u_int)pc->k;
+
+		case BPF_RET|BPF_A:
+			return (u_int)A;
+
+		case BPF_LD|BPF_W|BPF_ABS:
+			k = pc->k;
+			if (k + sizeof(int32_t) > buflen) {
+#ifdef KERNEL
+				int merr;
+
+				if (buflen != 0)
+					return 0;
+				A = m_xword((struct mbuf *)p, k, &merr);
+				if (merr != 0)
+					return 0;
+				continue;
+#else
+				return 0;
+#endif
+			}
+#ifdef BPF_ALIGN
+			if (((int)(p + k) & 3) != 0)
+				A = EXTRACT_LONG(&p[k]);
+			else
+#endif
+				A = ntohl(*(long *)(p + k));
+			continue;
+
+		case BPF_LD|BPF_H|BPF_ABS:
+			k = pc->k;
+			if (k + sizeof(short) > buflen) {
+#ifdef KERNEL
+				int merr;
+
+				if (buflen != 0)
+					return 0;
+				A = m_xhalf((struct mbuf *)p, k, &merr);
+				continue;
+#else
+				return 0;
+#endif
+			}
+			A = EXTRACT_SHORT(&p[k]);
+			continue;
+
+		case BPF_LD|BPF_B|BPF_ABS:
+			k = pc->k;
+			if (k >= buflen) {
+#ifdef KERNEL
+				register struct mbuf *m;
+
+				if (buflen != 0)
+					return 0;
+				m = (struct mbuf *)p;
+				MINDEX(m, k);
+				A = mtod(m, u_char *)[k];
+				continue;
+#else
+				return 0;
+#endif
+			}
+			A = p[k];
+			continue;
+
+		case BPF_LD|BPF_W|BPF_LEN:
+			A = wirelen;
+			continue;
+
+		case BPF_LDX|BPF_W|BPF_LEN:
+			X = wirelen;
+			continue;
+
+		case BPF_LD|BPF_W|BPF_IND:
+			k = X + pc->k;
+			if (k + sizeof(int32_t) > buflen) {
+#ifdef KERNEL
+				int merr;
+
+				if (buflen != 0)
+					return 0;
+				A = m_xword((struct mbuf *)p, k, &merr);
+				if (merr != 0)
+					return 0;
+				continue;
+#else
+				return 0;
+#endif
+			}
+#ifdef BPF_ALIGN
+			if (((int)(p + k) & 3) != 0)
+				A = EXTRACT_LONG(&p[k]);
+			else
+#endif
+				A = ntohl(*(long *)(p + k));
+			continue;
+
+		case BPF_LD|BPF_H|BPF_IND:
+			k = X + pc->k;
+			if (k + sizeof(short) > buflen) {
+#ifdef KERNEL
+				int merr;
+
+				if (buflen != 0)
+					return 0;
+				A = m_xhalf((struct mbuf *)p, k, &merr);
+				if (merr != 0)
+					return 0;
+				continue;
+#else
+				return 0;
+#endif
+			}
+			A = EXTRACT_SHORT(&p[k]);
+			continue;
+
+		case BPF_LD|BPF_B|BPF_IND:
+			k = X + pc->k;
+			if (k >= buflen) {
+#ifdef KERNEL
+				register struct mbuf *m;
+
+				if (buflen != 0)
+					return 0;
+				m = (struct mbuf *)p;
+				MINDEX(m, k);
+				A = mtod(m, char *)[k];
+				continue;
+#else
+				return 0;
+#endif
+			}
+			A = p[k];
+			continue;
+
+		case BPF_LDX|BPF_MSH|BPF_B:
+			k = pc->k;
+			if (k >= buflen) {
+#ifdef KERNEL
+				register struct mbuf *m;
+
+				if (buflen != 0)
+					return 0;
+				m = (struct mbuf *)p;
+				MINDEX(m, k);
+				X = (mtod(m, char *)[k] & 0xf) << 2;
+				continue;
+#else
+				return 0;
+#endif
+			}
+			X = (p[pc->k] & 0xf) << 2;
+			continue;
+
+		case BPF_LD|BPF_IMM:
+			A = pc->k;
+			continue;
+
+		case BPF_LDX|BPF_IMM:
+			X = pc->k;
+			continue;
+
+		case BPF_LD|BPF_MEM:
+			A = mem[pc->k];
+			continue;
+			
+		case BPF_LDX|BPF_MEM:
+			X = mem[pc->k];
+			continue;
+
+		case BPF_ST:
+			mem[pc->k] = A;
+			continue;
+
+		case BPF_STX:
+			mem[pc->k] = X;
+			continue;
+
+		case BPF_JMP|BPF_JA:
+			pc += pc->k;
+			continue;
+
+		case BPF_JMP|BPF_JGT|BPF_K:
+			pc += (A > pc->k) ? pc->jt : pc->jf;
+			continue;
+
+		case BPF_JMP|BPF_JGE|BPF_K:
+			pc += (A >= pc->k) ? pc->jt : pc->jf;
+			continue;
+
+		case BPF_JMP|BPF_JEQ|BPF_K:
+			pc += (A == pc->k) ? pc->jt : pc->jf;
+			continue;
+
+		case BPF_JMP|BPF_JSET|BPF_K:
+			pc += (A & pc->k) ? pc->jt : pc->jf;
+			continue;
+
+		case BPF_JMP|BPF_JGT|BPF_X:
+			pc += (A > X) ? pc->jt : pc->jf;
+			continue;
+
+		case BPF_JMP|BPF_JGE|BPF_X:
+			pc += (A >= X) ? pc->jt : pc->jf;
+			continue;
+
+		case BPF_JMP|BPF_JEQ|BPF_X:
+			pc += (A == X) ? pc->jt : pc->jf;
+			continue;
+
+		case BPF_JMP|BPF_JSET|BPF_X:
+			pc += (A & X) ? pc->jt : pc->jf;
+			continue;
+
+		case BPF_ALU|BPF_ADD|BPF_X:
+			A += X;
+			continue;
+			
+		case BPF_ALU|BPF_SUB|BPF_X:
+			A -= X;
+			continue;
+			
+		case BPF_ALU|BPF_MUL|BPF_X:
+			A *= X;
+			continue;
+			
+		case BPF_ALU|BPF_DIV|BPF_X:
+			if (X == 0)
+				return 0;
+			A /= X;
+			continue;
+			
+		case BPF_ALU|BPF_AND|BPF_X:
+			A &= X;
+			continue;
+			
+		case BPF_ALU|BPF_OR|BPF_X:
+			A |= X;
+			continue;
+
+		case BPF_ALU|BPF_LSH|BPF_X:
+			A <<= X;
+			continue;
+
+		case BPF_ALU|BPF_RSH|BPF_X:
+			A >>= X;
+			continue;
+
+		case BPF_ALU|BPF_ADD|BPF_K:
+			A += pc->k;
+			continue;
+			
+		case BPF_ALU|BPF_SUB|BPF_K:
+			A -= pc->k;
+			continue;
+			
+		case BPF_ALU|BPF_MUL|BPF_K:
+			A *= pc->k;
+			continue;
+			
+		case BPF_ALU|BPF_DIV|BPF_K:
+			A /= pc->k;
+			continue;
+			
+		case BPF_ALU|BPF_AND|BPF_K:
+			A &= pc->k;
+			continue;
+			
+		case BPF_ALU|BPF_OR|BPF_K:
+			A |= pc->k;
+			continue;
+
+		case BPF_ALU|BPF_LSH|BPF_K:
+			A <<= pc->k;
+			continue;
+
+		case BPF_ALU|BPF_RSH|BPF_K:
+			A >>= pc->k;
+			continue;
+
+		case BPF_ALU|BPF_NEG:
+			A = -A;
+			continue;
+
+		case BPF_MISC|BPF_TAX:
+			X = A;
+			continue;
+
+		case BPF_MISC|BPF_TXA:
+			A = X;
+			continue;
+		}
+	}
+}
+
+#ifdef KERNEL
+/*
+ * Return true if the 'fcode' is a valid filter program.
+ * The constraints are that each jump be forward and to a valid
+ * code.  The code must terminate with either an accept or reject. 
+ * 'valid' is an array for use by the routine (it must be at least
+ * 'len' bytes long).  
+ *
+ * The kernel needs to be able to verify an application's filter code.
+ * Otherwise, a bogus program could easily crash the system.
+ */
+int
+bpf_validate(f, len)
+	struct bpf_insn *f;
+	int len;
+{
+	register int i;
+	register struct bpf_insn *p;
+
+	for (i = 0; i < len; ++i) {
+		/*
+		 * Check that that jumps are forward, and within 
+		 * the code block.
+		 */
+		p = &f[i];
+		if (BPF_CLASS(p->code) == BPF_JMP) {
+			register int from = i + 1;
+
+			if (BPF_OP(p->code) == BPF_JA) {
+				if (from + p->k >= len)
+					return 0;
+			}
+			else if (from + p->jt >= len || from + p->jf >= len)
+				return 0;
+		}
+		/*
+		 * Check that memory operations use valid addresses.
+		 */
+		if ((BPF_CLASS(p->code) == BPF_ST ||
+		     (BPF_CLASS(p->code) == BPF_LD && 
+		      (p->code & 0xe0) == BPF_MEM)) &&
+		    (p->k >= BPF_MEMWORDS || p->k < 0))
+			return 0;
+		/*
+		 * Check for constant division by 0.
+		 */
+		if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
+			return 0;
+	}
+	return BPF_CLASS(f[len - 1].code) == BPF_RET;
+}
+#endif
diff --git a/pcap/bpf_image.c b/pcap/bpf_image.c
new file mode 100644
index 0000000..f5177d9
--- /dev/null
+++ b/pcap/bpf_image.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*      $OpenBSD */
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+	"@(#) Header: bpf_image.c,v 1.19 95/11/26 14:02:36 leres Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <net/bpf.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+
+char *
+bpf_image(p, n)
+	struct bpf_insn *p;
+	int n;
+{
+	int v;
+	char *fmt, *op;
+	static char image[256];
+	char operand[64];
+
+	v = p->k;
+	switch (p->code) {
+
+	default:
+		op = "unimp";
+		fmt = "0x%x";
+		v = p->code;
+		break;
+
+	case BPF_RET|BPF_K:
+		op = "ret";
+		fmt = "#%d";
+		break;
+
+	case BPF_RET|BPF_A:
+		op = "ret";
+		fmt = "";
+		break;
+
+	case BPF_LD|BPF_W|BPF_ABS:
+		op = "ld";
+		fmt = "[%d]";
+		break;
+
+	case BPF_LD|BPF_H|BPF_ABS:
+		op = "ldh";
+		fmt = "[%d]";
+		break;
+
+	case BPF_LD|BPF_B|BPF_ABS:
+		op = "ldb";
+		fmt = "[%d]";
+		break;
+
+	case BPF_LD|BPF_W|BPF_LEN:
+		op = "ld";
+		fmt = "#pktlen";
+		break;
+
+	case BPF_LD|BPF_W|BPF_IND:
+		op = "ld";
+		fmt = "[x + %d]";
+		break;
+
+	case BPF_LD|BPF_H|BPF_IND:
+		op = "ldh";
+		fmt = "[x + %d]";
+		break;
+
+	case BPF_LD|BPF_B|BPF_IND:
+		op = "ldb";
+		fmt = "[x + %d]";
+		break;
+
+	case BPF_LD|BPF_IMM:
+		op = "ld";
+		fmt = "#0x%x";
+		break;
+
+	case BPF_LDX|BPF_IMM:
+		op = "ldx";
+		fmt = "#0x%x";
+		break;
+
+	case BPF_LDX|BPF_MSH|BPF_B:
+		op = "ldxb";
+		fmt = "4*([%d]&0xf)";
+		break;
+
+	case BPF_LD|BPF_MEM:
+		op = "ld";
+		fmt = "M[%d]";
+		break;
+
+	case BPF_LDX|BPF_MEM:
+		op = "ldx";
+		fmt = "M[%d]";
+		break;
+
+	case BPF_ST:
+		op = "st";
+		fmt = "M[%d]";
+		break;
+
+	case BPF_STX:
+		op = "stx";
+		fmt = "M[%d]";
+		break;
+
+	case BPF_JMP|BPF_JA:
+		op = "ja";
+		fmt = "%d";
+		v = n + 1 + p->k;
+		break;
+
+	case BPF_JMP|BPF_JGT|BPF_K:
+		op = "jgt";
+		fmt = "#0x%x";
+		break;
+
+	case BPF_JMP|BPF_JGE|BPF_K:
+		op = "jge";
+		fmt = "#0x%x";
+		break;
+
+	case BPF_JMP|BPF_JEQ|BPF_K:
+		op = "jeq";
+		fmt = "#0x%x";
+		break;
+
+	case BPF_JMP|BPF_JSET|BPF_K:
+		op = "jset";
+		fmt = "#0x%x";
+		break;
+
+	case BPF_JMP|BPF_JGT|BPF_X:
+		op = "jgt";
+		fmt = "x";
+		break;
+
+	case BPF_JMP|BPF_JGE|BPF_X:
+		op = "jge";
+		fmt = "x";
+		break;
+
+	case BPF_JMP|BPF_JEQ|BPF_X:
+		op = "jeq";
+		fmt = "x";
+		break;
+
+	case BPF_JMP|BPF_JSET|BPF_X:
+		op = "jset";
+		fmt = "x";
+		break;
+
+	case BPF_ALU|BPF_ADD|BPF_X:
+		op = "add";
+		fmt = "x";
+		break;
+
+	case BPF_ALU|BPF_SUB|BPF_X:
+		op = "sub";
+		fmt = "x";
+		break;
+
+	case BPF_ALU|BPF_MUL|BPF_X:
+		op = "mul";
+		fmt = "x";
+		break;
+
+	case BPF_ALU|BPF_DIV|BPF_X:
+		op = "div";
+		fmt = "x";
+		break;
+
+	case BPF_ALU|BPF_AND|BPF_X:
+		op = "and";
+		fmt = "x";
+		break;
+
+	case BPF_ALU|BPF_OR|BPF_X:
+		op = "or";
+		fmt = "x";
+		break;
+
+	case BPF_ALU|BPF_LSH|BPF_X:
+		op = "lsh";
+		fmt = "x";
+		break;
+
+	case BPF_ALU|BPF_RSH|BPF_X:
+		op = "rsh";
+		fmt = "x";
+		break;
+
+	case BPF_ALU|BPF_ADD|BPF_K:
+		op = "add";
+		fmt = "#%d";
+		break;
+
+	case BPF_ALU|BPF_SUB|BPF_K:
+		op = "sub";
+		fmt = "#%d";
+		break;
+
+	case BPF_ALU|BPF_MUL|BPF_K:
+		op = "mul";
+		fmt = "#%d";
+		break;
+
+	case BPF_ALU|BPF_DIV|BPF_K:
+		op = "div";
+		fmt = "#%d";
+		break;
+
+	case BPF_ALU|BPF_AND|BPF_K:
+		op = "and";
+		fmt = "#%d";
+		break;
+
+	case BPF_ALU|BPF_OR|BPF_K:
+		op = "or";
+		fmt = "#%d";
+		break;
+
+	case BPF_ALU|BPF_LSH|BPF_K:
+		op = "lsh";
+		fmt = "#%d";
+		break;
+
+	case BPF_ALU|BPF_RSH|BPF_K:
+		op = "rsh";
+		fmt = "#%d";
+		break;
+
+	case BPF_ALU|BPF_NEG:
+		op = "neg";
+		fmt = "";
+		break;
+
+	case BPF_MISC|BPF_TAX:
+		op = "tax";
+		fmt = "";
+		break;
+
+	case BPF_MISC|BPF_TXA:
+		op = "txa";
+		fmt = "";
+		break;
+	}
+	(void)sprintf(operand, fmt, v);
+	(void)sprintf(image,
+		      (BPF_CLASS(p->code) == BPF_JMP &&
+		       BPF_OP(p->code) != BPF_JA) ?
+		      "(%03d) %-8s %-16s jt %d\tjf %d"
+		      : "(%03d) %-8s %s",
+		      n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
+	return image;
+}
diff --git a/pcap/etherent.c b/pcap/etherent.c
new file mode 100644
index 0000000..3b2347e
--- /dev/null
+++ b/pcap/etherent.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: etherent.c,v 1.5 1996/09/16 02:33:04 tholo Exp $	*/
+
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static char rcsid[] =
+    "@(#) Header: etherent.c,v 1.18 95/10/07 03:08:12 leres Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <memory.h>
+#include <pcap.h>
+#include <pcap-namedb.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+
+static __inline int xdtoi(int);
+static __inline int skip_space(FILE *);
+static __inline int skip_line(FILE *);
+
+/* Hex digit to integer. */
+static __inline int
+xdtoi(c)
+	register int c;
+{
+	if (isdigit(c))
+		return c - '0';
+	else if (islower(c))
+		return c - 'a' + 10;
+	else
+		return c - 'A' + 10;
+}
+
+static __inline int
+skip_space(f)
+	FILE *f;
+{
+	int c;
+
+	do {
+		c = getc(f);
+	} while (isspace(c) && c != '\n');
+
+	return c;
+}
+
+static __inline int
+skip_line(f)
+	FILE *f;
+{
+	int c;
+
+	do
+		c = getc(f);
+	while (c != '\n' && c != EOF);
+
+	return c;
+}
+
+struct pcap_etherent *
+pcap_next_etherent(FILE *fp)
+{
+	register int c, d, i;
+	char *bp;
+	static struct pcap_etherent e;
+
+	memset((char *)&e, 0, sizeof(e));
+	do {
+		/* Find addr */
+		c = skip_space(fp);
+		if (c == '\n')
+			continue;
+
+		/* If this is a comment, or first thing on line
+		   cannot be etehrnet address, skip the line. */
+		if (!isxdigit(c)) {
+			c = skip_line(fp);
+			continue;
+		}
+
+		/* must be the start of an address */
+		for (i = 0; i < 6; i += 1) {
+			d = xdtoi(c);
+			c = getc(fp);
+			if (isxdigit(c)) {
+				d <<= 4;
+				d |= xdtoi(c);
+				c = getc(fp);
+			}
+			e.addr[i] = d;
+			if (c != ':')
+				break;
+			c = getc(fp);
+		}
+		if (c == EOF)
+			break;
+
+		/* Must be whitespace */
+		if (!isspace(c)) {
+			c = skip_line(fp);
+			continue;
+		}
+		c = skip_space(fp);
+
+		/* hit end of line... */
+		if (c == '\n')
+			continue;
+
+		if (c == '#') {
+			c = skip_line(fp);
+			continue;
+		}
+
+		/* pick up name */
+		bp = e.name;
+		/* Use 'd' to prevent buffer overflow. */
+		d = sizeof(e.name) - 1;
+		do {
+			*bp++ = c;
+			c = getc(fp);
+		} while (!isspace(c) && c != EOF && --d > 0);
+		*bp = '\0';
+
+		/* Eat trailing junk */
+		if (c != '\n')
+			(void)skip_line(fp);
+
+		return &e;
+
+	} while (c != EOF);
+
+	return (NULL);
+}
diff --git a/pcap/ethertype.h b/pcap/ethertype.h
new file mode 100644
index 0000000..0a046fa
--- /dev/null
+++ b/pcap/ethertype.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD */
+/*	$NetBSD: ethertype.h,v 1.2 1995/03/06 11:38:17 mycroft Exp $	*/
+
+/*
+ * Copyright (c) 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: ethertype.h,v 1.2 94/06/14 20:03:27 leres Exp (LBL)
+ */
+
+/* Map between Ethernet protocol types and names */
+
+/* Add other Ethernet packet types here */
+#ifndef	ETHERTYPE_SPRITE
+#define	ETHERTYPE_SPRITE	0x0500
+#endif
+#ifndef	ETHERTYPE_MOPDL
+#define	ETHERTYPE_MOPDL		0x6001
+#endif
+#ifndef	ETHERTYPE_MOPRC
+#define	ETHERTYPE_MOPRC		0x6002
+#endif
+#ifndef	ETHERTYPE_DN
+#define	ETHERTYPE_DN		0x6003
+#endif
+#ifndef	ETHERTYPE_LAT
+#define	ETHERTYPE_LAT		0x6004
+#endif
+#ifndef	ETHERTYPE_LANBRIDGE
+#define	ETHERTYPE_LANBRIDGE	0x8038
+#endif
+#ifndef	ETHERTYPE_DECDNS
+#define	ETHERTYPE_DECDNS	0x803c
+#endif
+#ifndef	ETHERTYPE_DECDTS
+#define	ETHERTYPE_DECDTS	0x803e
+#endif
+#ifndef	ETHERTYPE_VEXP
+#define	ETHERTYPE_VEXP		0x805b
+#endif
+#ifndef	ETHERTYPE_VPROD
+#define	ETHERTYPE_VPROD		0x805c
+#endif
+#ifndef	ETHERTYPE_LOOPBACK
+#define	ETHERTYPE_LOOPBACK	0x9000
+#endif
+
+#ifndef ETHERTYPE_ATALK
+#define ETHERTYPE_ATALK		0x809b /* XXX */
+#endif
+#ifndef ETHERTYPE_AARP
+#define ETHERTYPE_AARP		0x80f3
+#endif
+#ifndef ETHERTYPE_NS
+#define ETHERTYPE_NS		0x0600
+#endif
+
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP	0x8035
+#endif
+
diff --git a/pcap/gencode.c b/pcap/gencode.c
new file mode 100644
index 0000000..dfcd9e4
--- /dev/null
+++ b/pcap/gencode.c
@@ -0,0 +1,1843 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: gencode.c,v 1.5 1996/09/16 02:33:05 tholo Exp $	*/
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static char rcsid[] =
+    "@(#) Header: gencode.c,v 1.81 96/06/19 23:09:09 leres Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+
+#include <net/if.h>
+#include <net/bpf.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <stdlib.h>
+#include <memory.h>
+#include <pcap.h>
+#include <pcap-namedb.h>
+#include <setjmp.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP	0x8035
+#endif
+#ifndef	ETHERTYPE_MOPDL
+#define	ETHERTYPE_MOPDL		0x6001
+#endif
+#ifndef	ETHERTYPE_MOPRC
+#define	ETHERTYPE_MOPRC		0x6002
+#endif
+#ifndef	ETHERTYPE_DN
+#define	ETHERTYPE_DN		0x6003
+#endif
+#ifndef	ETHERTYPE_LAT
+#define	ETHERTYPE_LAT		0x6004
+#endif
+
+#define JMP(c) ((c)|BPF_JMP|BPF_K)
+
+/* Locals */
+static jmp_buf top_ctx;
+static pcap_t *bpf_pcap;
+
+/* XXX */
+#ifdef PCAP_FDDIPAD
+int	pcap_fddipad = PCAP_FDDIPAD;
+#else
+int	pcap_fddipad;
+#endif
+#ifndef DLT_ATM_RFC1483
+#define DLT_ATM_RFC1483 11
+#endif
+
+
+/* VARARGS */
+__dead void
+#if __STDC__
+bpf_error(const char *fmt, ...)
+#else
+bpf_error(fmt, va_alist)
+	const char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	if (bpf_pcap != NULL)
+		(void)vsprintf(pcap_geterr(bpf_pcap), fmt, ap);
+	va_end(ap);
+	longjmp(top_ctx, 1);
+	/* NOTREACHED */
+}
+
+static void init_linktype(int);
+
+static int alloc_reg(void);
+static void free_reg(int);
+
+static struct block *root;
+
+/*
+ * We divy out chunks of memory rather than call malloc each time so
+ * we don't have to worry about leaking memory.  It's probably
+ * not a big deal if all this memory was wasted but it this ever
+ * goes into a library that would probably not be a good idea.
+ */
+#define NCHUNKS 16
+#define CHUNK0SIZE 1024
+struct chunk {
+	u_int n_left;
+	void *m;
+};
+
+static struct chunk chunks[NCHUNKS];
+static int cur_chunk;
+
+static void *newchunk(u_int);
+static void freechunks(void);
+static __inline struct block *new_block(int);
+static __inline struct slist *new_stmt(int);
+static struct block *gen_retblk(int);
+static __inline void syntax(void);
+
+static void backpatch(struct block *, struct block *);
+static void merge(struct block *, struct block *);
+static struct block *gen_cmp(u_int, u_int, bpf_int32);
+static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32);
+static struct block *gen_bcmp(u_int, u_int, u_char *);
+static struct block *gen_uncond(int);
+static __inline struct block *gen_true(void);
+static __inline struct block *gen_false(void);
+static struct block *gen_linktype(int);
+static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
+static struct block *gen_ehostop(u_char *, int);
+static struct block *gen_fhostop(u_char *, int);
+static struct block *gen_dnhostop(bpf_u_int32, int, u_int);
+static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int);
+static struct block *gen_gateway(u_char *, bpf_u_int32 **, int, int);
+static struct block *gen_ipfrag(void);
+static struct block *gen_portatom(int, bpf_int32);
+struct block *gen_portop(int, int, int);
+static struct block *gen_port(int, int, int);
+static int lookup_proto(char *, int);
+static struct block *gen_proto(int, int, int);
+static bpf_u_int32 net_mask(bpf_u_int32 *);
+static struct slist *xfer_to_x(struct arth *);
+static struct slist *xfer_to_a(struct arth *);
+static struct block *gen_len(int, int);
+
+static void *
+newchunk(n)
+	u_int n;
+{
+	struct chunk *cp;
+	int k, size;
+
+	/* XXX Round up to nearest long. */
+	n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
+
+	cp = &chunks[cur_chunk];
+	if (n > cp->n_left) {
+		++cp, k = ++cur_chunk;
+		if (k >= NCHUNKS)
+			bpf_error("out of memory");
+		size = CHUNK0SIZE << k;
+		cp->m = (void *)malloc(size);
+		memset((char *)cp->m, 0, size);
+		cp->n_left = size;
+		if (n > size)
+			bpf_error("out of memory");
+	}
+	cp->n_left -= n;
+	return (void *)((char *)cp->m + cp->n_left);
+}
+
+static void
+freechunks()
+{
+	int i;
+
+	cur_chunk = 0;
+	for (i = 0; i < NCHUNKS; ++i)
+		if (chunks[i].m != NULL) {
+			free(chunks[i].m);
+			chunks[i].m = NULL;
+		}
+}
+
+/*
+ * A strdup whose allocations are freed after code generation is over.
+ */
+char *
+sdup(s)
+	char *s;
+{
+	int n = strlen(s) + 1;
+	char *cp = newchunk(n);
+	strcpy(cp, s);
+	return (cp);
+}
+
+static __inline struct block *
+new_block(code)
+	int code;
+{
+	struct block *p;
+
+	p = (struct block *)newchunk(sizeof(*p));
+	p->s.code = code;
+	p->head = p;
+
+	return p;
+}
+
+static __inline struct slist *
+new_stmt(code)
+	int code;
+{
+	struct slist *p;
+
+	p = (struct slist *)newchunk(sizeof(*p));
+	p->s.code = code;
+
+	return p;
+}
+
+static struct block *
+gen_retblk(v)
+	int v;
+{
+	struct block *b = new_block(BPF_RET|BPF_K);
+
+	b->s.k = v;
+	return b;
+}
+
+static __inline void
+syntax()
+{
+	bpf_error("syntax error in filter expression");
+}
+
+static bpf_u_int32 netmask;
+static int snaplen;
+
+int
+pcap_compile(pcap_t *p, struct bpf_program *program,
+	     char *buf, int optimize, bpf_u_int32 mask)
+{
+	extern int n_errors;
+	int len;
+
+	n_errors = 0;
+	root = NULL;
+	bpf_pcap = p;
+	if (setjmp(top_ctx)) {
+		freechunks();
+		return (-1);
+	}
+
+	netmask = mask;
+	snaplen = pcap_snapshot(p);
+
+	lex_init(buf ? buf : "");
+	init_linktype(pcap_datalink(p));
+	(void)pcap_parse();
+
+	if (n_errors)
+		syntax();
+
+	if (root == NULL)
+		root = gen_retblk(snaplen);
+
+	if (optimize) {
+		bpf_optimize(&root);
+		if (root == NULL ||
+		    (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
+			bpf_error("expression rejects all packets");
+	}
+	program->bf_insns = icode_to_fcode(root, &len);
+	program->bf_len = len;
+
+	freechunks();
+	return (0);
+}
+
+/*
+ * Backpatch the blocks in 'list' to 'target'.  The 'sense' field indicates
+ * which of the jt and jf fields has been resolved and which is a pointer
+ * back to another unresolved block (or nil).  At least one of the fields
+ * in each block is already resolved.
+ */
+static void
+backpatch(list, target)
+	struct block *list, *target;
+{
+	struct block *next;
+
+	while (list) {
+		if (!list->sense) {
+			next = JT(list);
+			JT(list) = target;
+		} else {
+			next = JF(list);
+			JF(list) = target;
+		}
+		list = next;
+	}
+}
+
+/*
+ * Merge the lists in b0 and b1, using the 'sense' field to indicate
+ * which of jt and jf is the link.
+ */
+static void
+merge(b0, b1)
+	struct block *b0, *b1;
+{
+	register struct block **p = &b0;
+
+	/* Find end of list. */
+	while (*p)
+		p = !((*p)->sense) ? &JT(*p) : &JF(*p);
+
+	/* Concatenate the lists. */
+	*p = b1;
+}
+
+void
+finish_parse(p)
+	struct block *p;
+{
+	backpatch(p, gen_retblk(snaplen));
+	p->sense = !p->sense;
+	backpatch(p, gen_retblk(0));
+	root = p->head;
+}
+
+void
+gen_and(b0, b1)
+	struct block *b0, *b1;
+{
+	backpatch(b0, b1->head);
+	b0->sense = !b0->sense;
+	b1->sense = !b1->sense;
+	merge(b1, b0);
+	b1->sense = !b1->sense;
+	b1->head = b0->head;
+}
+
+void
+gen_or(b0, b1)
+	struct block *b0, *b1;
+{
+	b0->sense = !b0->sense;
+	backpatch(b0, b1->head);
+	b0->sense = !b0->sense;
+	merge(b1, b0);
+	b1->head = b0->head;
+}
+
+void
+gen_not(b)
+	struct block *b;
+{
+	b->sense = !b->sense;
+}
+
+static struct block *
+gen_cmp(offset, size, v)
+	u_int offset, size;
+	bpf_int32 v;
+{
+	struct slist *s;
+	struct block *b;
+
+	s = new_stmt(BPF_LD|BPF_ABS|size);
+	s->s.k = offset;
+
+	b = new_block(JMP(BPF_JEQ));
+	b->stmts = s;
+	b->s.k = v;
+
+	return b;
+}
+
+static struct block *
+gen_mcmp(offset, size, v, mask)
+	u_int offset, size;
+	bpf_int32 v;
+	bpf_u_int32 mask;
+{
+	struct block *b = gen_cmp(offset, size, v);
+	struct slist *s;
+
+	if (mask != 0xffffffff) {
+		s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+		s->s.k = mask;
+		b->stmts->next = s;
+	}
+	return b;
+}
+
+static struct block *
+gen_bcmp(offset, size, v)
+	u_int offset, size;
+	u_char *v;
+{
+	struct block *b, *tmp;
+
+	b = NULL;
+	while (size >= 4) {
+		u_char *p = &v[size - 4];
+		bpf_int32 w = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+		tmp = gen_cmp(offset + size - 4, BPF_W, w);
+		if (b != NULL)
+			gen_and(b, tmp);
+		b = tmp;
+		size -= 4;
+	}
+	while (size >= 2) {
+		u_char *p = &v[size - 2];
+		bpf_int32 w = (p[0] << 8) | p[1];
+		tmp = gen_cmp(offset + size - 2, BPF_H, w);
+		if (b != NULL)
+			gen_and(b, tmp);
+		b = tmp;
+		size -= 2;
+	}
+	if (size > 0) {
+		tmp = gen_cmp(offset, BPF_B, (bpf_int32)v[0]);
+		if (b != NULL)
+			gen_and(b, tmp);
+		b = tmp;
+	}
+	return b;
+}
+
+/*
+ * Various code constructs need to know the layout of the data link
+ * layer.  These variables give the necessary offsets.  off_linktype
+ * is set to -1 for no encapsulation, in which case, IP is assumed.
+ */
+static u_int off_linktype;
+static u_int off_nl;
+static int linktype;
+
+static void
+init_linktype(type)
+	int type;
+{
+	linktype = type;
+
+	switch (type) {
+
+	case DLT_EN10MB:
+		off_linktype = 12;
+		off_nl = 14;
+		return;
+
+	case DLT_SLIP:
+		/*
+		 * SLIP doesn't have a link level type.  The 16 byte
+		 * header is hacked into our SLIP driver.
+		 */
+		off_linktype = -1;
+		off_nl = 16;
+		return;
+
+	case DLT_NULL:
+		off_linktype = -1;
+		off_nl = 0;
+		return;
+
+	case DLT_PPP:
+		off_linktype = 2;
+		off_nl = 4;
+		return;
+
+	case DLT_FDDI:
+		/*
+		 * FDDI doesn't really have a link-level type field.
+		 * We assume that SSAP = SNAP is being used and pick
+		 * out the encapsulated Ethernet type.
+		 */
+		off_linktype = 19;
+#ifdef PCAP_FDDIPAD
+		off_linktype += pcap_fddipad;
+#endif
+		off_nl = 21;
+#ifdef PCAP_FDDIPAD
+		off_nl += pcap_fddipad;
+#endif
+		return;
+
+	case DLT_IEEE802:
+		off_linktype = 20;
+		off_nl = 22;
+		return;
+
+	case DLT_ATM_RFC1483:
+		/*
+		 * assume routed, non-ISO PDUs
+		 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
+		 */
+		off_linktype = 6;
+		off_nl = 8;
+		return;
+	}
+	bpf_error("unknown data link type 0x%x", linktype);
+	/* NOTREACHED */
+}
+
+static struct block *
+gen_uncond(rsense)
+	int rsense;
+{
+	struct block *b;
+	struct slist *s;
+
+	s = new_stmt(BPF_LD|BPF_IMM);
+	s->s.k = !rsense;
+	b = new_block(JMP(BPF_JEQ));
+	b->stmts = s;
+
+	return b;
+}
+
+static __inline struct block *
+gen_true()
+{
+	return gen_uncond(1);
+}
+
+static __inline struct block *
+gen_false()
+{
+	return gen_uncond(0);
+}
+
+static struct block *
+gen_linktype(proto)
+	int proto;
+{
+	switch (linktype) {
+	case DLT_SLIP:
+		if (proto == ETHERTYPE_IP)
+			return gen_true();
+		else
+			return gen_false();
+
+	case DLT_PPP:
+		if (proto == ETHERTYPE_IP)
+			proto = 0x0021;		/* XXX - need ppp.h defs */
+		break;
+
+	case DLT_NULL:
+		/* XXX */
+		if (proto == ETHERTYPE_IP)
+			return (gen_cmp(0, BPF_W, (bpf_int32)AF_INET));
+		else
+			return gen_false();
+	}
+	return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
+}
+
+static struct block *
+gen_hostop(addr, mask, dir, proto, src_off, dst_off)
+	bpf_u_int32 addr;
+	bpf_u_int32 mask;
+	int dir, proto;
+	u_int src_off, dst_off;
+{
+	struct block *b0, *b1;
+	u_int offset;
+
+	switch (dir) {
+
+	case Q_SRC:
+		offset = src_off;
+		break;
+
+	case Q_DST:
+		offset = dst_off;
+		break;
+
+	case Q_AND:
+		b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
+		b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
+		gen_and(b0, b1);
+		return b1;
+
+	case Q_OR:
+	case Q_DEFAULT:
+		b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
+		b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
+		gen_or(b0, b1);
+		return b1;
+
+	default:
+		abort();
+	}
+	b0 = gen_linktype(proto);
+	b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask);
+	gen_and(b0, b1);
+	return b1;
+}
+
+static struct block *
+gen_ehostop(eaddr, dir)
+	u_char *eaddr;
+	int dir;
+{
+	struct block *b0, *b1;
+
+	switch (dir) {
+	case Q_SRC:
+		return gen_bcmp(6, 6, eaddr);
+
+	case Q_DST:
+		return gen_bcmp(0, 6, eaddr);
+
+	case Q_AND:
+		b0 = gen_ehostop(eaddr, Q_SRC);
+		b1 = gen_ehostop(eaddr, Q_DST);
+		gen_and(b0, b1);
+		return b1;
+
+	case Q_DEFAULT:
+	case Q_OR:
+		b0 = gen_ehostop(eaddr, Q_SRC);
+		b1 = gen_ehostop(eaddr, Q_DST);
+		gen_or(b0, b1);
+		return b1;
+	}
+	abort();
+	/* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for DLT_FDDI
+ */
+static struct block *
+gen_fhostop(eaddr, dir)
+	u_char *eaddr;
+	int dir;
+{
+	struct block *b0, *b1;
+
+	switch (dir) {
+	case Q_SRC:
+#ifdef PCAP_FDDIPAD
+		return gen_bcmp(6 + 1 + pcap_fddipad, 6, eaddr);
+#else
+		return gen_bcmp(6 + 1, 6, eaddr);
+#endif
+
+	case Q_DST:
+#ifdef PCAP_FDDIPAD
+		return gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr);
+#else
+		return gen_bcmp(0 + 1, 6, eaddr);
+#endif
+
+	case Q_AND:
+		b0 = gen_fhostop(eaddr, Q_SRC);
+		b1 = gen_fhostop(eaddr, Q_DST);
+		gen_and(b0, b1);
+		return b1;
+
+	case Q_DEFAULT:
+	case Q_OR:
+		b0 = gen_fhostop(eaddr, Q_SRC);
+		b1 = gen_fhostop(eaddr, Q_DST);
+		gen_or(b0, b1);
+		return b1;
+	}
+	abort();
+	/* NOTREACHED */
+}
+
+/*
+ * This is quite tricky because there may be pad bytes in front of the
+ * DECNET header, and then there are two possible data packet formats that
+ * carry both src and dst addresses, plus 5 packet types in a format that
+ * carries only the src node, plus 2 types that use a different format and
+ * also carry just the src node.
+ *
+ * Yuck.
+ *
+ * Instead of doing those all right, we just look for data packets with
+ * 0 or 1 bytes of padding.  If you want to look at other packets, that
+ * will require a lot more hacking.
+ *
+ * To add support for filtering on DECNET "areas" (network numbers)
+ * one would want to add a "mask" argument to this routine.  That would
+ * make the filter even more inefficient, although one could be clever
+ * and not generate masking instructions if the mask is 0xFFFF.
+ */
+static struct block *
+gen_dnhostop(addr, dir, base_off)
+	bpf_u_int32 addr;
+	int dir;
+	u_int base_off;
+{
+	struct block *b0, *b1, *b2, *tmp;
+	u_int offset_lh;	/* offset if long header is received */
+	u_int offset_sh;	/* offset if short header is received */
+
+	switch (dir) {
+
+	case Q_DST:
+		offset_sh = 1;	/* follows flags */
+		offset_lh = 7;	/* flgs,darea,dsubarea,HIORD */
+		break;
+
+	case Q_SRC:
+		offset_sh = 3;	/* follows flags, dstnode */
+		offset_lh = 15;	/* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
+		break;
+
+	case Q_AND:
+		/* Inefficient because we do our Calvinball dance twice */
+		b0 = gen_dnhostop(addr, Q_SRC, base_off);
+		b1 = gen_dnhostop(addr, Q_DST, base_off);
+		gen_and(b0, b1);
+		return b1;
+
+	case Q_OR:
+	case Q_DEFAULT:
+		/* Inefficient because we do our Calvinball dance twice */
+		b0 = gen_dnhostop(addr, Q_SRC, base_off);
+		b1 = gen_dnhostop(addr, Q_DST, base_off);
+		gen_or(b0, b1);
+		return b1;
+
+	default:
+		abort();
+	}
+	b0 = gen_linktype(ETHERTYPE_DN);
+	/* Check for pad = 1, long header case */
+	tmp = gen_mcmp(base_off + 2, BPF_H,
+	    (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF));
+	b1 = gen_cmp(base_off + 2 + 1 + offset_lh,
+	    BPF_H, (bpf_int32)ntohs(addr));
+	gen_and(tmp, b1);
+	/* Check for pad = 0, long header case */
+	tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7);
+	b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr));
+	gen_and(tmp, b2);
+	gen_or(b2, b1);
+	/* Check for pad = 1, short header case */
+	tmp = gen_mcmp(base_off + 2, BPF_H,
+	    (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF));
+	b2 = gen_cmp(base_off + 2 + 1 + offset_sh,
+	    BPF_H, (bpf_int32)ntohs(addr));
+	gen_and(tmp, b2);
+	gen_or(b2, b1);
+	/* Check for pad = 0, short header case */
+	tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7);
+	b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr));
+	gen_and(tmp, b2);
+	gen_or(b2, b1);
+
+	/* Combine with test for linktype */
+	gen_and(b0, b1);
+	return b1;
+}
+
+static struct block *
+gen_host(addr, mask, proto, dir)
+	bpf_u_int32 addr;
+	bpf_u_int32 mask;
+	int proto;
+	int dir;
+{
+	struct block *b0, *b1;
+
+	switch (proto) {
+
+	case Q_DEFAULT:
+		b0 = gen_host(addr, mask, Q_IP, dir);
+		b1 = gen_host(addr, mask, Q_ARP, dir);
+		gen_or(b0, b1);
+		b0 = gen_host(addr, mask, Q_RARP, dir);
+		gen_or(b1, b0);
+		return b0;
+
+	case Q_IP:
+		return gen_hostop(addr, mask, dir, ETHERTYPE_IP,
+				  off_nl + 12, off_nl + 16);
+
+	case Q_RARP:
+		return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP,
+				  off_nl + 14, off_nl + 24);
+
+	case Q_ARP:
+		return gen_hostop(addr, mask, dir, ETHERTYPE_ARP,
+				  off_nl + 14, off_nl + 24);
+
+	case Q_TCP:
+		bpf_error("'tcp' modifier applied to host");
+
+	case Q_UDP:
+		bpf_error("'udp' modifier applied to host");
+
+	case Q_ICMP:
+		bpf_error("'icmp' modifier applied to host");
+
+	case Q_IGMP:
+		bpf_error("'igmp' modifier applied to host");
+
+	case Q_DECNET:
+		return gen_dnhostop(addr, dir, off_nl);
+
+	case Q_LAT:
+		bpf_error("LAT host filtering not implemented");
+
+	case Q_MOPDL:
+		bpf_error("MOPDL host filtering not implemented");
+
+	case Q_MOPRC:
+		bpf_error("MOPRC host filtering not implemented");
+
+	default:
+		abort();
+	}
+	/* NOTREACHED */
+}
+
+static struct block *
+gen_gateway(eaddr, alist, proto, dir)
+	u_char *eaddr;
+	bpf_u_int32 **alist;
+	int proto;
+	int dir;
+{
+	struct block *b0, *b1, *tmp;
+
+	if (dir != 0)
+		bpf_error("direction applied to 'gateway'");
+
+	switch (proto) {
+	case Q_DEFAULT:
+	case Q_IP:
+	case Q_ARP:
+	case Q_RARP:
+		if (linktype == DLT_EN10MB)
+			b0 = gen_ehostop(eaddr, Q_OR);
+		else if (linktype == DLT_FDDI)
+			b0 = gen_fhostop(eaddr, Q_OR);
+		else
+			bpf_error(
+			    "'gateway' supported only on ethernet or FDDI");
+
+		b1 = gen_host(**alist++, 0xffffffffL, proto, Q_OR);
+		while (*alist) {
+			tmp = gen_host(**alist++, 0xffffffffL, proto, Q_OR);
+			gen_or(b1, tmp);
+			b1 = tmp;
+		}
+		gen_not(b1);
+		gen_and(b0, b1);
+		return b1;
+	}
+	bpf_error("illegal modifier of 'gateway'");
+	/* NOTREACHED */
+}
+
+struct block *
+gen_proto_abbrev(proto)
+	int proto;
+{
+	struct block *b0, *b1;
+
+	switch (proto) {
+
+	case Q_TCP:
+		b0 = gen_linktype(ETHERTYPE_IP);
+		b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_TCP);
+		gen_and(b0, b1);
+		break;
+
+	case Q_UDP:
+		b0 =  gen_linktype(ETHERTYPE_IP);
+		b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_UDP);
+		gen_and(b0, b1);
+		break;
+
+	case Q_ICMP:
+		b0 =  gen_linktype(ETHERTYPE_IP);
+		b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_ICMP);
+		gen_and(b0, b1);
+		break;
+
+	case Q_IGMP:
+		b0 =  gen_linktype(ETHERTYPE_IP);
+		b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)2);
+		gen_and(b0, b1);
+		break;
+
+	case Q_IP:
+		b1 =  gen_linktype(ETHERTYPE_IP);
+		break;
+
+	case Q_ARP:
+		b1 =  gen_linktype(ETHERTYPE_ARP);
+		break;
+
+	case Q_RARP:
+		b1 =  gen_linktype(ETHERTYPE_REVARP);
+		break;
+
+	case Q_LINK:
+		bpf_error("link layer applied in wrong context");
+
+	case Q_DECNET:
+		b1 =  gen_linktype(ETHERTYPE_DN);
+		break;
+
+	case Q_LAT:
+		b1 =  gen_linktype(ETHERTYPE_LAT);
+		break;
+
+	case Q_MOPDL:
+		b1 =  gen_linktype(ETHERTYPE_MOPDL);
+		break;
+
+	case Q_MOPRC:
+		b1 =  gen_linktype(ETHERTYPE_MOPRC);
+		break;
+
+	default:
+		abort();
+	}
+	return b1;
+}
+
+static struct block *
+gen_ipfrag()
+{
+	struct slist *s;
+	struct block *b;
+
+	/* not ip frag */
+	s = new_stmt(BPF_LD|BPF_H|BPF_ABS);
+	s->s.k = off_nl + 6;
+	b = new_block(JMP(BPF_JSET));
+	b->s.k = 0x1fff;
+	b->stmts = s;
+	gen_not(b);
+
+	return b;
+}
+
+static struct block *
+gen_portatom(off, v)
+	int off;
+	bpf_int32 v;
+{
+	struct slist *s;
+	struct block *b;
+
+	s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+	s->s.k = off_nl;
+
+	s->next = new_stmt(BPF_LD|BPF_IND|BPF_H);
+	s->next->s.k = off_nl + off;
+
+	b = new_block(JMP(BPF_JEQ));
+	b->stmts = s;
+	b->s.k = v;
+
+	return b;
+}
+
+struct block *
+gen_portop(port, proto, dir)
+	int port, proto, dir;
+{
+	struct block *b0, *b1, *tmp;
+
+	/* ip proto 'proto' */
+	tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto);
+	b0 = gen_ipfrag();
+	gen_and(tmp, b0);
+
+	switch (dir) {
+	case Q_SRC:
+		b1 = gen_portatom(0, (bpf_int32)port);
+		break;
+
+	case Q_DST:
+		b1 = gen_portatom(2, (bpf_int32)port);
+		break;
+
+	case Q_OR:
+	case Q_DEFAULT:
+		tmp = gen_portatom(0, (bpf_int32)port);
+		b1 = gen_portatom(2, (bpf_int32)port);
+		gen_or(tmp, b1);
+		break;
+
+	case Q_AND:
+		tmp = gen_portatom(0, (bpf_int32)port);
+		b1 = gen_portatom(2, (bpf_int32)port);
+		gen_and(tmp, b1);
+		break;
+
+	default:
+		abort();
+	}
+	gen_and(b0, b1);
+
+	return b1;
+}
+
+static struct block *
+gen_port(port, ip_proto, dir)
+	int port;
+	int ip_proto;
+	int dir;
+{
+	struct block *b0, *b1, *tmp;
+
+	/* ether proto ip */
+	b0 =  gen_linktype(ETHERTYPE_IP);
+
+	switch (ip_proto) {
+	case IPPROTO_UDP:
+	case IPPROTO_TCP:
+		b1 = gen_portop(port, ip_proto, dir);
+		break;
+
+	case PROTO_UNDEF:
+		tmp = gen_portop(port, IPPROTO_TCP, dir);
+		b1 = gen_portop(port, IPPROTO_UDP, dir);
+		gen_or(tmp, b1);
+		break;
+
+	default:
+		abort();
+	}
+	gen_and(b0, b1);
+	return b1;
+}
+
+static int
+lookup_proto(name, proto)
+	char *name;
+	int proto;
+{
+	int v;
+
+	switch (proto) {
+	case Q_DEFAULT:
+	case Q_IP:
+		v = pcap_nametoproto(name);
+		if (v == PROTO_UNDEF)
+			bpf_error("unknown ip proto '%s'", name);
+		break;
+
+	case Q_LINK:
+		/* XXX should look up h/w protocol type based on linktype */
+		v = pcap_nametoeproto(name);
+		if (v == PROTO_UNDEF)
+			bpf_error("unknown ether proto '%s'", name);
+		break;
+
+	default:
+		v = PROTO_UNDEF;
+		break;
+	}
+	return v;
+}
+
+static struct block *
+gen_proto(v, proto, dir)
+	int v;
+	int proto;
+	int dir;
+{
+	struct block *b0, *b1;
+
+	if (dir != Q_DEFAULT)
+		bpf_error("direction applied to 'proto'");
+
+	switch (proto) {
+	case Q_DEFAULT:
+	case Q_IP:
+		b0 = gen_linktype(ETHERTYPE_IP);
+		b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v);
+		gen_and(b0, b1);
+		return b1;
+
+	case Q_ARP:
+		bpf_error("arp does not encapsulate another protocol");
+		/* NOTREACHED */
+
+	case Q_RARP:
+		bpf_error("rarp does not encapsulate another protocol");
+		/* NOTREACHED */
+
+	case Q_DECNET:
+		bpf_error("decnet encapsulation is not specifiable");
+		/* NOTREACHED */
+
+	case Q_LAT:
+		bpf_error("lat does not encapsulate another protocol");
+		/* NOTREACHED */
+
+	case Q_MOPRC:
+		bpf_error("moprc does not encapsulate another protocol");
+		/* NOTREACHED */
+
+	case Q_MOPDL:
+		bpf_error("mopdl does not encapsulate another protocol");
+		/* NOTREACHED */
+
+	case Q_LINK:
+		return gen_linktype(v);
+
+	case Q_UDP:
+		bpf_error("'udp proto' is bogus");
+		/* NOTREACHED */
+
+	case Q_TCP:
+		bpf_error("'tcp proto' is bogus");
+		/* NOTREACHED */
+
+	case Q_ICMP:
+		bpf_error("'icmp proto' is bogus");
+		/* NOTREACHED */
+
+	case Q_IGMP:
+		bpf_error("'igmp proto' is bogus");
+		/* NOTREACHED */
+
+	default:
+		abort();
+		/* NOTREACHED */
+	}
+	/* NOTREACHED */
+}
+
+/*
+ * Left justify 'addr' and return its resulting network mask.
+ */
+static bpf_u_int32
+net_mask(addr)
+	bpf_u_int32 *addr;
+{
+	register bpf_u_int32 m = 0xffffffff;
+
+	if (*addr)
+		while ((*addr & 0xff000000) == 0)
+			*addr <<= 8, m <<= 8;
+
+	return m;
+}
+
+struct block *
+gen_scode(name, q)
+	char *name;
+	struct qual q;
+{
+	int proto = q.proto;
+	int dir = q.dir;
+	u_char *eaddr;
+	bpf_u_int32 mask, addr, **alist;
+	struct block *b, *tmp;
+	int port, real_proto;
+
+	switch (q.addr) {
+
+	case Q_NET:
+		addr = pcap_nametonetaddr(name);
+		if (addr == 0)
+			bpf_error("unknown network '%s'", name);
+		mask = net_mask(&addr);
+		return gen_host(addr, mask, proto, dir);
+
+	case Q_DEFAULT:
+	case Q_HOST:
+		if (proto == Q_LINK) {
+			switch (linktype) {
+
+			case DLT_EN10MB:
+				eaddr = pcap_ether_hostton(name);
+				if (eaddr == NULL)
+					bpf_error(
+					    "unknown ether host '%s'", name);
+				return gen_ehostop(eaddr, dir);
+
+			case DLT_FDDI:
+				eaddr = pcap_ether_hostton(name);
+				if (eaddr == NULL)
+					bpf_error(
+					    "unknown FDDI host '%s'", name);
+				return gen_fhostop(eaddr, dir);
+
+			default:
+				bpf_error(
+			"only ethernet/FDDI supports link-level host name");
+				break;
+			}
+		} else if (proto == Q_DECNET) {
+			unsigned short dn_addr = __pcap_nametodnaddr(name);
+			/*
+			 * I don't think DECNET hosts can be multihomed, so
+			 * there is no need to build up a list of addresses
+			 */
+			return (gen_host(dn_addr, 0, proto, dir));
+		} else {
+			alist = pcap_nametoaddr(name);
+			if (alist == NULL || *alist == NULL)
+				bpf_error("unknown host '%s'", name);
+			b = gen_host(**alist++, 0xffffffffL, proto, dir);
+			while (*alist) {
+				tmp = gen_host(**alist++, 0xffffffffL,
+					       proto, dir);
+				gen_or(b, tmp);
+				b = tmp;
+			}
+			return b;
+		}
+
+	case Q_PORT:
+		if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP)
+			bpf_error("illegal qualifier of 'port'");
+		if (pcap_nametoport(name, &port, &real_proto) == 0)
+			bpf_error("unknown port '%s'", name);
+		if (proto == Q_UDP) {
+			if (real_proto == IPPROTO_TCP)
+				bpf_error("port '%s' is tcp", name);
+			else
+				/* override PROTO_UNDEF */
+				real_proto = IPPROTO_UDP;
+		}
+		if (proto == Q_TCP) {
+			if (real_proto == IPPROTO_UDP)
+				bpf_error("port '%s' is udp", name);
+			else
+				/* override PROTO_UNDEF */
+				real_proto = IPPROTO_TCP;
+		}
+		return gen_port(port, real_proto, dir);
+
+	case Q_GATEWAY:
+		eaddr = pcap_ether_hostton(name);
+		if (eaddr == NULL)
+			bpf_error("unknown ether host: %s", name);
+
+		alist = pcap_nametoaddr(name);
+		if (alist == NULL || *alist == NULL)
+			bpf_error("unknown host '%s'", name);
+		return gen_gateway(eaddr, alist, proto, dir);
+
+	case Q_PROTO:
+		real_proto = lookup_proto(name, proto);
+		if (real_proto >= 0)
+			return gen_proto(real_proto, proto, dir);
+		else
+			bpf_error("unknown protocol: %s", name);
+
+	case Q_UNDEF:
+		syntax();
+		/* NOTREACHED */
+	}
+	abort();
+	/* NOTREACHED */
+}
+
+struct block *
+gen_ncode(v, q)
+	bpf_u_int32 v;
+	struct qual q;
+{
+	bpf_u_int32 mask;
+	int proto = q.proto;
+	int dir = q.dir;
+
+	switch (q.addr) {
+
+	case Q_DEFAULT:
+	case Q_HOST:
+	case Q_NET:
+		if (proto == Q_DECNET)
+			return gen_host(v, 0, proto, dir);
+		else if (proto == Q_LINK) {
+			bpf_error("illegal link layer address");
+		} else {
+			mask = net_mask(&v);
+			return gen_host(v, mask, proto, dir);
+		}
+
+	case Q_PORT:
+		if (proto == Q_UDP)
+			proto = IPPROTO_UDP;
+		else if (proto == Q_TCP)
+			proto = IPPROTO_TCP;
+		else if (proto == Q_DEFAULT)
+			proto = PROTO_UNDEF;
+		else
+			bpf_error("illegal qualifier of 'port'");
+
+		return gen_port((int)v, proto, dir);
+
+	case Q_GATEWAY:
+		bpf_error("'gateway' requires a name");
+		/* NOTREACHED */
+
+	case Q_PROTO:
+		return gen_proto((int)v, proto, dir);
+
+	case Q_UNDEF:
+		syntax();
+		/* NOTREACHED */
+
+	default:
+		abort();
+		/* NOTREACHED */
+	}
+	/* NOTREACHED */
+}
+
+struct block *
+gen_ecode(eaddr, q)
+	u_char *eaddr;
+	struct qual q;
+{
+	if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
+		if (linktype == DLT_EN10MB)
+			return gen_ehostop(eaddr, (int)q.dir);
+		if (linktype == DLT_FDDI)
+			return gen_fhostop(eaddr, (int)q.dir);
+	}
+	bpf_error("ethernet address used in non-ether expression");
+	/* NOTREACHED */
+}
+
+void
+sappend(s0, s1)
+	struct slist *s0, *s1;
+{
+	/*
+	 * This is definitely not the best way to do this, but the
+	 * lists will rarely get long.
+	 */
+	while (s0->next)
+		s0 = s0->next;
+	s0->next = s1;
+}
+
+static struct slist *
+xfer_to_x(a)
+	struct arth *a;
+{
+	struct slist *s;
+
+	s = new_stmt(BPF_LDX|BPF_MEM);
+	s->s.k = a->regno;
+	return s;
+}
+
+static struct slist *
+xfer_to_a(a)
+	struct arth *a;
+{
+	struct slist *s;
+
+	s = new_stmt(BPF_LD|BPF_MEM);
+	s->s.k = a->regno;
+	return s;
+}
+
+struct arth *
+gen_load(proto, index, size)
+	int proto;
+	struct arth *index;
+	int size;
+{
+	struct slist *s, *tmp;
+	struct block *b;
+	int regno = alloc_reg();
+
+	free_reg(index->regno);
+	switch (size) {
+
+	default:
+		bpf_error("data size must be 1, 2, or 4");
+
+	case 1:
+		size = BPF_B;
+		break;
+
+	case 2:
+		size = BPF_H;
+		break;
+
+	case 4:
+		size = BPF_W;
+		break;
+	}
+	switch (proto) {
+	default:
+		bpf_error("unsupported index operation");
+
+	case Q_LINK:
+		s = xfer_to_x(index);
+		tmp = new_stmt(BPF_LD|BPF_IND|size);
+		sappend(s, tmp);
+		sappend(index->s, s);
+		break;
+
+	case Q_IP:
+	case Q_ARP:
+	case Q_RARP:
+	case Q_DECNET:
+	case Q_LAT:
+	case Q_MOPRC:
+	case Q_MOPDL:
+		/* XXX Note that we assume a fixed link link header here. */
+		s = xfer_to_x(index);
+		tmp = new_stmt(BPF_LD|BPF_IND|size);
+		tmp->s.k = off_nl;
+		sappend(s, tmp);
+		sappend(index->s, s);
+
+		b = gen_proto_abbrev(proto);
+		if (index->b)
+			gen_and(index->b, b);
+		index->b = b;
+		break;
+
+	case Q_TCP:
+	case Q_UDP:
+	case Q_ICMP:
+	case Q_IGMP:
+		s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+		s->s.k = off_nl;
+		sappend(s, xfer_to_a(index));
+		sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
+		sappend(s, new_stmt(BPF_MISC|BPF_TAX));
+		sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));
+		tmp->s.k = off_nl;
+		sappend(index->s, s);
+
+		gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
+		if (index->b)
+			gen_and(index->b, b);
+		index->b = b;
+		break;
+	}
+	index->regno = regno;
+	s = new_stmt(BPF_ST);
+	s->s.k = regno;
+	sappend(index->s, s);
+
+	return index;
+}
+
+struct block *
+gen_relation(code, a0, a1, reversed)
+	int code;
+	struct arth *a0, *a1;
+	int reversed;
+{
+	struct slist *s0, *s1, *s2;
+	struct block *b, *tmp;
+
+	s0 = xfer_to_x(a1);
+	s1 = xfer_to_a(a0);
+	s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
+	b = new_block(JMP(code));
+	if (code == BPF_JGT || code == BPF_JGE) {
+		reversed = !reversed;
+		b->s.k = 0x80000000;
+	}
+	if (reversed)
+		gen_not(b);
+
+	sappend(s1, s2);
+	sappend(s0, s1);
+	sappend(a1->s, s0);
+	sappend(a0->s, a1->s);
+
+	b->stmts = a0->s;
+
+	free_reg(a0->regno);
+	free_reg(a1->regno);
+
+	/* 'and' together protocol checks */
+	if (a0->b) {
+		if (a1->b) {
+			gen_and(a0->b, tmp = a1->b);
+		}
+		else
+			tmp = a0->b;
+	} else
+		tmp = a1->b;
+
+	if (tmp)
+		gen_and(tmp, b);
+
+	return b;
+}
+
+struct arth *
+gen_loadlen()
+{
+	int regno = alloc_reg();
+	struct arth *a = (struct arth *)newchunk(sizeof(*a));
+	struct slist *s;
+
+	s = new_stmt(BPF_LD|BPF_LEN);
+	s->next = new_stmt(BPF_ST);
+	s->next->s.k = regno;
+	a->s = s;
+	a->regno = regno;
+
+	return a;
+}
+
+struct arth *
+gen_loadi(val)
+	int val;
+{
+	struct arth *a;
+	struct slist *s;
+	int reg;
+
+	a = (struct arth *)newchunk(sizeof(*a));
+
+	reg = alloc_reg();
+
+	s = new_stmt(BPF_LD|BPF_IMM);
+	s->s.k = val;
+	s->next = new_stmt(BPF_ST);
+	s->next->s.k = reg;
+	a->s = s;
+	a->regno = reg;
+
+	return a;
+}
+
+struct arth *
+gen_neg(a)
+	struct arth *a;
+{
+	struct slist *s;
+
+	s = xfer_to_a(a);
+	sappend(a->s, s);
+	s = new_stmt(BPF_ALU|BPF_NEG);
+	s->s.k = 0;
+	sappend(a->s, s);
+	s = new_stmt(BPF_ST);
+	s->s.k = a->regno;
+	sappend(a->s, s);
+
+	return a;
+}
+
+struct arth *
+gen_arth(code, a0, a1)
+	int code;
+	struct arth *a0, *a1;
+{
+	struct slist *s0, *s1, *s2;
+
+	s0 = xfer_to_x(a1);
+	s1 = xfer_to_a(a0);
+	s2 = new_stmt(BPF_ALU|BPF_X|code);
+
+	sappend(s1, s2);
+	sappend(s0, s1);
+	sappend(a1->s, s0);
+	sappend(a0->s, a1->s);
+
+	free_reg(a1->regno);
+
+	s0 = new_stmt(BPF_ST);
+	a0->regno = s0->s.k = alloc_reg();
+	sappend(a0->s, s0);
+
+	return a0;
+}
+
+/*
+ * Here we handle simple allocation of the scratch registers.
+ * If too many registers are alloc'd, the allocator punts.
+ */
+static int regused[BPF_MEMWORDS];
+static int curreg;
+
+/*
+ * Return the next free register.
+ */
+static int
+alloc_reg()
+{
+	int n = BPF_MEMWORDS;
+
+	while (--n >= 0) {
+		if (regused[curreg])
+			curreg = (curreg + 1) % BPF_MEMWORDS;
+		else {
+			regused[curreg] = 1;
+			return curreg;
+		}
+	}
+	bpf_error("too many registers needed to evaluate expression");
+	/* NOTREACHED */
+}
+
+/*
+ * Return a register to the table so it can
+ * be used later.
+ */
+static void
+free_reg(n)
+	int n;
+{
+	regused[n] = 0;
+}
+
+static struct block *
+gen_len(jmp, n)
+	int jmp, n;
+{
+	struct slist *s;
+	struct block *b;
+
+	s = new_stmt(BPF_LD|BPF_LEN);
+	b = new_block(JMP(jmp));
+	b->stmts = s;
+	b->s.k = n;
+
+	return b;
+}
+
+struct block *
+gen_greater(n)
+	int n;
+{
+	return gen_len(BPF_JGE, n);
+}
+
+struct block *
+gen_less(n)
+	int n;
+{
+	struct block *b;
+
+	b = gen_len(BPF_JGT, n);
+	gen_not(b);
+
+	return b;
+}
+
+struct block *
+gen_byteop(op, idx, val)
+	int op, idx, val;
+{
+	struct block *b;
+	struct slist *s;
+
+	switch (op) {
+	default:
+		abort();
+
+	case '=':
+		return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
+
+	case '<':
+		b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
+		b->s.code = JMP(BPF_JGE);
+		gen_not(b);
+		return b;
+
+	case '>':
+		b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
+		b->s.code = JMP(BPF_JGT);
+		return b;
+
+	case '|':
+		s = new_stmt(BPF_ALU|BPF_OR|BPF_K);
+		break;
+
+	case '&':
+		s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+		break;
+	}
+	s->s.k = val;
+	b = new_block(JMP(BPF_JEQ));
+	b->stmts = s;
+	gen_not(b);
+
+	return b;
+}
+
+struct block *
+gen_broadcast(proto)
+	int proto;
+{
+	bpf_u_int32 hostmask;
+	struct block *b0, *b1, *b2;
+	static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	switch (proto) {
+
+	case Q_DEFAULT:
+	case Q_LINK:
+		if (linktype == DLT_EN10MB)
+			return gen_ehostop(ebroadcast, Q_DST);
+		if (linktype == DLT_FDDI)
+			return gen_fhostop(ebroadcast, Q_DST);
+		bpf_error("not a broadcast link");
+		break;
+
+	case Q_IP:
+		b0 = gen_linktype(ETHERTYPE_IP);
+		hostmask = ~netmask;
+		b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask);
+		b2 = gen_mcmp(off_nl + 16, BPF_W,
+			      (bpf_int32)(~0 & hostmask), hostmask);
+		gen_or(b1, b2);
+		gen_and(b0, b2);
+		return b2;
+	}
+	bpf_error("only ether/ip broadcast filters supported");
+}
+
+struct block *
+gen_multicast(proto)
+	int proto;
+{
+	register struct block *b0, *b1;
+	register struct slist *s;
+
+	switch (proto) {
+
+	case Q_DEFAULT:
+	case Q_LINK:
+		if (linktype == DLT_EN10MB) {
+			/* ether[0] & 1 != 0 */
+			s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+			s->s.k = 0;
+			b0 = new_block(JMP(BPF_JSET));
+			b0->s.k = 1;
+			b0->stmts = s;
+			return b0;
+		}
+
+		if (linktype == DLT_FDDI) {
+			/* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */
+			/* fddi[1] & 1 != 0 */
+			s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+			s->s.k = 1;
+			b0 = new_block(JMP(BPF_JSET));
+			b0->s.k = 1;
+			b0->stmts = s;
+			return b0;
+		}
+		/* Link not known to support multicasts */
+		break;
+
+	case Q_IP:
+		b0 = gen_linktype(ETHERTYPE_IP);
+		b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224);
+		b1->s.code = JMP(BPF_JGE);
+		gen_and(b0, b1);
+		return b1;
+	}
+	bpf_error("only IP multicast filters supported on ethernet/FDDI");
+}
+
+/*
+ * generate command for inbound/outbound.  It's here so we can
+ * make it link-type specific.  'dir' = 0 implies "inbound",
+ * = 1 implies "outbound".
+ */
+struct block *
+gen_inbound(dir)
+	int dir;
+{
+	register struct block *b0;
+
+	b0 = gen_relation(BPF_JEQ,
+			  gen_load(Q_LINK, gen_loadi(0), 1),
+			  gen_loadi(0),
+			  dir);
+	return (b0);
+}
diff --git a/pcap/gencode.h b/pcap/gencode.h
new file mode 100644
index 0000000..33cb995
--- /dev/null
+++ b/pcap/gencode.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: gencode.h,v 1.4 1996/07/12 13:19:08 mickey Exp $	*/
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: gencode.h,v 1.33 96/06/23 02:21:09 leres Exp (LBL)
+ */
+
+/* Address qualifiers. */
+
+#define Q_HOST		1
+#define Q_NET		2
+#define Q_PORT		3
+#define Q_GATEWAY	4
+#define Q_PROTO		5
+
+/* Protocol qualifiers. */
+
+#define Q_LINK		1
+#define Q_IP		2
+#define Q_ARP		3
+#define Q_RARP		4
+#define Q_TCP		5
+#define Q_UDP		6
+#define Q_ICMP		7
+#define Q_IGMP		8
+
+#define	Q_DECNET	9
+#define	Q_LAT		10
+#define	Q_MOPRC		11
+#define	Q_MOPDL		12
+
+/* Directional qualifiers. */
+
+#define Q_SRC		1
+#define Q_DST		2
+#define Q_OR		3
+#define Q_AND		4
+
+#define Q_DEFAULT	0
+#define Q_UNDEF		255
+
+struct stmt {
+	int code;
+	bpf_int32 k;
+};
+
+struct slist {
+	struct stmt s;
+	struct slist *next;
+};
+
+/* 
+ * A bit vector to represent definition sets.  We assume TOT_REGISTERS
+ * is smaller than 8*sizeof(atomset).
+ */
+typedef bpf_u_int32 atomset;
+#define ATOMMASK(n) (1 << (n))
+#define ATOMELEM(d, n) (d & ATOMMASK(n))
+
+/*
+ * An unbounded set.
+ */
+typedef bpf_u_int32 *uset;
+
+/*
+ * Total number of atomic entities, including accumulator (A) and index (X).
+ * We treat all these guys similarly during flow analysis.
+ */
+#define N_ATOMS (BPF_MEMWORDS+2)
+
+struct edge {
+	int id;
+	int code;
+	uset edom;
+	struct block *succ;
+	struct block *pred;
+	struct edge *next;	/* link list of incoming edges for a node */
+};
+
+struct block {
+	int id;
+	struct slist *stmts;	/* side effect stmts */
+	struct stmt s;		/* branch stmt */
+	int mark;
+	int longjt;		/* jt branch requires long jump */
+	int longjf;		/* jf branch requires long jump */
+	int level;
+	int offset;
+	int sense;
+	struct edge et;
+	struct edge ef;
+	struct block *head;
+	struct block *link;	/* link field used by optimizer */
+	uset dom;
+	uset closure;
+	struct edge *in_edges;
+	atomset def, kill;
+	atomset in_use;
+	atomset out_use;
+	int oval;
+	int val[N_ATOMS];
+};
+
+struct arth {
+	struct block *b;	/* protocol checks */
+	struct slist *s;	/* stmt list */
+	int regno;		/* virtual register number of result */
+};
+
+struct qual {
+	unsigned char addr;
+	unsigned char proto;
+	unsigned char dir;
+	unsigned char pad;
+};
+
+struct arth *gen_loadi(int);
+struct arth *gen_load(int, struct arth *, int);
+struct arth *gen_loadlen(void);
+struct arth *gen_neg(struct arth *);
+struct arth *gen_arth(int, struct arth *, struct arth *);
+
+void gen_and(struct block *, struct block *);
+void gen_or(struct block *, struct block *);
+void gen_not(struct block *);
+
+struct block *gen_scode(char *, struct qual);
+struct block *gen_ecode(u_char *, struct qual);
+struct block *gen_ncode(bpf_u_int32, struct qual);
+struct block *gen_proto_abbrev(int);
+struct block *gen_relation(int, struct arth *, struct arth *, int);
+struct block *gen_less(int);
+struct block *gen_greater(int);
+struct block *gen_byteop(int, int, int);
+struct block *gen_broadcast(int);
+struct block *gen_multicast(int);
+struct block *gen_inbound(int);
+
+void bpf_optimize(struct block **);
+#if __STDC__
+__dead void bpf_error(const char *, ...)
+    __attribute__((volatile, format (printf, 1, 2)));
+#endif
+
+void finish_parse(struct block *);
+char *sdup(char *);
+
+struct bpf_insn *icode_to_fcode(struct block *, int *);
+int pcap_parse(void);
+void lex_init(char *);
+void sappend(struct slist *, struct slist *);
+
+/* XXX */
+#define JT(b)  ((b)->et.succ)
+#define JF(b)  ((b)->ef.succ)
diff --git a/pcap/grammar.y b/pcap/grammar.y
new file mode 100644
index 0000000..529ca97
--- /dev/null
+++ b/pcap/grammar.y
@@ -0,0 +1,280 @@
+%{
+/*	$OpenBSD: grammar.y,v 1.4 1996/07/12 13:19:09 mickey Exp $	*/
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+#ifndef lint
+static char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/pcap/grammar.y,v 1.1.1.1 1999/05/02 03:57:54 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+
+#include <net/if.h>
+#include <net/bpf.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <stdio.h>
+#include <pcap.h>
+#include <pcap-namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+#include "gencode.h"
+
+#define QSET(q, p, d, a) (q).proto = (p),\
+			 (q).dir = (d),\
+			 (q).addr = (a)
+
+int n_errors = 0;
+
+static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
+
+static void
+yyerror(char *msg)
+{
+	++n_errors;
+	bpf_error(msg);
+	/* NOTREACHED */
+}
+
+#ifndef YYBISON
+int yyparse(void);
+
+int
+pcap_parse()
+{
+	return (yyparse());
+}
+#endif
+
+%}
+
+%union {
+	int i;
+	u_long h;
+	u_char *e;
+	char *s;
+	struct stmt *stmt;
+	struct arth *a;
+	struct {
+		struct qual q;
+		struct block *b;
+	} blk;
+	struct block *rblk;
+}
+
+%type	<blk>	expr id nid pid term rterm qid
+%type	<blk>	head
+%type	<i>	pqual dqual aqual ndaqual
+%type	<a>	arth narth
+%type	<i>	byteop pname pnum relop irelop
+%type	<blk>	and or paren not null prog
+%type	<rblk>	other
+
+%token  DST SRC HOST GATEWAY
+%token  NET PORT LESS GREATER PROTO BYTE
+%token  ARP RARP IP TCP UDP ICMP IGMP
+%token  DECNET LAT MOPRC MOPDL
+%token  TK_BROADCAST TK_MULTICAST
+%token  NUM INBOUND OUTBOUND
+%token  LINK
+%token	GEQ LEQ NEQ
+%token	ID EID HID
+%token	LSH RSH
+%token  LEN
+
+%type	<s> ID
+%type	<e> EID
+%type	<h> HID
+%type	<i> NUM
+
+%left OR AND
+%nonassoc  '!'
+%left '|'
+%left '&'
+%left LSH RSH
+%left '+' '-'
+%left '*' '/'
+%nonassoc UMINUS
+%%
+prog:	  null expr
+{
+	finish_parse($2.b);
+}
+	| null
+	;
+null:	  /* null */		{ $$.q = qerr; }
+	;
+expr:	  term
+	| expr and term		{ gen_and($1.b, $3.b); $$ = $3; }
+	| expr and id		{ gen_and($1.b, $3.b); $$ = $3; }
+	| expr or term		{ gen_or($1.b, $3.b); $$ = $3; }
+	| expr or id		{ gen_or($1.b, $3.b); $$ = $3; }
+	;
+and:	  AND			{ $$ = $<blk>0; }
+	;
+or:	  OR			{ $$ = $<blk>0; }
+	;
+id:	  nid
+	| pnum			{ $$.b = gen_ncode((u_long)$1,
+						   $$.q = $<blk>0.q); }
+	| paren pid ')'		{ $$ = $2; }
+	;
+nid:	  ID			{ $$.b = gen_scode($1, $$.q = $<blk>0.q); }
+	| HID			{
+				  /* Decide how to parse HID based on proto */
+				  $$.q = $<blk>0.q;
+				  switch ($$.q.proto) {
+				  case Q_DECNET:
+					$$.b =
+					    gen_ncode(__pcap_atodn((char *)$1),
+					    $$.q);
+					break;
+				  default:
+					$$.b =
+					    gen_ncode(__pcap_atoin((char *)$1),
+					    $$.q);
+					break;
+				  }
+				}
+	| EID			{ $$.b = gen_ecode($1, $$.q = $<blk>0.q); }
+	| not id		{ gen_not($2.b); $$ = $2; }
+	;
+not:	  '!'			{ $$ = $<blk>0; }
+	;
+paren:	  '('			{ $$ = $<blk>0; }
+	;
+pid:	  nid
+	| qid and id		{ gen_and($1.b, $3.b); $$ = $3; }
+	| qid or id		{ gen_or($1.b, $3.b); $$ = $3; }
+	;
+qid:	  pnum			{ $$.b = gen_ncode((u_long)$1,
+						   $$.q = $<blk>0.q); }
+	| pid
+	;
+term:	  rterm
+	| not term		{ gen_not($2.b); $$ = $2; }
+	;
+head:	  pqual dqual aqual	{ QSET($$.q, $1, $2, $3); }
+	| pqual dqual		{ QSET($$.q, $1, $2, Q_DEFAULT); }
+	| pqual aqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
+	| pqual PROTO		{ QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
+	| pqual ndaqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
+	;
+rterm:	  head id		{ $$ = $2; }
+	| paren expr ')'	{ $$.b = $2.b; $$.q = $1.q; }
+	| pname			{ $$.b = gen_proto_abbrev($1); $$.q = qerr; }
+	| arth relop arth	{ $$.b = gen_relation($2, $1, $3, 0);
+				  $$.q = qerr; }
+	| arth irelop arth	{ $$.b = gen_relation($2, $1, $3, 1);
+				  $$.q = qerr; }
+	| other			{ $$.b = $1; $$.q = qerr; }
+	;
+/* protocol level qualifiers */
+pqual:	  pname
+	|			{ $$ = Q_DEFAULT; }
+	;
+/* 'direction' qualifiers */
+dqual:	  SRC			{ $$ = Q_SRC; }
+	| DST			{ $$ = Q_DST; }
+	| SRC OR DST		{ $$ = Q_OR; }
+	| DST OR SRC		{ $$ = Q_OR; }
+	| SRC AND DST		{ $$ = Q_AND; }
+	| DST AND SRC		{ $$ = Q_AND; }
+	;
+/* address type qualifiers */
+aqual:	  HOST			{ $$ = Q_HOST; }
+	| NET			{ $$ = Q_NET; }
+	| PORT			{ $$ = Q_PORT; }
+	;
+/* non-directional address type qualifiers */
+ndaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
+	;
+pname:	  LINK			{ $$ = Q_LINK; }
+	| IP			{ $$ = Q_IP; }
+	| ARP			{ $$ = Q_ARP; }
+	| RARP			{ $$ = Q_RARP; }
+	| TCP			{ $$ = Q_TCP; }
+	| UDP			{ $$ = Q_UDP; }
+	| ICMP			{ $$ = Q_ICMP; }
+	| IGMP			{ $$ = Q_IGMP; }
+	| DECNET		{ $$ = Q_DECNET; }
+	| LAT			{ $$ = Q_LAT; }
+	| MOPDL			{ $$ = Q_MOPDL; }
+	| MOPRC			{ $$ = Q_MOPRC; }
+	;
+other:	  pqual TK_BROADCAST	{ $$ = gen_broadcast($1); }
+	| pqual TK_MULTICAST	{ $$ = gen_multicast($1); }
+	| LESS NUM		{ $$ = gen_less($2); }
+	| GREATER NUM		{ $$ = gen_greater($2); }
+	| BYTE NUM byteop NUM	{ $$ = gen_byteop($3, $2, $4); }
+	| INBOUND		{ $$ = gen_inbound(0); }
+	| OUTBOUND		{ $$ = gen_inbound(1); }
+	;
+relop:	  '>'			{ $$ = BPF_JGT; }
+	| GEQ			{ $$ = BPF_JGE; }
+	| '='			{ $$ = BPF_JEQ; }
+	;
+irelop:	  LEQ			{ $$ = BPF_JGT; }
+	| '<'			{ $$ = BPF_JGE; }
+	| NEQ			{ $$ = BPF_JEQ; }
+	;
+arth:	  pnum			{ $$ = gen_loadi($1); }
+	| narth
+	;
+narth:	  pname '[' arth ']'		{ $$ = gen_load($1, $3, 1); }
+	| pname '[' arth ':' NUM ']'	{ $$ = gen_load($1, $3, $5); }
+	| arth '+' arth			{ $$ = gen_arth(BPF_ADD, $1, $3); }
+	| arth '-' arth			{ $$ = gen_arth(BPF_SUB, $1, $3); }
+	| arth '*' arth			{ $$ = gen_arth(BPF_MUL, $1, $3); }
+	| arth '/' arth			{ $$ = gen_arth(BPF_DIV, $1, $3); }
+	| arth '&' arth			{ $$ = gen_arth(BPF_AND, $1, $3); }
+	| arth '|' arth			{ $$ = gen_arth(BPF_OR, $1, $3); }
+	| arth LSH arth			{ $$ = gen_arth(BPF_LSH, $1, $3); }
+	| arth RSH arth			{ $$ = gen_arth(BPF_RSH, $1, $3); }
+	| '-' arth %prec UMINUS		{ $$ = gen_neg($2); }
+	| paren narth ')'		{ $$ = $2; }
+	| LEN				{ $$ = gen_loadlen(); }
+	;
+byteop:	  '&'			{ $$ = '&'; }
+	| '|'			{ $$ = '|'; }
+	| '<'			{ $$ = '<'; }
+	| '>'			{ $$ = '>'; }
+	| '='			{ $$ = '='; }
+	;
+pnum:	  NUM
+	| paren pnum ')'	{ $$ = $2; }
+	;
+%%
diff --git a/pcap/inet.c b/pcap/inet.c
new file mode 100644
index 0000000..50afec5
--- /dev/null
+++ b/pcap/inet.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: inet.c,v 1.6 1997/01/24 19:17:25 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the Computer Systems
+ *	Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+    "@(#) Header: inet.c,v 1.16 96/06/23 14:28:22 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+
+#include <net/if.h>
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pcap.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+
+/* Not all systems have IFF_LOOPBACK */
+#ifdef IFF_LOOPBACK
+#define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK)
+#else
+#define ISLOOPBACK(p) (strcmp((p)->ifr_name, "lo0") == 0)
+#endif
+
+/*
+ * Return the name of a network interface attached to the system, or NULL
+ * if none can be found.  The interface must be configured up; the
+ * lowest unit number is preferred; loopback is ignored.
+ */
+char *
+pcap_lookupdev(errbuf)
+	register char *errbuf;
+{
+	register int fd, minunit, n;
+	register char *cp, *ibuf = NULL;
+	register struct ifreq *ifrp, *ifend, *ifnext, *mp;
+	struct ifconf ifc;
+	struct ifreq ifr;
+	static char device[sizeof(ifrp->ifr_name) + 1];
+	int len = 8192;
+
+	fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (fd < 0) {
+		(void)sprintf(errbuf, "socket: %s", pcap_strerror(errno));
+		return (NULL);
+	}
+	while (1) {
+		ifc.ifc_len = len;
+		ifc.ifc_buf = ibuf = realloc(ibuf, len);
+		if (ibuf == NULL) {
+			close(fd);
+			return (NULL);
+		}
+		if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0) {
+			(void)close(fd);
+			free(ibuf);
+			return (NULL);
+		}
+		if (ifc.ifc_len + sizeof(ifr) < len)
+			break;
+		len *= 2;
+	}
+
+	ifrp = (struct ifreq *)ibuf;
+	ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
+
+	mp = NULL;
+	minunit = 666;
+	for (; ifrp < ifend; ifrp = ifnext) {
+#if BSD - 0 >= 199006
+		n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
+		if (n < sizeof(*ifrp))
+			ifnext = ifrp + 1;
+		else
+			ifnext = (struct ifreq *)((char *)ifrp + n);
+		if (ifrp->ifr_addr.sa_family != AF_INET)
+			continue;
+#else
+		ifnext = ifrp + 1;
+#endif
+		/*
+		 * Need a template to preserve address info that is
+		 * used below to locate the next entry.  (Otherwise,
+		 * SIOCGIFFLAGS stomps over it because the requests
+		 * are returned in a union.)
+		 */
+		strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
+		if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
+			(void)sprintf(errbuf, "SIOCGIFFLAGS: %s",
+			    pcap_strerror(errno));
+			(void)close(fd);
+			free(ibuf);
+			return (NULL);
+		}
+
+		/* Must be up and not the loopback */
+		if ((ifr.ifr_flags & IFF_UP) == 0 || ISLOOPBACK(&ifr))
+			continue;
+
+		for (cp = ifrp->ifr_name; !isdigit(*cp); ++cp)
+			continue;
+		n = atoi(cp);
+		if (n < minunit) {
+			minunit = n;
+			mp = ifrp;
+		}
+	}
+	free(ibuf);
+	(void)close(fd);
+	if (mp == NULL) {
+		(void)strcpy(errbuf, "no suitable device found");
+		return (NULL);
+	}
+
+	(void)strncpy(device, mp->ifr_name, sizeof(device) - 1);
+	device[sizeof(device) - 1] = '\0';
+	return (device);
+}
+
+int
+pcap_lookupnet(device, netp, maskp, errbuf)
+	register char *device;
+	register bpf_u_int32 *netp, *maskp;
+	register char *errbuf;
+{
+	register int fd;
+	register struct sockaddr_in *sin;
+	struct ifreq ifr;
+
+	fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (fd < 0) {
+		(void)sprintf(errbuf, "socket: %s", pcap_strerror(errno));
+		return (-1);
+	}
+	memset(&ifr, 0, sizeof(ifr));
+#ifdef linux
+	/* XXX Work around Linux kernel bug */
+	ifr.ifr_addr.sa_family = AF_INET;
+#endif
+	(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+	if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
+		(void)sprintf(errbuf, "SIOCGIFADDR: %s: %s",
+		    device, pcap_strerror(errno));
+		(void)close(fd);
+		return (-1);
+	}
+	sin = (struct sockaddr_in *)&ifr.ifr_addr;
+	*netp = sin->sin_addr.s_addr;
+	if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
+		(void)sprintf(errbuf, "SIOCGIFNETMASK: %s: %s",
+		    device, pcap_strerror(errno));
+		(void)close(fd);
+		return (-1);
+	}
+	(void)close(fd);
+	*maskp = sin->sin_addr.s_addr;
+	if (*maskp == 0) {
+		if (IN_CLASSA(*netp))
+			*maskp = IN_CLASSA_NET;
+		else if (IN_CLASSB(*netp))
+			*maskp = IN_CLASSB_NET;
+		else if (IN_CLASSC(*netp))
+			*maskp = IN_CLASSC_NET;
+		else {
+			(void)sprintf(errbuf, "inet class for 0x%x unknown",
+			    *netp);
+			return (-1);
+		}
+	}
+	*netp &= *maskp;
+	return (0);
+}
diff --git a/pcap/nametoaddr.c b/pcap/nametoaddr.c
new file mode 100644
index 0000000..3ce8008
--- /dev/null
+++ b/pcap/nametoaddr.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: nametoaddr.c,v 1.5 1996/09/16 02:33:06 tholo Exp $	*/
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Name to id translation routines used by the scanner.
+ * These functions are not time critical.
+ */
+
+#ifndef lint
+static char rcsid[] =
+    "@(#) Header: nametoaddr.c,v 1.38 96/06/17 02:42:50 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <pcap-namedb.h>
+#include <stdio.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+#include "gencode.h"
+
+#ifndef NTOHL
+#define NTOHL(x) (x) = ntohl(x)
+#define NTOHS(x) (x) = ntohs(x)
+#endif
+
+static __inline int xdtoi(int);
+
+/*
+ *  Convert host name to internet address.
+ *  Return 0 upon failure.
+ */
+bpf_u_int32 **
+pcap_nametoaddr(const char *name)
+{
+#ifndef h_addr
+	static bpf_u_int32 *hlist[2];
+#endif
+	bpf_u_int32 **p;
+	struct hostent *hp;
+
+	if ((hp = gethostbyname(name)) != NULL) {
+#ifndef h_addr
+		hlist[0] = (bpf_u_int32 *)hp->h_addr;
+		NTOHL(hp->h_addr);
+		return hlist;
+#else
+		for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
+			NTOHL(**p);
+		return (bpf_u_int32 **)hp->h_addr_list;
+#endif
+	}
+	else
+		return 0;
+}
+
+/*
+ *  Convert net name to internet address.
+ *  Return 0 upon failure.
+ */
+bpf_u_int32
+pcap_nametonetaddr(const char *name)
+{
+	struct netent *np;
+
+	if ((np = getnetbyname(name)) != NULL)
+		return np->n_net;
+	else
+		return 0;
+}
+
+/*
+ * Convert a port name to its port and protocol numbers.
+ * We assume only TCP or UDP.
+ * Return 0 upon failure.
+ */
+int
+pcap_nametoport(const char *name, int *port, int *proto)
+{
+	struct servent *sp;
+	char *other;
+
+	sp = getservbyname(name, (char *)0);
+	if (sp != NULL) {
+		NTOHS(sp->s_port);
+		*port = sp->s_port;
+		*proto = pcap_nametoproto(sp->s_proto);
+		/*
+		 * We need to check /etc/services for ambiguous entries.
+		 * If we find the ambiguous entry, and it has the
+		 * same port number, change the proto to PROTO_UNDEF
+		 * so both TCP and UDP will be checked.
+		 */
+		if (*proto == IPPROTO_TCP)
+			other = "udp";
+		else
+			other = "tcp";
+
+		sp = getservbyname(name, other);
+		if (sp != 0) {
+			NTOHS(sp->s_port);
+#ifdef notdef
+			if (*port != sp->s_port)
+				/* Can't handle ambiguous names that refer
+				   to different port numbers. */
+				warning("ambiguous port %s in /etc/services",
+					name);
+#endif
+			*proto = PROTO_UNDEF;
+		}
+		return 1;
+	}
+#if defined(ultrix) || defined(__osf__)
+	/* Special hack in case NFS isn't in /etc/services */
+	if (strcmp(name, "nfs") == 0) {
+		*port = 2049;
+		*proto = PROTO_UNDEF;
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+int
+pcap_nametoproto(const char *str)
+{
+	struct protoent *p;
+
+	p = getprotobyname(str);
+	if (p != 0)
+		return p->p_proto;
+	else
+		return PROTO_UNDEF;
+}
+
+#include "ethertype.h"
+
+struct eproto {
+	char *s;
+	u_short p;
+};
+
+/* Static data base of ether protocol types. */
+struct eproto eproto_db[] = {
+	{ "pup", ETHERTYPE_PUP },
+	{ "xns", ETHERTYPE_NS },
+	{ "ip", ETHERTYPE_IP },
+	{ "arp", ETHERTYPE_ARP },
+	{ "rarp", ETHERTYPE_REVARP },
+	{ "sprite", ETHERTYPE_SPRITE },
+	{ "mopdl", ETHERTYPE_MOPDL },
+	{ "moprc", ETHERTYPE_MOPRC },
+	{ "decnet", ETHERTYPE_DN },
+	{ "lat", ETHERTYPE_LAT },
+	{ "lanbridge", ETHERTYPE_LANBRIDGE },
+	{ "vexp", ETHERTYPE_VEXP },
+	{ "vprod", ETHERTYPE_VPROD },
+	{ "atalk", ETHERTYPE_ATALK },
+	{ "atalkarp", ETHERTYPE_AARP },
+	{ "loopback", ETHERTYPE_LOOPBACK },
+	{ "decdts", ETHERTYPE_DECDTS },
+	{ "decdns", ETHERTYPE_DECDNS },
+	{ (char *)0, 0 }
+};
+
+int
+pcap_nametoeproto(const char *s)
+{
+	struct eproto *p = eproto_db;
+
+	while (p->s != 0) {
+		if (strcmp(p->s, s) == 0)
+			return p->p;
+		p += 1;
+	}
+	return PROTO_UNDEF;
+}
+
+/* Hex digit to integer. */
+static __inline int
+xdtoi(c)
+	register int c;
+{
+	if (isdigit(c))
+		return c - '0';
+	else if (islower(c))
+		return c - 'a' + 10;
+	else
+		return c - 'A' + 10;
+}
+
+bpf_u_int32
+__pcap_atoin(const char *s)
+{
+	bpf_u_int32 addr = 0;
+	u_int n;
+
+	while (1) {
+		n = 0;
+		while (*s && *s != '.')
+			n = n * 10 + *s++ - '0';
+		addr <<= 8;
+		addr |= n & 0xff;
+		if (*s == '\0')
+			return addr;
+		++s;
+	}
+	/* NOTREACHED */
+}
+
+bpf_u_int32
+__pcap_atodn(const char *s)
+{
+#define AREASHIFT 10
+#define AREAMASK 0176000
+#define NODEMASK 01777
+
+	bpf_u_int32 addr = 0;
+	u_int node, area;
+
+	if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
+		bpf_error("malformed decnet address '%s'", s);
+
+	addr = (area << AREASHIFT) & AREAMASK;
+	addr |= (node & NODEMASK);
+
+	return(addr);
+}
+
+/*
+ * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
+ * ethernet address.  Assumes 's' is well formed.
+ */
+u_char *
+pcap_ether_aton(const char *s)
+{
+	register u_char *ep, *e;
+	register u_int d;
+
+	e = ep = (u_char *)malloc(6);
+
+	while (*s) {
+		if (*s == ':')
+			s += 1;
+		d = xdtoi(*s++);
+		if (isxdigit(*s)) {
+			d <<= 4;
+			d |= xdtoi(*s++);
+		}
+		*ep++ = d;
+	}
+
+	return (e);
+}
+
+#ifndef HAVE_ETHER_HOSTTON
+/* Roll our own */
+u_char *
+pcap_ether_hostton(const char *name)
+{
+	register struct pcap_etherent *ep;
+	register u_char *ap;
+	static FILE *fp = NULL;
+	static init = 0;
+
+	if (!init) {
+		fp = fopen(PCAP_ETHERS_FILE, "r");
+		++init;
+		if (fp == NULL)
+			return (NULL);
+	} else if (fp == NULL)
+		return (NULL);
+	else
+		rewind(fp);
+	
+	while ((ep = pcap_next_etherent(fp)) != NULL) {
+		if (strcmp(ep->name, name) == 0) {
+			ap = (u_char *)malloc(6);
+			if (ap != NULL) {
+				memcpy(ap, ep->addr, 6);
+				return (ap);
+			}
+			break;
+		}
+	}
+	return (NULL);
+}
+#else
+
+#ifndef sgi
+extern int ether_hostton(char *, struct ether_addr *);
+#endif
+
+/* Use the os supplied routines */
+u_char *
+pcap_ether_hostton(const char *name)
+{
+	register u_char *ap;
+	u_char a[6];
+
+	ap = NULL;
+	if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) {
+		ap = (u_char *)malloc(6);
+		if (ap != NULL)
+			memcpy(ap, a, 6);
+	}
+	return (ap);
+}
+#endif
+
+u_short
+__pcap_nametodnaddr(const char *name)
+{
+#ifdef	DECNETLIB
+	struct nodeent *getnodebyname();
+	struct nodeent *nep;
+	unsigned short res;
+
+	nep = getnodebyname(name);
+	if (nep == ((struct nodeent *)0))
+		bpf_error("unknown decnet host name '%s'\n", name);
+
+	memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
+	return(res);
+#else
+	bpf_error("decnet name support not included, '%s' cannot be translated\n",
+		name);
+#ifdef lint
+	return 0;
+#endif
+#endif
+}
diff --git a/pcap/optimize.c b/pcap/optimize.c
new file mode 100644
index 0000000..e78ce1c
--- /dev/null
+++ b/pcap/optimize.c
@@ -0,0 +1,2029 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: optimize.c,v 1.5 1996/09/16 02:33:07 tholo Exp $	*/
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *  Optimization module for tcpdump intermediate representation.
+ */
+#ifndef lint
+static char rcsid[] =
+    "@(#) Header: optimize.c,v 1.58 96/06/16 22:36:59 leres Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <net/bpf.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+#include "gencode.h"
+
+#ifdef BDEBUG
+extern int dflag;
+#endif
+
+#define A_ATOM BPF_MEMWORDS
+#define X_ATOM (BPF_MEMWORDS+1)
+
+#define NOP -1
+
+/*
+ * This define is used to represent *both* the accumulator and
+ * x register in use-def computations.
+ * Currently, the use-def code assumes only one definition per instruction.
+ */
+#define AX_ATOM N_ATOMS
+
+/*
+ * A flag to indicate that further optimization is needed.
+ * Iterative passes are continued until a given pass yields no
+ * branch movement.
+ */
+static int done;
+
+/*
+ * A block is marked if only if its mark equals the current mark.
+ * Rather than traverse the code array, marking each item, 'cur_mark' is
+ * incremented.  This automatically makes each element unmarked.
+ */
+static int cur_mark;
+#define isMarked(p) ((p)->mark == cur_mark)
+#define unMarkAll() cur_mark += 1
+#define Mark(p) ((p)->mark = cur_mark)
+
+static void opt_init(struct block *);
+static void opt_cleanup(void);
+
+static void make_marks(struct block *);
+static void mark_code(struct block *);
+
+static void intern_blocks(struct block *);
+
+static int eq_slist(struct slist *, struct slist *);
+
+static void find_levels_r(struct block *);
+
+static void find_levels(struct block *);
+static void find_dom(struct block *);
+static void propedom(struct edge *);
+static void find_edom(struct block *);
+static void find_closure(struct block *);
+static int atomuse(struct stmt *);
+static int atomdef(struct stmt *);
+static void compute_local_ud(struct block *);
+static void find_ud(struct block *);
+static void init_val(void);
+static int F(int, int, int);
+static __inline void vstore(struct stmt *, int *, int, int);
+static void opt_blk(struct block *, int);
+static int use_conflict(struct block *, struct block *);
+static void opt_j(struct edge *);
+static void or_pullup(struct block *);
+static void and_pullup(struct block *);
+static void opt_blks(struct block *, int);
+static __inline void link_inedge(struct edge *, struct block *);
+static void find_inedges(struct block *);
+static void opt_root(struct block **);
+static void opt_loop(struct block *, int);
+static void fold_op(struct stmt *, int, int);
+static __inline struct slist *this_op(struct slist *);
+static void opt_not(struct block *);
+static void opt_peep(struct block *);
+static void opt_stmt(struct stmt *, int[], int);
+static void deadstmt(struct stmt *, struct stmt *[]);
+static void opt_deadstores(struct block *);
+static void opt_blk(struct block *, int);
+static int use_conflict(struct block *, struct block *);
+static void opt_j(struct edge *);
+static struct block *fold_edge(struct block *, struct edge *);
+static __inline int eq_blk(struct block *, struct block *);
+static int slength(struct slist *);
+static int count_blocks(struct block *);
+static void number_blks_r(struct block *);
+static int count_stmts(struct block *);
+static int convert_code_r(struct block *);
+#ifdef BDEBUG
+static void opt_dump(struct block *);
+#endif
+
+static int n_blocks;
+struct block **blocks;
+static int n_edges;
+struct edge **edges;
+
+/*
+ * A bit vector set representation of the dominators.
+ * We round up the set size to the next power of two.
+ */
+static int nodewords;
+static int edgewords;
+struct block **levels;
+bpf_u_int32 *space;
+#define BITS_PER_WORD (8*sizeof(bpf_u_int32))
+/*
+ * True if a is in uset {p}
+ */
+#define SET_MEMBER(p, a) \
+((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
+
+/*
+ * Add 'a' to uset p.
+ */
+#define SET_INSERT(p, a) \
+(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD))
+
+/*
+ * Delete 'a' from uset p.
+ */
+#define SET_DELETE(p, a) \
+(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
+
+/*
+ * a := a intersect b
+ */
+#define SET_INTERSECT(a, b, n)\
+{\
+	register bpf_u_int32 *_x = a, *_y = b;\
+	register int _n = n;\
+	while (--_n >= 0) *_x++ &= *_y++;\
+}
+
+/*
+ * a := a - b
+ */
+#define SET_SUBTRACT(a, b, n)\
+{\
+	register bpf_u_int32 *_x = a, *_y = b;\
+	register int _n = n;\
+	while (--_n >= 0) *_x++ &=~ *_y++;\
+}
+
+/*
+ * a := a union b
+ */
+#define SET_UNION(a, b, n)\
+{\
+	register bpf_u_int32 *_x = a, *_y = b;\
+	register int _n = n;\
+	while (--_n >= 0) *_x++ |= *_y++;\
+}
+
+static uset all_dom_sets;
+static uset all_closure_sets;
+static uset all_edge_sets;
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
+static void
+find_levels_r(b)
+	struct block *b;
+{
+	int level;
+
+	if (isMarked(b))
+		return;
+
+	Mark(b);
+	b->link = 0;
+
+	if (JT(b)) {
+		find_levels_r(JT(b));
+		find_levels_r(JF(b));
+		level = MAX(JT(b)->level, JF(b)->level) + 1;
+	} else
+		level = 0;
+	b->level = level;
+	b->link = levels[level];
+	levels[level] = b;
+}
+
+/*
+ * Level graph.  The levels go from 0 at the leaves to
+ * N_LEVELS at the root.  The levels[] array points to the
+ * first node of the level list, whose elements are linked
+ * with the 'link' field of the struct block.
+ */
+static void
+find_levels(root)
+	struct block *root;
+{
+	memset((char *)levels, 0, n_blocks * sizeof(*levels));
+	unMarkAll();
+	find_levels_r(root);
+}
+
+/*
+ * Find dominator relationships.
+ * Assumes graph has been leveled.
+ */
+static void
+find_dom(root)
+	struct block *root;
+{
+	int i;
+	struct block *b;
+	bpf_u_int32 *x;
+
+	/*
+	 * Initialize sets to contain all nodes.
+	 */
+	x = all_dom_sets;
+	i = n_blocks * nodewords;
+	while (--i >= 0)
+		*x++ = ~0;
+	/* Root starts off empty. */
+	for (i = nodewords; --i >= 0;)
+		root->dom[i] = 0;
+
+	/* root->level is the highest level no found. */
+	for (i = root->level; i >= 0; --i) {
+		for (b = levels[i]; b; b = b->link) {
+			SET_INSERT(b->dom, b->id);
+			if (JT(b) == 0)
+				continue;
+			SET_INTERSECT(JT(b)->dom, b->dom, nodewords);
+			SET_INTERSECT(JF(b)->dom, b->dom, nodewords);
+		}
+	}
+}
+
+static void
+propedom(ep)
+	struct edge *ep;
+{
+	SET_INSERT(ep->edom, ep->id);
+	if (ep->succ) {
+		SET_INTERSECT(ep->succ->et.edom, ep->edom, edgewords);
+		SET_INTERSECT(ep->succ->ef.edom, ep->edom, edgewords);
+	}
+}
+
+/*
+ * Compute edge dominators.
+ * Assumes graph has been leveled and predecessors established.
+ */
+static void
+find_edom(root)
+	struct block *root;
+{
+	int i;
+	uset x;
+	struct block *b;
+
+	x = all_edge_sets;
+	for (i = n_edges * edgewords; --i >= 0; )
+		x[i] = ~0;
+
+	/* root->level is the highest level no found. */
+	memset(root->et.edom, 0, edgewords * sizeof(*(uset)0));
+	memset(root->ef.edom, 0, edgewords * sizeof(*(uset)0));
+	for (i = root->level; i >= 0; --i) {
+		for (b = levels[i]; b != 0; b = b->link) {
+			propedom(&b->et);
+			propedom(&b->ef);
+		}
+	}
+}
+
+/*
+ * Find the backwards transitive closure of the flow graph.  These sets
+ * are backwards in the sense that we find the set of nodes that reach
+ * a given node, not the set of nodes that can be reached by a node.
+ *
+ * Assumes graph has been leveled.
+ */
+static void
+find_closure(root)
+	struct block *root;
+{
+	int i;
+	struct block *b;
+
+	/*
+	 * Initialize sets to contain no nodes.
+	 */
+	memset((char *)all_closure_sets, 0,
+	      n_blocks * nodewords * sizeof(*all_closure_sets));
+
+	/* root->level is the highest level no found. */
+	for (i = root->level; i >= 0; --i) {
+		for (b = levels[i]; b; b = b->link) {
+			SET_INSERT(b->closure, b->id);
+			if (JT(b) == 0)
+				continue;
+			SET_UNION(JT(b)->closure, b->closure, nodewords);
+			SET_UNION(JF(b)->closure, b->closure, nodewords);
+		}
+	}
+}
+
+/*
+ * Return the register number that is used by s.  If A and X are both
+ * used, return AX_ATOM.  If no register is used, return -1.
+ *
+ * The implementation should probably change to an array access.
+ */
+static int
+atomuse(s)
+	struct stmt *s;
+{
+	register int c = s->code;
+
+	if (c == NOP)
+		return -1;
+
+	switch (BPF_CLASS(c)) {
+
+	case BPF_RET:
+		return (BPF_RVAL(c) == BPF_A) ? A_ATOM :
+			(BPF_RVAL(c) == BPF_X) ? X_ATOM : -1;
+
+	case BPF_LD:
+	case BPF_LDX:
+		return (BPF_MODE(c) == BPF_IND) ? X_ATOM :
+			(BPF_MODE(c) == BPF_MEM) ? s->k : -1;
+
+	case BPF_ST:
+		return A_ATOM;
+
+	case BPF_STX:
+		return X_ATOM;
+
+	case BPF_JMP:
+	case BPF_ALU:
+		if (BPF_SRC(c) == BPF_X)
+			return AX_ATOM;
+		return A_ATOM;
+
+	case BPF_MISC:
+		return BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM;
+	}
+	abort();
+	/* NOTREACHED */
+}
+
+/*
+ * Return the register number that is defined by 's'.  We assume that
+ * a single stmt cannot define more than one register.  If no register
+ * is defined, return -1.
+ *
+ * The implementation should probably change to an array access.
+ */
+static int
+atomdef(s)
+	struct stmt *s;
+{
+	if (s->code == NOP)
+		return -1;
+
+	switch (BPF_CLASS(s->code)) {
+
+	case BPF_LD:
+	case BPF_ALU:
+		return A_ATOM;
+
+	case BPF_LDX:
+		return X_ATOM;
+
+	case BPF_ST:
+	case BPF_STX:
+		return s->k;
+
+	case BPF_MISC:
+		return BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM;
+	}
+	return -1;
+}
+
+static void
+compute_local_ud(b)
+	struct block *b;
+{
+	struct slist *s;
+	atomset def = 0, use = 0, kill = 0;
+	int atom;
+
+	for (s = b->stmts; s; s = s->next) {
+		if (s->s.code == NOP)
+			continue;
+		atom = atomuse(&s->s);
+		if (atom >= 0) {
+			if (atom == AX_ATOM) {
+				if (!ATOMELEM(def, X_ATOM))
+					use |= ATOMMASK(X_ATOM);
+				if (!ATOMELEM(def, A_ATOM))
+					use |= ATOMMASK(A_ATOM);
+			}
+			else if (atom < N_ATOMS) {
+				if (!ATOMELEM(def, atom))
+					use |= ATOMMASK(atom);
+			}
+			else
+				abort();
+		}
+		atom = atomdef(&s->s);
+		if (atom >= 0) {
+			if (!ATOMELEM(use, atom))
+				kill |= ATOMMASK(atom);
+			def |= ATOMMASK(atom);
+		}
+	}
+	if (!ATOMELEM(def, A_ATOM) && BPF_CLASS(b->s.code) == BPF_JMP)
+		use |= ATOMMASK(A_ATOM);
+
+	b->def = def;
+	b->kill = kill;
+	b->in_use = use;
+}
+
+/*
+ * Assume graph is already leveled.
+ */
+static void
+find_ud(root)
+	struct block *root;
+{
+	int i, maxlevel;
+	struct block *p;
+
+	/*
+	 * root->level is the highest level no found;
+	 * count down from there.
+	 */
+	maxlevel = root->level;
+	for (i = maxlevel; i >= 0; --i)
+		for (p = levels[i]; p; p = p->link) {
+			compute_local_ud(p);
+			p->out_use = 0;
+		}
+
+	for (i = 1; i <= maxlevel; ++i) {
+		for (p = levels[i]; p; p = p->link) {
+			p->out_use |= JT(p)->in_use | JF(p)->in_use;
+			p->in_use |= p->out_use &~ p->kill;
+		}
+	}
+}
+
+/*
+ * These data structures are used in a Cocke and Shwarz style
+ * value numbering scheme.  Since the flowgraph is acyclic,
+ * exit values can be propagated from a node's predecessors
+ * provided it is uniquely defined.
+ */
+struct valnode {
+	int code;
+	int v0, v1;
+	int val;
+	struct valnode *next;
+};
+
+#define MODULUS 213
+static struct valnode *hashtbl[MODULUS];
+static int curval;
+static int maxval;
+
+/* Integer constants mapped with the load immediate opcode. */
+#define K(i) F(BPF_LD|BPF_IMM|BPF_W, i, 0L)
+
+struct vmapinfo {
+	int is_const;
+	bpf_int32 const_val;
+};
+
+struct vmapinfo *vmap;
+struct valnode *vnode_base;
+struct valnode *next_vnode;
+
+static void
+init_val()
+{
+	curval = 0;
+	next_vnode = vnode_base;
+	memset((char *)vmap, 0, maxval * sizeof(*vmap));
+	memset((char *)hashtbl, 0, sizeof hashtbl);
+}
+
+/* Because we really don't have an IR, this stuff is a little messy. */
+static int
+F(code, v0, v1)
+	int code;
+	int v0, v1;
+{
+	u_int hash;
+	int val;
+	struct valnode *p;
+
+	hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
+	hash %= MODULUS;
+
+	for (p = hashtbl[hash]; p; p = p->next)
+		if (p->code == code && p->v0 == v0 && p->v1 == v1)
+			return p->val;
+
+	val = ++curval;
+	if (BPF_MODE(code) == BPF_IMM &&
+	    (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) {
+		vmap[val].const_val = v0;
+		vmap[val].is_const = 1;
+	}
+	p = next_vnode++;
+	p->val = val;
+	p->code = code;
+	p->v0 = v0;
+	p->v1 = v1;
+	p->next = hashtbl[hash];
+	hashtbl[hash] = p;
+
+	return val;
+}
+
+static __inline void
+vstore(s, valp, newval, alter)
+	struct stmt *s;
+	int *valp;
+	int newval;
+	int alter;
+{
+	if (alter && *valp == newval)
+		s->code = NOP;
+	else
+		*valp = newval;
+}
+
+static void
+fold_op(s, v0, v1)
+	struct stmt *s;
+	int v0, v1;
+{
+	bpf_int32 a, b;
+
+	a = vmap[v0].const_val;
+	b = vmap[v1].const_val;
+
+	switch (BPF_OP(s->code)) {
+	case BPF_ADD:
+		a += b;
+		break;
+
+	case BPF_SUB:
+		a -= b;
+		break;
+
+	case BPF_MUL:
+		a *= b;
+		break;
+
+	case BPF_DIV:
+		if (b == 0)
+			bpf_error("division by zero");
+		a /= b;
+		break;
+
+	case BPF_AND:
+		a &= b;
+		break;
+
+	case BPF_OR:
+		a |= b;
+		break;
+
+	case BPF_LSH:
+		a <<= b;
+		break;
+
+	case BPF_RSH:
+		a >>= b;
+		break;
+
+	case BPF_NEG:
+		a = -a;
+		break;
+
+	default:
+		abort();
+	}
+	s->k = a;
+	s->code = BPF_LD|BPF_IMM;
+	done = 0;
+}
+
+static __inline struct slist *
+this_op(s)
+	struct slist *s;
+{
+	while (s != 0 && s->s.code == NOP)
+		s = s->next;
+	return s;
+}
+
+static void
+opt_not(b)
+	struct block *b;
+{
+	struct block *tmp = JT(b);
+
+	JT(b) = JF(b);
+	JF(b) = tmp;
+}
+
+static void
+opt_peep(b)
+	struct block *b;
+{
+	struct slist *s;
+	struct slist *next, *last;
+	int val;
+
+	s = b->stmts;
+	if (s == 0)
+		return;
+
+	last = s;
+	while (1) {
+		s = this_op(s);
+		if (s == 0)
+			break;
+		next = this_op(s->next);
+		if (next == 0)
+			break;
+		last = next;
+
+		/*
+		 * st  M[k]	-->	st  M[k]
+		 * ldx M[k]		tax
+		 */
+		if (s->s.code == BPF_ST &&
+		    next->s.code == (BPF_LDX|BPF_MEM) &&
+		    s->s.k == next->s.k) {
+			done = 0;
+			next->s.code = BPF_MISC|BPF_TAX;
+		}
+		/*
+		 * ld  #k	-->	ldx  #k
+		 * tax			txa
+		 */
+		if (s->s.code == (BPF_LD|BPF_IMM) &&
+		    next->s.code == (BPF_MISC|BPF_TAX)) {
+			s->s.code = BPF_LDX|BPF_IMM;
+			next->s.code = BPF_MISC|BPF_TXA;
+			done = 0;
+		}
+		/*
+		 * This is an ugly special case, but it happens
+		 * when you say tcp[k] or udp[k] where k is a constant.
+		 */
+		if (s->s.code == (BPF_LD|BPF_IMM)) {
+			struct slist *add, *tax, *ild;
+
+			/*
+			 * Check that X isn't used on exit from this
+			 * block (which the optimizer might cause).
+			 * We know the code generator won't generate
+			 * any local dependencies.
+			 */
+			if (ATOMELEM(b->out_use, X_ATOM))
+				break;
+
+			if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
+				add = next;
+			else
+				add = this_op(next->next);
+			if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X))
+				break;
+
+			tax = this_op(add->next);
+			if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX))
+				break;
+
+			ild = this_op(tax->next);
+			if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD ||
+			    BPF_MODE(ild->s.code) != BPF_IND)
+				break;
+			/*
+			 * XXX We need to check that X is not
+			 * subsequently used.  We know we can eliminate the
+			 * accumulator modifications since it is defined
+			 * by the last stmt of this sequence.
+			 *
+			 * We want to turn this sequence:
+			 *
+			 * (004) ldi     #0x2		{s}
+			 * (005) ldxms   [14]		{next}  -- optional
+			 * (006) addx			{add}
+			 * (007) tax			{tax}
+			 * (008) ild     [x+0]		{ild}
+			 *
+			 * into this sequence:
+			 *
+			 * (004) nop
+			 * (005) ldxms   [14]
+			 * (006) nop
+			 * (007) nop
+			 * (008) ild     [x+2]
+			 *
+			 */
+			ild->s.k += s->s.k;
+			s->s.code = NOP;
+			add->s.code = NOP;
+			tax->s.code = NOP;
+			done = 0;
+		}
+		s = next;
+	}
+	/*
+	 * If we have a subtract to do a comparison, and the X register
+	 * is a known constant, we can merge this value into the
+	 * comparison.
+	 */
+	if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
+	    !ATOMELEM(b->out_use, A_ATOM)) {
+		val = b->val[X_ATOM];
+		if (vmap[val].is_const) {
+			int op;
+
+			b->s.k += vmap[val].const_val;
+			op = BPF_OP(b->s.code);
+			if (op == BPF_JGT || op == BPF_JGE) {
+				struct block *t = JT(b);
+				JT(b) = JF(b);
+				JF(b) = t;
+				b->s.k += 0x80000000;
+			}
+			last->s.code = NOP;
+			done = 0;
+		} else if (b->s.k == 0) {
+			/*
+			 * sub x  ->	nop
+			 * j  #0	j  x
+			 */
+			last->s.code = NOP;
+			b->s.code = BPF_CLASS(b->s.code) | BPF_OP(b->s.code) |
+				BPF_X;
+			done = 0;
+		}
+	}
+	/*
+	 * Likewise, a constant subtract can be simplified.
+	 */
+	else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
+		 !ATOMELEM(b->out_use, A_ATOM)) {
+		int op;
+
+		b->s.k += last->s.k;
+		last->s.code = NOP;
+		op = BPF_OP(b->s.code);
+		if (op == BPF_JGT || op == BPF_JGE) {
+			struct block *t = JT(b);
+			JT(b) = JF(b);
+			JF(b) = t;
+			b->s.k += 0x80000000;
+		}
+		done = 0;
+	}
+	/*
+	 * and #k	nop
+	 * jeq #0  ->	jset #k
+	 */
+	if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) &&
+	    !ATOMELEM(b->out_use, A_ATOM) && b->s.k == 0) {
+		b->s.k = last->s.k;
+		b->s.code = BPF_JMP|BPF_K|BPF_JSET;
+		last->s.code = NOP;
+		done = 0;
+		opt_not(b);
+	}
+	/*
+	 * If the accumulator is a known constant, we can compute the
+	 * comparison result.
+	 */
+	val = b->val[A_ATOM];
+	if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) {
+		bpf_int32 v = vmap[val].const_val;
+		switch (BPF_OP(b->s.code)) {
+
+		case BPF_JEQ:
+			v = v == b->s.k;
+			break;
+
+		case BPF_JGT:
+			v = (unsigned)v > b->s.k;
+			break;
+
+		case BPF_JGE:
+			v = (unsigned)v >= b->s.k;
+			break;
+
+		case BPF_JSET:
+			v &= b->s.k;
+			break;
+
+		default:
+			abort();
+		}
+		if (JF(b) != JT(b))
+			done = 0;
+		if (v)
+			JF(b) = JT(b);
+		else
+			JT(b) = JF(b);
+	}
+}
+
+/*
+ * Compute the symbolic value of expression of 's', and update
+ * anything it defines in the value table 'val'.  If 'alter' is true,
+ * do various optimizations.  This code would be cleaner if symbolic
+ * evaluation and code transformations weren't folded together.
+ */
+static void
+opt_stmt(s, val, alter)
+	struct stmt *s;
+	int val[];
+	int alter;
+{
+	int op;
+	int v;
+
+	switch (s->code) {
+
+	case BPF_LD|BPF_ABS|BPF_W:
+	case BPF_LD|BPF_ABS|BPF_H:
+	case BPF_LD|BPF_ABS|BPF_B:
+		v = F(s->code, s->k, 0L);
+		vstore(s, &val[A_ATOM], v, alter);
+		break;
+
+	case BPF_LD|BPF_IND|BPF_W:
+	case BPF_LD|BPF_IND|BPF_H:
+	case BPF_LD|BPF_IND|BPF_B:
+		v = val[X_ATOM];
+		if (alter && vmap[v].is_const) {
+			s->code = BPF_LD|BPF_ABS|BPF_SIZE(s->code);
+			s->k += vmap[v].const_val;
+			v = F(s->code, s->k, 0L);
+			done = 0;
+		}
+		else
+			v = F(s->code, s->k, v);
+		vstore(s, &val[A_ATOM], v, alter);
+		break;
+
+	case BPF_LD|BPF_LEN:
+		v = F(s->code, 0L, 0L);
+		vstore(s, &val[A_ATOM], v, alter);
+		break;
+
+	case BPF_LD|BPF_IMM:
+		v = K(s->k);
+		vstore(s, &val[A_ATOM], v, alter);
+		break;
+
+	case BPF_LDX|BPF_IMM:
+		v = K(s->k);
+		vstore(s, &val[X_ATOM], v, alter);
+		break;
+
+	case BPF_LDX|BPF_MSH|BPF_B:
+		v = F(s->code, s->k, 0L);
+		vstore(s, &val[X_ATOM], v, alter);
+		break;
+
+	case BPF_ALU|BPF_NEG:
+		if (alter && vmap[val[A_ATOM]].is_const) {
+			s->code = BPF_LD|BPF_IMM;
+			s->k = -vmap[val[A_ATOM]].const_val;
+			val[A_ATOM] = K(s->k);
+		}
+		else
+			val[A_ATOM] = F(s->code, val[A_ATOM], 0L);
+		break;
+
+	case BPF_ALU|BPF_ADD|BPF_K:
+	case BPF_ALU|BPF_SUB|BPF_K:
+	case BPF_ALU|BPF_MUL|BPF_K:
+	case BPF_ALU|BPF_DIV|BPF_K:
+	case BPF_ALU|BPF_AND|BPF_K:
+	case BPF_ALU|BPF_OR|BPF_K:
+	case BPF_ALU|BPF_LSH|BPF_K:
+	case BPF_ALU|BPF_RSH|BPF_K:
+		op = BPF_OP(s->code);
+		if (alter) {
+			if (s->k == 0) {
+				if (op == BPF_ADD || op == BPF_SUB ||
+				    op == BPF_LSH || op == BPF_RSH ||
+				    op == BPF_OR) {
+					s->code = NOP;
+					break;
+				}
+				if (op == BPF_MUL || op == BPF_AND) {
+					s->code = BPF_LD|BPF_IMM;
+					val[A_ATOM] = K(s->k);
+					break;
+				}
+			}
+			if (vmap[val[A_ATOM]].is_const) {
+				fold_op(s, val[A_ATOM], K(s->k));
+				val[A_ATOM] = K(s->k);
+				break;
+			}
+		}
+		val[A_ATOM] = F(s->code, val[A_ATOM], K(s->k));
+		break;
+
+	case BPF_ALU|BPF_ADD|BPF_X:
+	case BPF_ALU|BPF_SUB|BPF_X:
+	case BPF_ALU|BPF_MUL|BPF_X:
+	case BPF_ALU|BPF_DIV|BPF_X:
+	case BPF_ALU|BPF_AND|BPF_X:
+	case BPF_ALU|BPF_OR|BPF_X:
+	case BPF_ALU|BPF_LSH|BPF_X:
+	case BPF_ALU|BPF_RSH|BPF_X:
+		op = BPF_OP(s->code);
+		if (alter && vmap[val[X_ATOM]].is_const) {
+			if (vmap[val[A_ATOM]].is_const) {
+				fold_op(s, val[A_ATOM], val[X_ATOM]);
+				val[A_ATOM] = K(s->k);
+			}
+			else {
+				s->code = BPF_ALU|BPF_K|op;
+				s->k = vmap[val[X_ATOM]].const_val;
+				done = 0;
+				val[A_ATOM] =
+					F(s->code, val[A_ATOM], K(s->k));
+			}
+			break;
+		}
+		/*
+		 * Check if we're doing something to an accumulator
+		 * that is 0, and simplify.  This may not seem like
+		 * much of a simplification but it could open up further
+		 * optimizations.
+		 * XXX We could also check for mul by 1, and -1, etc.
+		 */
+		if (alter && vmap[val[A_ATOM]].is_const
+		    && vmap[val[A_ATOM]].const_val == 0) {
+			if (op == BPF_ADD || op == BPF_OR ||
+			    op == BPF_LSH || op == BPF_RSH || op == BPF_SUB) {
+				s->code = BPF_MISC|BPF_TXA;
+				vstore(s, &val[A_ATOM], val[X_ATOM], alter);
+				break;
+			}
+			else if (op == BPF_MUL || op == BPF_DIV ||
+				 op == BPF_AND) {
+				s->code = BPF_LD|BPF_IMM;
+				s->k = 0;
+				vstore(s, &val[A_ATOM], K(s->k), alter);
+				break;
+			}
+			else if (op == BPF_NEG) {
+				s->code = NOP;
+				break;
+			}
+		}
+		val[A_ATOM] = F(s->code, val[A_ATOM], val[X_ATOM]);
+		break;
+
+	case BPF_MISC|BPF_TXA:
+		vstore(s, &val[A_ATOM], val[X_ATOM], alter);
+		break;
+
+	case BPF_LD|BPF_MEM:
+		v = val[s->k];
+		if (alter && vmap[v].is_const) {
+			s->code = BPF_LD|BPF_IMM;
+			s->k = vmap[v].const_val;
+			done = 0;
+		}
+		vstore(s, &val[A_ATOM], v, alter);
+		break;
+
+	case BPF_MISC|BPF_TAX:
+		vstore(s, &val[X_ATOM], val[A_ATOM], alter);
+		break;
+
+	case BPF_LDX|BPF_MEM:
+		v = val[s->k];
+		if (alter && vmap[v].is_const) {
+			s->code = BPF_LDX|BPF_IMM;
+			s->k = vmap[v].const_val;
+			done = 0;
+		}
+		vstore(s, &val[X_ATOM], v, alter);
+		break;
+
+	case BPF_ST:
+		vstore(s, &val[s->k], val[A_ATOM], alter);
+		break;
+
+	case BPF_STX:
+		vstore(s, &val[s->k], val[X_ATOM], alter);
+		break;
+	}
+}
+
+static void
+deadstmt(s, last)
+	register struct stmt *s;
+	register struct stmt *last[];
+{
+	register int atom;
+
+	atom = atomuse(s);
+	if (atom >= 0) {
+		if (atom == AX_ATOM) {
+			last[X_ATOM] = 0;
+			last[A_ATOM] = 0;
+		}
+		else
+			last[atom] = 0;
+	}
+	atom = atomdef(s);
+	if (atom >= 0) {
+		if (last[atom]) {
+			done = 0;
+			last[atom]->code = NOP;
+		}
+		last[atom] = s;
+	}
+}
+
+static void
+opt_deadstores(b)
+	register struct block *b;
+{
+	register struct slist *s;
+	register int atom;
+	struct stmt *last[N_ATOMS];
+
+	memset((char *)last, 0, sizeof last);
+
+	for (s = b->stmts; s != 0; s = s->next)
+		deadstmt(&s->s, last);
+	deadstmt(&b->s, last);
+
+	for (atom = 0; atom < N_ATOMS; ++atom)
+		if (last[atom] && !ATOMELEM(b->out_use, atom)) {
+			last[atom]->code = NOP;
+			done = 0;
+		}
+}
+
+static void
+opt_blk(b, do_stmts)
+	struct block *b;
+	int do_stmts;
+{
+	struct slist *s;
+	struct edge *p;
+	int i;
+	bpf_int32 aval;
+
+	/*
+	 * Initialize the atom values.
+	 * If we have no predecessors, everything is undefined.
+	 * Otherwise, we inherent our values from our predecessors.
+	 * If any register has an ambiguous value (i.e. control paths are
+	 * merging) give it the undefined value of 0.
+	 */
+	p = b->in_edges;
+	if (p == 0)
+		memset((char *)b->val, 0, sizeof(b->val));
+	else {
+		memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val));
+		while ((p = p->next) != NULL) {
+			for (i = 0; i < N_ATOMS; ++i)
+				if (b->val[i] != p->pred->val[i])
+					b->val[i] = 0;
+		}
+	}
+	aval = b->val[A_ATOM];
+	for (s = b->stmts; s; s = s->next)
+		opt_stmt(&s->s, b->val, do_stmts);
+
+	/*
+	 * This is a special case: if we don't use anything from this
+	 * block, and we load the accumulator with value that is
+	 * already there, or if this block is a return,
+	 * eliminate all the statements.
+	 */
+	if (do_stmts && 
+	    ((b->out_use == 0 && aval != 0 &&b->val[A_ATOM] == aval) ||
+	     BPF_CLASS(b->s.code) == BPF_RET)) {
+		if (b->stmts != 0) {
+			b->stmts = 0;
+			done = 0;
+		}
+	} else {
+		opt_peep(b);
+		opt_deadstores(b);
+	}
+	/*
+	 * Set up values for branch optimizer.
+	 */
+	if (BPF_SRC(b->s.code) == BPF_K)
+		b->oval = K(b->s.k);
+	else
+		b->oval = b->val[X_ATOM];
+	b->et.code = b->s.code;
+	b->ef.code = -b->s.code;
+}
+
+/*
+ * Return true if any register that is used on exit from 'succ', has
+ * an exit value that is different from the corresponding exit value
+ * from 'b'.
+ */
+static int
+use_conflict(b, succ)
+	struct block *b, *succ;
+{
+	int atom;
+	atomset use = succ->out_use;
+
+	if (use == 0)
+		return 0;
+
+	for (atom = 0; atom < N_ATOMS; ++atom)
+		if (ATOMELEM(use, atom))
+			if (b->val[atom] != succ->val[atom])
+				return 1;
+	return 0;
+}
+
+static struct block *
+fold_edge(child, ep)
+	struct block *child;
+	struct edge *ep;
+{
+	int sense;
+	int aval0, aval1, oval0, oval1;
+	int code = ep->code;
+
+	if (code < 0) {
+		code = -code;
+		sense = 0;
+	} else
+		sense = 1;
+
+	if (child->s.code != code)
+		return 0;
+
+	aval0 = child->val[A_ATOM];
+	oval0 = child->oval;
+	aval1 = ep->pred->val[A_ATOM];
+	oval1 = ep->pred->oval;
+
+	if (aval0 != aval1)
+		return 0;
+
+	if (oval0 == oval1)
+		/*
+		 * The operands are identical, so the
+		 * result is true if a true branch was
+		 * taken to get here, otherwise false.
+		 */
+		return sense ? JT(child) : JF(child);
+
+	if (sense && code == (BPF_JMP|BPF_JEQ|BPF_K))
+		/*
+		 * At this point, we only know the comparison if we
+		 * came down the true branch, and it was an equality
+		 * comparison with a constant.  We rely on the fact that
+		 * distinct constants have distinct value numbers.
+		 */
+		return JF(child);
+
+	return 0;
+}
+
+static void
+opt_j(ep)
+	struct edge *ep;
+{
+	register int i, k;
+	register struct block *target;
+
+	if (JT(ep->succ) == 0)
+		return;
+
+	if (JT(ep->succ) == JF(ep->succ)) {
+		/*
+		 * Common branch targets can be eliminated, provided
+		 * there is no data dependency.
+		 */
+		if (!use_conflict(ep->pred, ep->succ->et.succ)) {
+			done = 0;
+			ep->succ = JT(ep->succ);
+		}
+	}
+	/*
+	 * For each edge dominator that matches the successor of this
+	 * edge, promote the edge successor to the its grandchild.
+	 *
+	 * XXX We violate the set abstraction here in favor a reasonably
+	 * efficient loop.
+	 */
+ top:
+	for (i = 0; i < edgewords; ++i) {
+		register bpf_u_int32 x = ep->edom[i];
+
+		while (x != 0) {
+			k = ffs(x) - 1;
+			x &=~ (1 << k);
+			k += i * BITS_PER_WORD;
+
+			target = fold_edge(ep->succ, edges[k]);
+			/*
+			 * Check that there is no data dependency between
+			 * nodes that will be violated if we move the edge.
+			 */
+			if (target != 0 && !use_conflict(ep->pred, target)) {
+				done = 0;
+				ep->succ = target;
+				if (JT(target) != 0)
+					/*
+					 * Start over unless we hit a leaf.
+					 */
+					goto top;
+				return;
+			}
+		}
+	}
+}
+
+
+static void
+or_pullup(b)
+	struct block *b;
+{
+	int val, at_top;
+	struct block *pull;
+	struct block **diffp, **samep;
+	struct edge *ep;
+
+	ep = b->in_edges;
+	if (ep == 0)
+		return;
+
+	/*
+	 * Make sure each predecessor loads the same value.
+	 * XXX why?
+	 */
+	val = ep->pred->val[A_ATOM];
+	for (ep = ep->next; ep != 0; ep = ep->next)
+		if (val != ep->pred->val[A_ATOM])
+			return;
+
+	if (JT(b->in_edges->pred) == b)
+		diffp = &JT(b->in_edges->pred);
+	else
+		diffp = &JF(b->in_edges->pred);
+
+	at_top = 1;
+	while (1) {
+		if (*diffp == 0)
+			return;
+
+		if (JT(*diffp) != JT(b))
+			return;
+
+		if (!SET_MEMBER((*diffp)->dom, b->id))
+			return;
+
+		if ((*diffp)->val[A_ATOM] != val)
+			break;
+
+		diffp = &JF(*diffp);
+		at_top = 0;
+	}
+	samep = &JF(*diffp);
+	while (1) {
+		if (*samep == 0)
+			return;
+
+		if (JT(*samep) != JT(b))
+			return;
+
+		if (!SET_MEMBER((*samep)->dom, b->id))
+			return;
+
+		if ((*samep)->val[A_ATOM] == val)
+			break;
+
+		/* XXX Need to check that there are no data dependencies
+		   between dp0 and dp1.  Currently, the code generator
+		   will not produce such dependencies. */
+		samep = &JF(*samep);
+	}
+#ifdef notdef
+	/* XXX This doesn't cover everything. */
+	for (i = 0; i < N_ATOMS; ++i)
+		if ((*samep)->val[i] != pred->val[i])
+			return;
+#endif
+	/* Pull up the node. */
+	pull = *samep;
+	*samep = JF(pull);
+	JF(pull) = *diffp;
+
+	/*
+	 * At the top of the chain, each predecessor needs to point at the
+	 * pulled up node.  Inside the chain, there is only one predecessor
+	 * to worry about.
+	 */
+	if (at_top) {
+		for (ep = b->in_edges; ep != 0; ep = ep->next) {
+			if (JT(ep->pred) == b)
+				JT(ep->pred) = pull;
+			else
+				JF(ep->pred) = pull;
+		}
+	}
+	else
+		*diffp = pull;
+
+	done = 0;
+}
+
+static void
+and_pullup(b)
+	struct block *b;
+{
+	int val, at_top;
+	struct block *pull;
+	struct block **diffp, **samep;
+	struct edge *ep;
+
+	ep = b->in_edges;
+	if (ep == 0)
+		return;
+
+	/*
+	 * Make sure each predecessor loads the same value.
+	 */
+	val = ep->pred->val[A_ATOM];
+	for (ep = ep->next; ep != 0; ep = ep->next)
+		if (val != ep->pred->val[A_ATOM])
+			return;
+
+	if (JT(b->in_edges->pred) == b)
+		diffp = &JT(b->in_edges->pred);
+	else
+		diffp = &JF(b->in_edges->pred);
+
+	at_top = 1;
+	while (1) {
+		if (*diffp == 0)
+			return;
+
+		if (JF(*diffp) != JF(b))
+			return;
+
+		if (!SET_MEMBER((*diffp)->dom, b->id))
+			return;
+
+		if ((*diffp)->val[A_ATOM] != val)
+			break;
+
+		diffp = &JT(*diffp);
+		at_top = 0;
+	}
+	samep = &JT(*diffp);
+	while (1) {
+		if (*samep == 0)
+			return;
+
+		if (JF(*samep) != JF(b))
+			return;
+
+		if (!SET_MEMBER((*samep)->dom, b->id))
+			return;
+
+		if ((*samep)->val[A_ATOM] == val)
+			break;
+
+		/* XXX Need to check that there are no data dependencies
+		   between diffp and samep.  Currently, the code generator
+		   will not produce such dependencies. */
+		samep = &JT(*samep);
+	}
+#ifdef notdef
+	/* XXX This doesn't cover everything. */
+	for (i = 0; i < N_ATOMS; ++i)
+		if ((*samep)->val[i] != pred->val[i])
+			return;
+#endif
+	/* Pull up the node. */
+	pull = *samep;
+	*samep = JT(pull);
+	JT(pull) = *diffp;
+
+	/*
+	 * At the top of the chain, each predecessor needs to point at the
+	 * pulled up node.  Inside the chain, there is only one predecessor
+	 * to worry about.
+	 */
+	if (at_top) {
+		for (ep = b->in_edges; ep != 0; ep = ep->next) {
+			if (JT(ep->pred) == b)
+				JT(ep->pred) = pull;
+			else
+				JF(ep->pred) = pull;
+		}
+	}
+	else
+		*diffp = pull;
+
+	done = 0;
+}
+
+static void
+opt_blks(root, do_stmts)
+	struct block *root;
+	int do_stmts;
+{
+	int i, maxlevel;
+	struct block *p;
+
+	init_val();
+	maxlevel = root->level;
+	for (i = maxlevel; i >= 0; --i)
+		for (p = levels[i]; p; p = p->link)
+			opt_blk(p, do_stmts);
+
+	if (do_stmts)
+		/*
+		 * No point trying to move branches; it can't possibly
+		 * make a difference at this point.
+		 */
+		return;
+
+	for (i = 1; i <= maxlevel; ++i) {
+		for (p = levels[i]; p; p = p->link) {
+			opt_j(&p->et);
+			opt_j(&p->ef);
+		}
+	}
+	for (i = 1; i <= maxlevel; ++i) {
+		for (p = levels[i]; p; p = p->link) {
+			or_pullup(p);
+			and_pullup(p);
+		}
+	}
+}
+
+static __inline void
+link_inedge(parent, child)
+	struct edge *parent;
+	struct block *child;
+{
+	parent->next = child->in_edges;
+	child->in_edges = parent;
+}
+
+static void
+find_inedges(root)
+	struct block *root;
+{
+	int i;
+	struct block *b;
+
+	for (i = 0; i < n_blocks; ++i)
+		blocks[i]->in_edges = 0;
+
+	/*
+	 * Traverse the graph, adding each edge to the predecessor
+	 * list of its successors.  Skip the leaves (i.e. level 0).
+	 */
+	for (i = root->level; i > 0; --i) {
+		for (b = levels[i]; b != 0; b = b->link) {
+			link_inedge(&b->et, JT(b));
+			link_inedge(&b->ef, JF(b));
+		}
+	}
+}
+
+static void
+opt_root(b)
+	struct block **b;
+{
+	struct slist *tmp, *s;
+
+	s = (*b)->stmts;
+	(*b)->stmts = 0;
+	while (BPF_CLASS((*b)->s.code) == BPF_JMP && JT(*b) == JF(*b))
+		*b = JT(*b);
+
+	tmp = (*b)->stmts;
+	if (tmp != 0)
+		sappend(s, tmp);
+	(*b)->stmts = s;
+
+	/*
+	 * If the root node is a return, then there is no
+	 * point executing any statements (since the bpf machine
+	 * has no side effects).
+	 */
+	if (BPF_CLASS((*b)->s.code) == BPF_RET)
+		(*b)->stmts = 0;
+}
+
+static void
+opt_loop(root, do_stmts)
+	struct block *root;
+	int do_stmts;
+{
+
+#ifdef BDEBUG
+	if (dflag > 1)
+		opt_dump(root);
+#endif
+	do {
+		done = 1;
+		find_levels(root);
+		find_dom(root);
+		find_closure(root);
+		find_inedges(root);
+		find_ud(root);
+		find_edom(root);
+		opt_blks(root, do_stmts);
+#ifdef BDEBUG
+		if (dflag > 1)
+			opt_dump(root);
+#endif
+	} while (!done);
+}
+
+/*
+ * Optimize the filter code in its dag representation.
+ */
+void
+bpf_optimize(rootp)
+	struct block **rootp;
+{
+	struct block *root;
+
+	root = *rootp;
+
+	opt_init(root);
+	opt_loop(root, 0);
+	opt_loop(root, 1);
+	intern_blocks(root);
+	opt_root(rootp);
+	opt_cleanup();
+}
+
+static void
+make_marks(p)
+	struct block *p;
+{
+	if (!isMarked(p)) {
+		Mark(p);
+		if (BPF_CLASS(p->s.code) != BPF_RET) {
+			make_marks(JT(p));
+			make_marks(JF(p));
+		}
+	}
+}
+
+/*
+ * Mark code array such that isMarked(i) is true
+ * only for nodes that are alive.
+ */
+static void
+mark_code(p)
+	struct block *p;
+{
+	cur_mark += 1;
+	make_marks(p);
+}
+
+/*
+ * True iff the two stmt lists load the same value from the packet into
+ * the accumulator.
+ */
+static int
+eq_slist(x, y)
+	struct slist *x, *y;
+{
+	while (1) {
+		while (x && x->s.code == NOP)
+			x = x->next;
+		while (y && y->s.code == NOP)
+			y = y->next;
+		if (x == 0)
+			return y == 0;
+		if (y == 0)
+			return x == 0;
+		if (x->s.code != y->s.code || x->s.k != y->s.k)
+			return 0;
+		x = x->next;
+		y = y->next;
+	}
+}
+
+static __inline int
+eq_blk(b0, b1)
+	struct block *b0, *b1;
+{
+	if (b0->s.code == b1->s.code &&
+	    b0->s.k == b1->s.k &&
+	    b0->et.succ == b1->et.succ &&
+	    b0->ef.succ == b1->ef.succ)
+		return eq_slist(b0->stmts, b1->stmts);
+	return 0;
+}
+
+static void
+intern_blocks(root)
+	struct block *root;
+{
+	struct block *p;
+	int i, j;
+	int done;
+ top:
+	done = 1;
+	for (i = 0; i < n_blocks; ++i)
+		blocks[i]->link = 0;
+
+	mark_code(root);
+
+	for (i = n_blocks - 1; --i >= 0; ) {
+		if (!isMarked(blocks[i]))
+			continue;
+		for (j = i + 1; j < n_blocks; ++j) {
+			if (!isMarked(blocks[j]))
+				continue;
+			if (eq_blk(blocks[i], blocks[j])) {
+				blocks[i]->link = blocks[j]->link ?
+					blocks[j]->link : blocks[j];
+				break;
+			}
+		}
+	}
+	for (i = 0; i < n_blocks; ++i) {
+		p = blocks[i];
+		if (JT(p) == 0)
+			continue;
+		if (JT(p)->link) {
+			done = 0;
+			JT(p) = JT(p)->link;
+		}
+		if (JF(p)->link) {
+			done = 0;
+			JF(p) = JF(p)->link;
+		}
+	}
+	if (!done)
+		goto top;
+}
+
+static void
+opt_cleanup()
+{
+	free((void *)vnode_base);
+	free((void *)vmap);
+	free((void *)edges);
+	free((void *)space);
+	free((void *)levels);
+	free((void *)blocks);
+}
+
+/*
+ * Return the number of stmts in 's'.
+ */
+static int
+slength(s)
+	struct slist *s;
+{
+	int n = 0;
+
+	for (; s; s = s->next)
+		if (s->s.code != NOP)
+			++n;
+	return n;
+}
+
+/*
+ * Return the number of nodes reachable by 'p'.
+ * All nodes should be initially unmarked.
+ */
+static int
+count_blocks(p)
+	struct block *p;
+{
+	if (p == 0 || isMarked(p))
+		return 0;
+	Mark(p);
+	return count_blocks(JT(p)) + count_blocks(JF(p)) + 1;
+}
+
+/*
+ * Do a depth first search on the flow graph, numbering the
+ * the basic blocks, and entering them into the 'blocks' array.`
+ */
+static void
+number_blks_r(p)
+	struct block *p;
+{
+	int n;
+
+	if (p == 0 || isMarked(p))
+		return;
+
+	Mark(p);
+	n = n_blocks++;
+	p->id = n;
+	blocks[n] = p;
+
+	number_blks_r(JT(p));
+	number_blks_r(JF(p));
+}
+
+/*
+ * Return the number of stmts in the flowgraph reachable by 'p'.
+ * The nodes should be unmarked before calling.
+ */
+static int
+count_stmts(p)
+	struct block *p;
+{
+	int n;
+
+	if (p == 0 || isMarked(p))
+		return 0;
+	Mark(p);
+	n = count_stmts(JT(p)) + count_stmts(JF(p));
+	return slength(p->stmts) + n + 1;
+}
+
+/*
+ * Allocate memory.  All allocation is done before optimization
+ * is begun.  A linear bound on the size of all data structures is computed
+ * from the total number of blocks and/or statements.
+ */
+static void
+opt_init(root)
+	struct block *root;
+{
+	bpf_u_int32 *p;
+	int i, n, max_stmts;
+
+	/*
+	 * First, count the blocks, so we can malloc an array to map
+	 * block number to block.  Then, put the blocks into the array.
+	 */
+	unMarkAll();
+	n = count_blocks(root);
+	blocks = (struct block **)malloc(n * sizeof(*blocks));
+	unMarkAll();
+	n_blocks = 0;
+	number_blks_r(root);
+
+	n_edges = 2 * n_blocks;
+	edges = (struct edge **)malloc(n_edges * sizeof(*edges));
+
+	/*
+	 * The number of levels is bounded by the number of nodes.
+	 */
+	levels = (struct block **)malloc(n_blocks * sizeof(*levels));
+
+	edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1;
+	nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
+
+	/* XXX */
+	space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space)
+				 + n_edges * edgewords * sizeof(*space));
+	p = space;
+	all_dom_sets = p;
+	for (i = 0; i < n; ++i) {
+		blocks[i]->dom = p;
+		p += nodewords;
+	}
+	all_closure_sets = p;
+	for (i = 0; i < n; ++i) {
+		blocks[i]->closure = p;
+		p += nodewords;
+	}
+	all_edge_sets = p;
+	for (i = 0; i < n; ++i) {
+		register struct block *b = blocks[i];
+
+		b->et.edom = p;
+		p += edgewords;
+		b->ef.edom = p;
+		p += edgewords;
+		b->et.id = i;
+		edges[i] = &b->et;
+		b->ef.id = n_blocks + i;
+		edges[n_blocks + i] = &b->ef;
+		b->et.pred = b;
+		b->ef.pred = b;
+	}
+	max_stmts = 0;
+	for (i = 0; i < n; ++i)
+		max_stmts += slength(blocks[i]->stmts) + 1;
+	/*
+	 * We allocate at most 3 value numbers per statement,
+	 * so this is an upper bound on the number of valnodes
+	 * we'll need.
+	 */
+	maxval = 3 * max_stmts;
+	vmap = (struct vmapinfo *)malloc(maxval * sizeof(*vmap));
+	vnode_base = (struct valnode *)malloc(maxval * sizeof(*vmap));
+}
+
+/*
+ * Some pointers used to convert the basic block form of the code,
+ * into the array form that BPF requires.  'fstart' will point to
+ * the malloc'd array while 'ftail' is used during the recursive traversal.
+ */
+static struct bpf_insn *fstart;
+static struct bpf_insn *ftail;
+
+#ifdef BDEBUG
+int bids[1000];
+#endif
+
+/*
+ * Returns true if successful.  Returns false if a branch has
+ * an offset that is too large.  If so, we have marked that
+ * branch so that on a subsequent iteration, it will be treated
+ * properly.
+ */
+static int
+convert_code_r(p)
+	struct block *p;
+{
+	struct bpf_insn *dst;
+	struct slist *src;
+	int slen;
+	u_int off;
+	int extrajmps;		/* number of extra jumps inserted */
+
+	if (p == 0 || isMarked(p))
+		return (1);
+	Mark(p);
+
+	if (convert_code_r(JF(p)) == 0)
+		return (0);
+	if (convert_code_r(JT(p)) == 0)
+		return (0);
+
+	slen = slength(p->stmts);
+	dst = ftail -= (slen + 1 + p->longjt + p->longjf);
+		/* inflate length by any extra jumps */
+
+	p->offset = dst - fstart;
+
+	for (src = p->stmts; src; src = src->next) {
+		if (src->s.code == NOP)
+			continue;
+		dst->code = (u_short)src->s.code;
+		dst->k = src->s.k;
+		++dst;
+	}
+#ifdef BDEBUG
+	bids[dst - fstart] = p->id + 1;
+#endif
+	dst->code = (u_short)p->s.code;
+	dst->k = p->s.k;
+	if (JT(p)) {
+		extrajmps = 0;
+		off = JT(p)->offset - (p->offset + slen) - 1;
+		if (off >= 256) {
+		    /* offset too large for branch, must add a jump */
+		    if (p->longjt == 0) {
+		    	/* mark this instruction and retry */
+			p->longjt++;
+			return(0);
+		    }
+		    /* branch if T to following jump */
+		    dst->jt = extrajmps;
+		    extrajmps++;
+		    dst[extrajmps].code = BPF_JMP|BPF_JA;
+		    dst[extrajmps].k = off - extrajmps;
+		}
+		else
+		    dst->jt = off;
+		off = JF(p)->offset - (p->offset + slen) - 1;
+		if (off >= 256) {
+		    /* offset too large for branch, must add a jump */
+		    if (p->longjf == 0) {
+		    	/* mark this instruction and retry */
+			p->longjf++;
+			return(0);
+		    }
+		    /* branch if F to following jump */
+		    /* if two jumps are inserted, F goes to second one */
+		    dst->jf = extrajmps;
+		    extrajmps++;
+		    dst[extrajmps].code = BPF_JMP|BPF_JA;
+		    dst[extrajmps].k = off - extrajmps;
+		}
+		else
+		    dst->jf = off;
+	}
+	return (1);
+}
+
+
+/*
+ * Convert flowgraph intermediate representation to the
+ * BPF array representation.  Set *lenp to the number of instructions.
+ */
+struct bpf_insn *
+icode_to_fcode(root, lenp)
+	struct block *root;
+	int *lenp;
+{
+	int n;
+	struct bpf_insn *fp;
+
+	/*
+	 * Loop doing convert_codr_r() until no branches remain
+	 * with too-large offsets.
+	 */
+	while (1) {
+	    unMarkAll();
+	    n = *lenp = count_stmts(root);
+    
+	    fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
+	    memset((char *)fp, 0, sizeof(*fp) * n);
+	    fstart = fp;
+	    ftail = fp + n;
+    
+	    unMarkAll();
+	    if (convert_code_r(root))
+		break;
+	    free(fp);
+	}
+
+	return fp;
+}
+
+#ifdef BDEBUG
+static void
+opt_dump(root)
+	struct block *root;
+{
+	struct bpf_program f;
+
+	memset(bids, 0, sizeof bids);
+	f.bf_insns = icode_to_fcode(root, &f.bf_len);
+	bpf_dump(&f, 1);
+	putchar('\n');
+	free((char *)f.bf_insns);
+}
+#endif
diff --git a/pcap/pcap-bpf.c b/pcap/pcap-bpf.c
new file mode 100644
index 0000000..c327b55
--- /dev/null
+++ b/pcap/pcap-bpf.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: pcap-bpf.c,v 1.7 1996/09/16 02:33:08 tholo Exp $	*/
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static  char rcsid[] =
+    "@(#)Header: pcap-bpf.c,v 1.25 96/06/24 02:50:11 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>			/* optionally get BSD define */
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+
+int
+pcap_stats(pcap_t *p, struct pcap_stat *ps)
+{
+	struct bpf_stat s;
+
+	if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
+		sprintf(p->errbuf, "BIOCGSTATS: %s", pcap_strerror(errno));
+		return (-1);
+	}
+
+	ps->ps_recv = s.bs_recv;
+	ps->ps_drop = s.bs_drop;
+	return (0);
+}
+
+int
+pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+	int cc;
+	int n = 0;
+	register u_char *bp, *ep;
+
+ again:
+	cc = p->cc;
+	if (p->cc == 0) {
+		cc = read(p->fd, (char *)p->buffer, p->bufsize);
+		if (cc < 0) {
+			/* Don't choke when we get ptraced */
+			switch (errno) {
+
+			case EINTR:
+				goto again;
+
+			case EWOULDBLOCK:
+				return (0);
+#if defined(sun) && !defined(BSD)
+			/*
+			 * Due to a SunOS bug, after 2^31 bytes, the kernel
+			 * file offset overflows and read fails with EINVAL.
+			 * The lseek() to 0 will fix things.
+			 */
+			case EINVAL:
+				if (lseek(p->fd, 0L, SEEK_CUR) +
+				    p->bufsize < 0) {
+					(void)lseek(p->fd, 0L, SEEK_SET);
+					goto again;
+				}
+				/* fall through */
+#endif
+			}
+			sprintf(p->errbuf, "read: %s", pcap_strerror(errno));
+			return (-1);
+		}
+		bp = p->buffer;
+	} else
+		bp = p->bp;
+
+	/*
+	 * Loop through each packet.
+	 */
+#define bhp ((struct bpf_hdr *)bp)
+	ep = bp + cc;
+	while (bp < ep) {
+		register int caplen, hdrlen;
+		caplen = bhp->bh_caplen;
+		hdrlen = bhp->bh_hdrlen;
+		/*
+		 * XXX A bpf_hdr matches a pcap_pkthdr.
+		 */
+		(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
+		bp += BPF_WORDALIGN(caplen + hdrlen);
+		if (++n >= cnt && cnt > 0) {
+			p->bp = bp;
+			p->cc = ep - bp;
+			return (n);
+		}
+	}
+#undef bhp
+	p->cc = 0;
+	return (n);
+}
+
+int
+pcap_inject(pcap_t *p, const void *buf, size_t len)
+{
+	return (write(p->fd, buf, len));
+}
+
+static __inline int
+bpf_open(pcap_t *p, char *errbuf)
+{
+	int fd;
+	int n = 0;
+	char device[sizeof "/dev/bpf000"];
+
+	/*
+	 * Go through all the minors and find one that isn't in use.
+	 */
+	do {
+		(void)sprintf(device, "/dev/bpf%d", n++);
+		fd = open(device, O_RDONLY);
+	} while (fd < 0 && errno == EBUSY);
+
+	/*
+	 * XXX better message for all minors used
+	 */
+	if (fd < 0)
+		sprintf(errbuf, "%s: %s", device, pcap_strerror(errno));
+
+	return (fd);
+}
+
+pcap_t *
+pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
+{
+	int fd;
+	struct ifreq ifr;
+	struct bpf_version bv;
+	u_int v;
+	pcap_t *p;
+
+	p = (pcap_t *)malloc(sizeof(*p));
+	if (p == NULL) {
+		sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
+		return (NULL);
+	}
+	bzero(p, sizeof(*p));
+	fd = bpf_open(p, ebuf);
+	if (fd < 0)
+		goto bad;
+
+	p->fd = fd;
+	p->snapshot = snaplen;
+
+	if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
+		sprintf(ebuf, "BIOCVERSION: %s", pcap_strerror(errno));
+		goto bad;
+	}
+	if (bv.bv_major != BPF_MAJOR_VERSION ||
+	    bv.bv_minor < BPF_MINOR_VERSION) {
+		sprintf(ebuf, "kernel bpf filter out of date");
+		goto bad;
+	}
+	(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+	if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
+		sprintf(ebuf, "%s: %s", device, pcap_strerror(errno));
+		goto bad;
+	}
+	/* Get the data link layer type. */
+	if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
+		sprintf(ebuf, "BIOCGDLT: %s", pcap_strerror(errno));
+		goto bad;
+	}
+	p->linktype = v;
+
+	/* set timeout */
+	if (to_ms != 0) {
+		struct timeval to;
+		to.tv_sec = to_ms / 1000;
+		to.tv_usec = (to_ms * 1000) % 1000000;
+		if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
+			sprintf(ebuf, "BIOCSRTIMEOUT: %s",
+				pcap_strerror(errno));
+			goto bad;
+		}
+	}
+	if (promisc)
+		/* set promiscuous mode, okay if it fails */
+		(void)ioctl(p->fd, BIOCPROMISC, NULL);
+
+	if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
+		sprintf(ebuf, "BIOCGBLEN: %s", pcap_strerror(errno));
+		goto bad;
+	}
+	p->bufsize = v;
+	p->buffer = (u_char *)malloc(p->bufsize);
+	if (p->buffer == NULL) {
+		sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
+		goto bad;
+	}
+
+	return (p);
+ bad:
+	(void)close(fd);
+	free(p);
+	return (NULL);
+}
+
+int
+pcap_setfilter(pcap_t *p, struct bpf_program *fp)
+{
+	if (p->sf.rfile != NULL)
+		p->fcode = *fp;
+	else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
+		sprintf(p->errbuf, "BIOCSETF: %s", pcap_strerror(errno));
+		return (-1);
+	}
+	return (0);
+}
diff --git a/pcap/pcap-int.h b/pcap/pcap-int.h
new file mode 100644
index 0000000..9513df1
--- /dev/null
+++ b/pcap/pcap-int.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: pcap-int.h,v 1.6 1996/08/03 12:38:44 niklas Exp $	*/
+
+/*
+ * Copyright (c) 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the Computer Systems
+ *	Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: pcap-int.h,v 1.14 95/10/21 22:04:49 leres Exp (LBL)
+ */
+
+#ifndef pcap_int_h
+#define pcap_int_h
+
+#include <pcap.h>
+
+/*
+ * Savefile
+ */
+struct pcap_sf {
+	FILE *rfile;
+	int swapped;
+	int version_major;
+	int version_minor;
+	u_char *base;
+};
+
+struct pcap_md {
+	struct pcap_stat stat;
+	/*XXX*/
+	int use_bpf;
+	u_long	TotPkts;	/* can't oflow for 79 hrs on ether */
+	u_long	TotAccepted;	/* count accepted by filter */
+	u_long	TotDrops;	/* count of dropped packets */
+	long	TotMissed;	/* missed by i/f during this run */
+	long	OrigMissed;	/* missed by i/f before this run */
+};
+
+struct pcap {
+	int fd;
+	int snapshot;
+	int linktype;
+	int tzoff;		/* timezone offset */
+
+	struct pcap_sf sf;
+	struct pcap_md md;
+
+	/*
+	 * Read buffer.
+	 */
+	int bufsize;
+	u_char *buffer;
+	u_char *bp;
+	int cc;
+
+	/*
+	 * Place holder for pcap_next().
+	 */
+	u_char *pkt;
+
+	
+	/*
+	 * Placeholder for filter code if bpf not in kernel.
+	 */
+	struct bpf_program fcode;
+
+	char errbuf[PCAP_ERRBUF_SIZE];
+};
+
+int	yylex(void);
+
+/* XXX should these be in pcap.h? */
+int	pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
+int	pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
+
+/* Ultrix pads to make everything line up on a nice boundary */
+#if defined(ultrix) || defined(__alpha)
+#define       PCAP_FDDIPAD 3
+#endif
+#endif
diff --git a/pcap/pcap-namedb.h b/pcap/pcap-namedb.h
new file mode 100644
index 0000000..d8bf162
--- /dev/null
+++ b/pcap/pcap-namedb.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: pcap-namedb.h,v 1.4 1996/07/12 13:19:11 mickey Exp $	*/
+
+/*
+ * Copyright (c) 1994, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the Computer Systems
+ *	Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: pcap-namedb.h,v 1.4 96/06/23 02:21:08 leres Exp (LBL)
+ */
+
+#ifndef lib_pcap_ethers_h
+#define lib_pcap_ethers_h
+
+/*
+ * As returned by the pcap_next_etherent()
+ * XXX this stuff doesn't belong in this interface, but this
+ * library already must do name to address translation, so
+ * on systems that don't have support for /etc/ethers, we
+ * export these hooks since they'll
+ */
+struct pcap_etherent {
+	u_char addr[6];
+	char name[122];
+};
+#ifndef PCAP_ETHERS_FILE
+#define PCAP_ETHERS_FILE "/etc/ethers"
+#endif
+struct	pcap_etherent *pcap_next_etherent(FILE *);
+u_char *pcap_ether_hostton(const char*);
+u_char *pcap_ether_aton(const char *);
+
+bpf_u_int32 **pcap_nametoaddr(const char *);
+bpf_u_int32 pcap_nametonetaddr(const char *);
+
+int	pcap_nametoport(const char *, int *, int *);
+int	pcap_nametoproto(const char *);
+int	pcap_nametoeproto(const char *);
+/*
+ * If a protocol is unknown, PROTO_UNDEF is returned.
+ * Also, pcap_nametoport() returns the protocol along with the port number.
+ * If there are ambiguous entried in /etc/services (i.e. domain
+ * can be either tcp or udp) PROTO_UNDEF is returned.
+ */
+#define PROTO_UNDEF		-1
+
+/* XXX move these to pcap-int.h? */
+bpf_u_int32 __pcap_atodn(const char *);
+bpf_u_int32 __pcap_atoin(const char *);
+u_short	__pcap_nametodnaddr(const char *);
+
+#endif
diff --git a/pcap/pcap.c b/pcap/pcap.c
new file mode 100644
index 0000000..c34b0b2
--- /dev/null
+++ b/pcap/pcap.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: pcap.c,v 1.4 1996/07/12 13:19:12 mickey Exp $	*/
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the Computer Systems
+ *	Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+    "@(#) Header: pcap.c,v 1.25 96/06/05 21:45:26 leres Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+
+int
+pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+	register int cc;
+
+	if (p->sf.rfile != NULL)
+		return (pcap_offline_read(p, cnt, callback, user));
+	/* XXX keep reading until we get something (or an error occurs) */
+	do {
+		cc = pcap_read(p, cnt, callback, user);
+	} while (cc == 0);
+	return (cc);
+}
+
+int
+pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+	for (;;) {
+		int n = pcap_dispatch(p, cnt, callback, user);
+		if (n <= 0)
+			return (n);
+		if (cnt > 0) {
+			cnt -= n;
+			if (cnt <= 0)
+				return (0);
+		}
+	}
+}
+
+struct singleton {
+	struct pcap_pkthdr *hdr;
+	const u_char *pkt;
+};
+
+
+static void
+pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt)
+{
+	struct singleton *sp = (struct singleton *)userData;
+	*sp->hdr = *h;
+	sp->pkt = pkt;
+}
+
+const u_char *
+pcap_next(pcap_t *p, struct pcap_pkthdr *h)
+{
+	struct singleton s;
+
+	s.hdr = h;
+	if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0)
+		return (0);
+	return (s.pkt);
+}
+
+int
+pcap_datalink(pcap_t *p)
+{
+	return (p->linktype);
+}
+
+int
+pcap_snapshot(pcap_t *p)
+{
+	return (p->snapshot);
+}
+
+int
+pcap_is_swapped(pcap_t *p)
+{
+	return (p->sf.swapped);
+}
+
+int
+pcap_major_version(pcap_t *p)
+{
+	return (p->sf.version_major);
+}
+
+int
+pcap_minor_version(pcap_t *p)
+{
+	return (p->sf.version_minor);
+}
+
+FILE *
+pcap_file(pcap_t *p)
+{
+	return (p->sf.rfile);
+}
+
+int
+pcap_fileno(pcap_t *p)
+{
+	return (p->fd);
+}
+
+void
+pcap_perror(pcap_t *p, char *prefix)
+{
+	fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
+}
+
+char *
+pcap_geterr(pcap_t *p)
+{
+	return (p->errbuf);
+}
+
+/*
+ * Not all systems have strerror().
+ */
+char *
+pcap_strerror(int errnum)
+{
+#ifdef HAVE_STRERROR
+	return (strerror(errnum));
+#else
+	extern int sys_nerr;
+	extern const char *const sys_errlist[];
+	static char ebuf[20];
+
+	if ((unsigned int)errnum < sys_nerr)
+		return ((char *)sys_errlist[errnum]);
+	(void)sprintf(ebuf, "Unknown error: %d", errnum);
+	return(ebuf);
+#endif
+}
+
+void
+pcap_close(pcap_t *p)
+{
+	/*XXX*/
+	if (p->fd >= 0)
+		close(p->fd);
+	if (p->sf.rfile != NULL) {
+		(void)fclose(p->sf.rfile);
+		if (p->sf.base != NULL)
+			free(p->sf.base);
+	} else if (p->buffer != NULL)
+		free(p->buffer);
+	
+	free(p);
+}
diff --git a/pcap/pcap.h b/pcap/pcap.h
new file mode 100644
index 0000000..46db423
--- /dev/null
+++ b/pcap/pcap.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: pcap.h,v 1.6 1996/07/12 13:19:12 mickey Exp $	*/
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the Computer Systems
+ *	Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: pcap.h,v 1.19 96/06/16 22:36:28 leres Exp (LBL)
+ */
+
+#ifndef lib_pcap_h
+#define lib_pcap_h
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <net/bpf.h>
+
+#include <stdio.h>
+
+#define PCAP_VERSION_MAJOR 2
+#define PCAP_VERSION_MINOR 4
+
+#define PCAP_ERRBUF_SIZE 256
+
+/*
+ * Compatibility for systems that have a bpf.h that
+ * predates the bpf typedefs for 64-bit support.
+ */
+#if BPF_RELEASE - 0 < 199406
+typedef	int bpf_int32;
+typedef	u_int bpf_u_int32;
+#endif
+
+typedef struct pcap pcap_t;
+typedef struct pcap_dumper pcap_dumper_t;
+
+/*
+ * The first record in the file contains saved values for some
+ * of the flags used in the printout phases of tcpdump.
+ * Many fields here are 32 bit ints so compilers won't insert unwanted
+ * padding; these files need to be interchangeable across architectures.
+ */
+struct pcap_file_header {
+	bpf_u_int32 magic;
+	u_short version_major;
+	u_short version_minor;
+	bpf_int32 thiszone;	/* gmt to local correction */
+	bpf_u_int32 sigfigs;	/* accuracy of timestamps */
+	bpf_u_int32 snaplen;	/* max length saved portion of each pkt */
+	bpf_u_int32 linktype;	/* data link type (DLT_*) */
+};
+
+/*
+ * Each packet in the dump file is prepended with this generic header.
+ * This gets around the problem of different headers for different
+ * packet interfaces.
+ */
+struct pcap_pkthdr {
+	struct timeval ts;	/* time stamp */
+	bpf_u_int32 caplen;	/* length of portion present */
+	bpf_u_int32 len;	/* length this packet (off wire) */
+};
+
+/*
+ * As returned by the pcap_stats()
+ */
+struct pcap_stat {
+	u_int ps_recv;		/* number of packets received */
+	u_int ps_drop;		/* number of packets dropped */
+	u_int ps_ifdrop;	/* drops by interface XXX not yet supported */
+};
+
+typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
+			     const u_char *);
+
+char	*pcap_lookupdev(char *);
+int	pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
+pcap_t	*pcap_open_live(char *, int, int, int, char *);
+pcap_t	*pcap_open_offline(char *, char *);
+void	pcap_close(pcap_t *);
+int	pcap_loop(pcap_t *, int, pcap_handler, u_char *);
+int	pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
+const u_char*
+	pcap_next(pcap_t *, struct pcap_pkthdr *);
+int	pcap_stats(pcap_t *, struct pcap_stat *);
+int	pcap_setfilter(pcap_t *, struct bpf_program *);
+void	pcap_perror(pcap_t *, char *);
+char	*pcap_strerror(int);
+char	*pcap_geterr(pcap_t *);
+int	pcap_compile(pcap_t *, struct bpf_program *, char *, int,
+	    bpf_u_int32);
+/* XXX */
+int	pcap_freecode(pcap_t *, struct bpf_program *);
+int	pcap_datalink(pcap_t *);
+int	pcap_snapshot(pcap_t *);
+int	pcap_is_swapped(pcap_t *);
+int	pcap_major_version(pcap_t *);
+int	pcap_minor_version(pcap_t *);
+
+/* XXX */
+FILE	*pcap_file(pcap_t *);
+int	pcap_fileno(pcap_t *);
+
+pcap_dumper_t *pcap_dump_open(pcap_t *, char *);
+void	pcap_dump_close(pcap_dumper_t *);
+void	pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
+
+/* XXX this guy lives in the bpf tree */
+u_int	bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
+char	*bpf_image(struct bpf_insn *, int);
+
+/* XXX */
+extern	int pcap_fddipad;
+
+#endif
diff --git a/pcap/savefile.c b/pcap/savefile.c
new file mode 100644
index 0000000..ba1e9c0
--- /dev/null
+++ b/pcap/savefile.c
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: savefile.c,v 1.4 1996/07/12 13:19:13 mickey Exp $	*/
+
+/*
+ * Copyright (c) 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static char rcsid[] =
+    "@(#)Header: savefile.c,v 1.28 95/10/07 03:09:06 leres Exp (LBL)";
+#endif
+
+/*
+ * savefile.c - supports offline use of tcpdump
+ *	Extraction/creation by Jeffrey Mogul, DECWRL
+ *	Modified by Steve McCanne, LBL.
+ *
+ * Used to save the received packet headers, after filtering, to
+ * a file, and then read them later.
+ * The first record in the file contains saved values for the machine
+ * dependent values so we can print the dump file on any architecture.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <net/bpf.h>
+
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+/*
+ * We use the "receiver-makes-right" approach to byte order,
+ * because time is at a premium when we are writing the file.
+ * In other words, the pcap_file_header and pcap_pkthdr,
+ * records are written in host byte order.
+ * Note that the packets are always written in network byte order.
+ *
+ * ntoh[ls] aren't sufficient because we might need to swap on a big-endian
+ * machine (if the file was written in little-end order).
+ */
+#define	SWAPLONG(y) \
+((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+#define	SWAPSHORT(y) \
+	( (((y)&0xff)<<8) | (((y)&0xff00)>>8) )
+
+#define SFERR_TRUNC		1
+#define SFERR_BADVERSION	2
+#define SFERR_BADF		3
+#define SFERR_EOF		4 /* not really an error, just a status */
+
+static int
+sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
+{
+	struct pcap_file_header hdr;
+
+	hdr.magic = TCPDUMP_MAGIC;
+	hdr.version_major = PCAP_VERSION_MAJOR;
+	hdr.version_minor = PCAP_VERSION_MINOR;
+
+	hdr.thiszone = thiszone;
+	hdr.snaplen = snaplen;
+	hdr.sigfigs = 0;
+	hdr.linktype = linktype;
+
+	if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
+		return (-1);
+
+	return (0);
+}
+
+static void
+swap_hdr(struct pcap_file_header *hp)
+{
+	hp->version_major = SWAPSHORT(hp->version_major);
+	hp->version_minor = SWAPSHORT(hp->version_minor);
+	hp->thiszone = SWAPLONG(hp->thiszone);
+	hp->sigfigs = SWAPLONG(hp->sigfigs);
+	hp->snaplen = SWAPLONG(hp->snaplen);
+	hp->linktype = SWAPLONG(hp->linktype);
+}
+
+pcap_t *
+pcap_open_offline(char *fname, char *errbuf)
+{
+	register pcap_t *p;
+	register FILE *fp;
+	struct pcap_file_header hdr;
+	int linklen;
+
+	p = (pcap_t *)malloc(sizeof(*p));
+	if (p == NULL) {
+		strcpy(errbuf, "out of swap");
+		return (NULL);
+	}
+
+	memset((char *)p, 0, sizeof(*p));
+	/*
+	 * Set this field so we don't close stdin in pcap_close!
+	 */
+	p->fd = -1;
+
+	if (fname[0] == '-' && fname[1] == '\0')
+		fp = stdin;
+	else {
+		fp = fopen(fname, "r");
+		if (fp == NULL) {
+			sprintf(errbuf, "%s: %s", fname, pcap_strerror(errno));
+			goto bad;
+		}
+	}
+	if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
+		sprintf(errbuf, "fread: %s", pcap_strerror(errno));
+		goto bad;
+	}
+	if (hdr.magic != TCPDUMP_MAGIC) {
+		if (SWAPLONG(hdr.magic) != TCPDUMP_MAGIC) {
+			sprintf(errbuf, "bad dump file format");
+			goto bad;
+		}
+		p->sf.swapped = 1;
+		swap_hdr(&hdr);
+	}
+	if (hdr.version_major < PCAP_VERSION_MAJOR) {
+		sprintf(errbuf, "archaic file format");
+		goto bad;
+	}
+	p->tzoff = hdr.thiszone;
+	p->snapshot = hdr.snaplen;
+	p->linktype = hdr.linktype;
+	p->sf.rfile = fp;
+	p->bufsize = hdr.snaplen;
+
+	/* Align link header as required for proper data alignment */
+	/* XXX should handle all types */
+	switch (p->linktype) {
+
+	case DLT_EN10MB:
+		linklen = 14;
+		break;
+
+	case DLT_FDDI:
+		linklen = 13 + 8;	/* fddi_header + llc */
+		break;
+
+	case DLT_NULL:
+	default:
+		linklen = 0;
+		break;
+	}
+
+	p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT);
+	p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT);
+	p->sf.version_major = hdr.version_major;
+	p->sf.version_minor = hdr.version_minor;
+
+	return (p);
+ bad:
+	free(p);
+	return (NULL);
+}
+
+/*
+ * Read sf_readfile and return the next packet.  Return the header in hdr
+ * and the contents in buf.  Return 0 on success, SFERR_EOF if there were
+ * no more packets, and SFERR_TRUNC if a partial packet was encountered.
+ */
+static int
+sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
+{
+	FILE *fp = p->sf.rfile;
+
+	/* read the stamp */
+	if (fread((char *)hdr, sizeof(struct pcap_pkthdr), 1, fp) != 1) {
+		/* probably an EOF, though could be a truncated packet */
+		return (1);
+	}
+
+	if (p->sf.swapped) {
+		/* these were written in opposite byte order */
+		hdr->caplen = SWAPLONG(hdr->caplen);
+		hdr->len = SWAPLONG(hdr->len);
+		hdr->ts.tv_sec = SWAPLONG(hdr->ts.tv_sec);
+		hdr->ts.tv_usec = SWAPLONG(hdr->ts.tv_usec);
+	}
+	/*
+	 * We interchanged the caplen and len fields at version 2.3,
+	 * in order to match the bpf header layout.  But unfortunately
+	 * some files were written with version 2.3 in their headers
+	 * but without the interchanged fields.
+	 */
+	if (p->sf.version_minor < 3 ||
+	    (p->sf.version_minor == 3 && hdr->caplen > hdr->len)) {
+		int t = hdr->caplen;
+		hdr->caplen = hdr->len;
+		hdr->len = t;
+	}
+
+	if (hdr->caplen > buflen) {
+		/*
+		 * This can happen due to Solaris 2.3 systems tripping
+		 * over the BUFMOD problem and not setting the snapshot
+		 * correctly in the savefile header.  If the caplen isn't
+		 * grossly wrong, try to salvage.
+		 */
+		static u_char *tp = NULL;
+		static int tsize = 0;
+
+		if (tsize < hdr->caplen) {
+			tsize = ((hdr->caplen + 1023) / 1024) * 1024;
+			if (tp != NULL)
+				free((u_char *)tp);
+			tp = (u_char *)malloc(tsize);
+			if (tp == NULL) {
+				sprintf(p->errbuf, "BUFMOD hack malloc");
+				return (-1);
+			}
+		}
+		if (fread((char *)tp, hdr->caplen, 1, fp) != 1) {
+			sprintf(p->errbuf, "truncated dump file");
+			return (-1);
+		}
+		memcpy((char *)buf, (char *)tp, buflen);
+
+	} else {
+		/* read the packet itself */
+
+		if (fread((char *)buf, hdr->caplen, 1, fp) != 1) {
+			sprintf(p->errbuf, "truncated dump file");
+			return (-1);
+		}
+	}
+	return (0);
+}
+
+/*
+ * Print out packets stored in the file initialized by sf_read_init().
+ * If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
+ */
+int
+pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+	struct bpf_insn *fcode = p->fcode.bf_insns;
+	int status = 0;
+	int n = 0;
+
+	while (status == 0) {
+		struct pcap_pkthdr h;
+
+		status = sf_next_packet(p, &h, p->buffer, p->bufsize);
+		if (status) {
+			if (status == 1)
+				return (0);
+			return (status);
+		}
+
+		if (fcode == NULL ||
+		    bpf_filter(fcode, p->buffer, h.len, h.caplen)) {
+			(*callback)(user, &h, p->buffer);
+			if (++n >= cnt && cnt > 0)
+				break;
+		}
+	}
+	/*XXX this breaks semantics tcpslice expects */
+	return (n);
+}
+
+/*
+ * Output a packet to the initialized dump file.
+ */
+void
+pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
+{
+	register FILE *f;
+
+	f = (FILE *)user;
+	/* XXX we should check the return status */
+	(void)fwrite((char *)h, sizeof(*h), 1, f);
+	(void)fwrite((char *)sp, h->caplen, 1, f);
+}
+
+/*
+ * Initialize so that sf_write() will output to the file named 'fname'.
+ */
+pcap_dumper_t *
+pcap_dump_open(pcap_t *p, char *fname)
+{
+	FILE *f;
+	if (fname[0] == '-' && fname[1] == '\0')
+		f = stdout;
+	else {
+		f = fopen(fname, "w");
+		if (f == NULL) {
+			sprintf(p->errbuf, "%s: %s",
+			    fname, pcap_strerror(errno));
+			return (NULL);
+		}
+	}
+	(void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot);
+	return ((pcap_dumper_t *)f);
+}
+
+void
+pcap_dump_close(pcap_dumper_t *p)
+{
+
+#ifdef notyet
+	if (ferror((FILE *)p))
+		return-an-error;
+	/* XXX should check return from fclose() too */
+#endif
+	(void)fclose((FILE *)p);
+}
diff --git a/pcap/scanner.l b/pcap/scanner.l
new file mode 100644
index 0000000..2cbb693
--- /dev/null
+++ b/pcap/scanner.l
@@ -0,0 +1,198 @@
+%{
+/*	$OpenBSD: scanner.l,v 1.5 1996/07/12 13:19:13 mickey Exp $	*/
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/pcap/scanner.l,v 1.1.1.1 1999/05/02 03:57:55 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <unistd.h>
+
+#include <pcap.h>
+#include <pcap-namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "pcap-int.h"
+#include "gencode.h"
+#include "y.tab.h"
+
+static int stoi(char *);
+static inline int xdtoi(int);
+
+#ifdef FLEX_SCANNER
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max)\
+ {\
+	char *src = in_buffer;\
+	int i;\
+\
+	if (*src == 0)\
+		result = YY_NULL;\
+	else {\
+		for (i = 0; *src && i < max; ++i)\
+			buf[i] = *src++;\
+		in_buffer += i;\
+		result = i;\
+	}\
+ }
+#else
+#undef getc
+#define getc(fp)  (*in_buffer == 0 ? EOF : *in_buffer++)
+#endif
+
+extern YYSTYPE yylval;
+
+static char *in_buffer;
+
+%}
+
+N		([0-9]+|(0X|0x)[0-9A-Fa-f]+)
+B		([0-9A-Fa-f][0-9A-Fa-f]?)
+
+%a 3000
+
+%%
+dst		return DST;
+src		return SRC;
+
+link|ether|ppp|slip  return LINK;
+fddi		return LINK;
+arp		return ARP;
+rarp		return RARP;
+ip		return IP;
+tcp		return TCP;
+udp		return UDP;
+icmp		return ICMP;
+igmp		return IGMP;
+
+decnet		return DECNET;
+lat		return LAT;
+moprc		return MOPRC;
+mopdl		return MOPDL;
+
+host		return HOST;
+net		return NET;
+port		return PORT;
+proto		return PROTO;
+
+gateway		return GATEWAY;
+
+less		return LESS;
+greater		return GREATER;
+byte		return BYTE;
+broadcast	return TK_BROADCAST;
+multicast	return TK_MULTICAST;
+
+and|"&&"	return AND;
+or|"||"		return OR;
+not		return '!';
+
+len|length	return LEN;
+inbound		return INBOUND;
+outbound	return OUTBOUND;
+
+[ \n\t]			;
+[+\-*/:\[\]!<>()&|=]	return yytext[0];
+">="			return GEQ;
+"<="			return LEQ;
+"!="			return NEQ;
+"=="			return '=';
+"<<"			return LSH;
+">>"			return RSH;
+{N}			{ yylval.i = stoi((char *)yytext); return NUM; }
+({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N})	{
+			yylval.s = sdup((char *)yytext); return HID;
+}
+{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext);
+			  return EID; }
+{B}:+({B}:+)+		{ bpf_error("bogus ethernet address %s", yytext); }
+[A-Za-z][-_.A-Za-z0-9]*	{ yylval.s = sdup((char *)yytext); return ID; }
+"\\"[^ !()\n\t]+	{ yylval.s = sdup((char *)yytext + 1); return ID; }
+[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+    { bpf_error("illegal token: %s\n", yytext); }
+.			{ bpf_error("illegal char '%c'", *yytext); }
+%%
+void
+lex_init(buf)
+	char *buf;
+{
+	in_buffer = buf;
+}
+
+/*
+ * Also define a yywrap.  Note that if we're using flex, it will
+ * define a macro to map this identifier to pcap_wrap.
+ */
+int
+yywrap()
+{
+	return 1;
+}
+
+/* Hex digit to integer. */
+static inline int
+xdtoi(c)
+	register int c;
+{
+	if (isdigit(c))
+		return c - '0';
+	else if (islower(c))
+		return c - 'a' + 10;
+	else
+		return c - 'A' + 10;
+}
+
+/*
+ * Convert string to integer.  Just like atoi(), but checks for
+ * preceding 0x or 0 and uses hex or octal instead of decimal.
+ */
+static int
+stoi(s)
+	char *s;
+{
+	int base = 10;
+	int n = 0;
+
+	if (*s == '0') {
+		if (s[1] == 'x' || s[1] == 'X') {
+			s += 2;
+			base = 16;
+		}
+		else {
+			base = 8;
+			s += 1;
+		}
+	}
+	while (*s)
+		n = n * base + xdtoi(*s++);
+
+	return n;
+}
+
diff --git a/ping.tproj/Makefile b/ping.tproj/Makefile
new file mode 100644
index 0000000..8ad77bf
--- /dev/null
+++ b/ping.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ping
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = ping.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\
+            ping.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /sbin
+WINDOWS_INSTALLDIR = /sbin
+PDO_UNIX_INSTALLDIR = /sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ping.tproj/Makefile.dist b/ping.tproj/Makefile.dist
new file mode 100644
index 0000000..d08f74d
--- /dev/null
+++ b/ping.tproj/Makefile.dist
@@ -0,0 +1,8 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/5/93
+
+PROG=	ping
+MAN8=	ping.0
+BINOWN=	root
+BINMODE=4555
+
+.include <bsd.prog.mk>
diff --git a/ping.tproj/Makefile.postamble b/ping.tproj/Makefile.postamble
new file mode 100644
index 0000000..23e0214
--- /dev/null
+++ b/ping.tproj/Makefile.postamble
@@ -0,0 +1 @@
+INSTALL_PERMISSIONS = 4555  # If set, 'install' chmod's executable to this
diff --git a/ping.tproj/Makefile.preamble b/ping.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/ping.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/ping.tproj/PB.project b/ping.tproj/PB.project
new file mode 100644
index 0000000..b7fd3c5
--- /dev/null
+++ b/ping.tproj/PB.project
@@ -0,0 +1,31 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (ping.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, Makefile.dist, ping.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = ping; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_INSTALLDIR = /sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_MAINNIB = ping; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ping; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_INSTALLDIR = /sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_MAINNIB = ping; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ping.tproj/ping.8 b/ping.tproj/ping.8
new file mode 100644
index 0000000..2382365
--- /dev/null
+++ b/ping.tproj/ping.8
@@ -0,0 +1,328 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)ping.8	8.3 (Berkeley) 4/28/95
+.\"
+.Dd April 28, 1995
+.Dt PING 8
+.Os BSD 4.3
+.Sh NAME
+.Nm ping
+.Nd send
+.Tn ICMP ECHO_REQUEST
+packets to network hosts
+.Sh SYNOPSIS
+.Nm ping
+.Op Fl Rdfnqrv
+.Op Fl c Ar count
+.Op Fl i Ar wait
+.Op Fl l Ar preload
+.Op Fl p Ar pattern
+.Op Fl s Ar packetsize
+.Ar host
+.Sh DESCRIPTION
+.Nm Ping
+uses the
+.Tn ICMP
+protocol's mandatory
+.Tn ECHO_REQUEST
+datagram to elicit an
+.Tn ICMP ECHO_RESPONSE
+from a host or gateway.
+.Tn ECHO_REQUEST
+datagrams (``pings'') have an IP and
+.Tn ICMP
+header,
+followed by a
+.Dq struct timeval
+and then an arbitrary number of ``pad'' bytes used to fill out the
+packet.
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl c Ar count
+Stop after sending (and receiving)
+.Ar count
+.Tn ECHO_RESPONSE
+packets.
+.It Fl d
+Set the
+.Dv SO_DEBUG
+option on the socket being used.
+.It Fl f
+Flood ping.
+Outputs packets as fast as they come back or one hundred times per second,
+whichever is more.
+For every
+.Tn ECHO_REQUEST
+sent a period ``.'' is printed, while for every
+.Tn ECHO_REPLY
+received a backspace is printed.
+This provides a rapid display of how many packets are being dropped.
+Only the super-user may use this option.
+.Bf -emphasis
+This can be very hard on a network and should be used with caution.
+.Ef
+.It Fl i Ar wait
+Wait
+.Ar wait
+seconds
+.Em between sending each packet .
+The default is to wait for one second between each packet.
+This option is incompatible with the
+.Fl f
+option.
+.It Fl l Ar preload
+If
+.Ar preload
+is specified,
+.Nm ping
+sends that many packets as fast as possible before falling into its normal
+mode of behavior.
+.It Fl n
+Numeric output only.
+No attempt will be made to lookup symbolic names for host addresses.
+.It Fl p Ar pattern
+You may specify up to 16 ``pad'' bytes to fill out the packet you send.
+This is useful for diagnosing data-dependent problems in a network.
+For example,
+.Dq Li \-p ff
+will cause the sent packet to be filled with all
+ones.
+.It Fl q
+Quiet output.
+Nothing is displayed except the summary lines at startup time and
+when finished.
+.It Fl R
+Record route.
+Includes the
+.Tn RECORD_ROUTE
+option in the
+.Tn ECHO_REQUEST
+packet and displays
+the route buffer on returned packets.
+Note that the IP header is only large enough for nine such routes.
+Many hosts ignore or discard this option.
+.It Fl r
+Bypass the normal routing tables and send directly to a host on an attached
+network.
+If the host is not on a directly-attached network, an error is returned.
+This option can be used to ping a local host through an interface
+that has no route through it (e.g., after the interface was dropped by
+.Xr routed 8 ) .
+.It Fl s Ar packetsize
+Specifies the number of data bytes to be sent.  
+The default is 56, which translates into 64
+.Tn ICMP
+data bytes when combined
+with the 8 bytes of
+.Tn ICMP
+header data.
+.It Fl v
+Verbose output.
+.Tn ICMP
+packets other than
+.Tn ECHO_RESPONSE
+that are received are listed.
+.El
+.Pp
+When using
+.Nm ping
+for fault isolation, it should first be run on the local host, to verify
+that the local network interface is up and running.
+Then, hosts and gateways further and further away should be ``pinged''.
+Round-trip times and packet loss statistics are computed.
+If duplicate packets are received, they are not included in the packet
+loss calculation, although the round trip time of these packets is used
+in calculating the minimum/average/maximum round-trip time numbers.
+When the specified number of packets have been sent (and received) or
+if the program is terminated with a
+.Dv SIGINT ,
+a brief summary is displayed.
+.Pp
+This program is intended for use in network testing, measurement and
+management.
+Because of the load it can impose on the network, it is unwise to use
+.Nm ping
+during normal operations or from automated scripts.
+.Sh ICMP PACKET DETAILS
+An IP header without options is 20 bytes.
+An
+.Tn ICMP
+.Tn ECHO_REQUEST
+packet contains an additional 8 bytes worth
+of
+.Tn ICMP
+header followed by an arbitrary amount of data.
+When a
+.Ar packetsize
+is given, this indicated the size of this extra piece of data (the
+default is 56).
+Thus the amount of data received inside of an IP packet of type
+.Tn ICMP
+.Tn ECHO_REPLY
+will always be 8 bytes more than the requested data space
+(the
+.Tn ICMP
+header).
+.Pp
+If the data space is at least eight bytes large,
+.Nm ping
+uses the first eight bytes of this space to include a timestamp which
+it uses in the computation of round trip times.
+If less than eight bytes of pad are specified, no round trip times are
+given.
+.Sh DUPLICATE AND DAMAGED PACKETS
+.Nm Ping
+will report duplicate and damaged packets.
+Duplicate packets should never occur, and seem to be caused by
+inappropriate link-level retransmissions.
+Duplicates may occur in many situations and are rarely (if ever) a
+good sign, although the presence of low levels of duplicates may not
+always be cause for alarm.
+.Pp
+Damaged packets are obviously serious cause for alarm and often
+indicate broken hardware somewhere in the
+.Nm ping
+packet's path (in the network or in the hosts).
+.Sh TRYING DIFFERENT DATA PATTERNS
+The (inter)network layer should never treat packets differently depending
+on the data contained in the data portion.
+Unfortunately, data-dependent problems have been known to sneak into
+networks and remain undetected for long periods of time.
+In many cases the particular pattern that will have problems is something
+that doesn't have sufficient ``transitions'', such as all ones or all
+zeros, or a pattern right at the edge, such as almost all zeros.
+It isn't necessarily enough to specify a data pattern of all zeros (for
+example) on the command line because the pattern that is of interest is
+at the data link level, and the relationship between what you type and
+what the controllers transmit can be complicated.
+.Pp
+This means that if you have a data-dependent problem you will probably
+have to do a lot of testing to find it.
+If you are lucky, you may manage to find a file that either can't be sent
+across your network or that takes much longer to transfer than other
+similar length files.
+You can then examine this file for repeated patterns that you can test
+using the
+.Fl p
+option of
+.Nm ping .
+.Sh TTL DETAILS
+The
+.Tn TTL
+value of an IP packet represents the maximum number of IP routers
+that the packet can go through before being thrown away.
+In current practice you can expect each router in the Internet to decrement
+the
+.Tn TTL
+field by exactly one.
+.Pp
+The
+.Tn TCP/IP
+specification states that the
+.Tn TTL
+field for
+.Tn TCP
+packets should
+be set to 60, but many systems use smaller values (4.3
+.Tn BSD
+uses 30, 4.2 used
+15).
+.Pp
+The maximum possible value of this field is 255, and most Unix systems set
+the
+.Tn TTL
+field of
+.Tn ICMP ECHO_REQUEST
+packets to 255.
+This is why you will find you can ``ping'' some hosts, but not reach them
+with
+.Xr telnet 1
+or
+.Xr ftp 1 .
+.Pp
+In normal operation ping prints the ttl value from the packet it receives.
+When a remote system receives a ping packet, it can do one of three things
+with the
+.Tn TTL
+field in its response:
+.Bl -bullet
+.It
+Not change it; this is what Berkeley Unix systems did before the
+.Bx 4.3 tahoe
+release.
+In this case the
+.Tn TTL
+value in the received packet will be 255 minus the
+number of routers in the round-trip path.
+.It
+Set it to 255; this is what current Berkeley Unix systems do.
+In this case the
+.Tn TTL
+value in the received packet will be 255 minus the
+number of routers in the path
+.Xr from
+the remote system
+.Em to
+the
+.Nm ping Ns Em ing
+host.
+.It
+Set it to some other value.
+Some machines use the same value for
+.Tn ICMP
+packets that they use for
+.Tn TCP
+packets, for example either 30 or 60.
+Others may use completely wild values.
+.El
+.Sh BUGS
+Many Hosts and Gateways ignore the
+.Tn RECORD_ROUTE
+option.
+.Pp
+The maximum IP header length is too small for options like
+.Tn RECORD_ROUTE
+to
+be completely useful.
+There's not much that that can be done about this, however.
+.Pp
+Flood pinging is not recommended in general, and flood pinging the
+broadcast address should only be done under very controlled conditions.
+.Sh SEE ALSO
+.Xr netstat 1 ,
+.Xr ifconfig 8 ,
+.Xr routed 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 .
diff --git a/ping.tproj/ping.c b/ping.tproj/ping.c
new file mode 100644
index 0000000..4aad17e
--- /dev/null
+++ b/ping.tproj/ping.c
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Muuss.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/*
+ *			P I N G . C
+ *
+ * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
+ * measure round-trip-delays and packet loss across network paths.
+ *
+ * Author -
+ *	Mike Muuss
+ *	U. S. Army Ballistic Research Laboratory
+ *	December, 1983
+ *
+ * Status -
+ *	Public Domain.  Distribution Unlimited.
+ * Bugs -
+ *	More statistics could always be gathered.
+ *	This program has to run SUID to ROOT to access the ICMP socket.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_var.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+#define	DEFDATALEN	(64 - 8)	/* default data length */
+#define	MAXIPLEN	60
+#define	MAXICMPLEN	76
+#define	MAXPACKET	(65536 - 60 - 8)/* max packet size */
+#define	MAXWAIT		10		/* max seconds to wait for response */
+#define	NROUTES		9		/* number of record route slots */
+
+#define	A(bit)		rcvd_tbl[(bit)>>3]	/* identify byte in array */
+#define	B(bit)		(1 << ((bit) & 0x07))	/* identify bit in byte */
+#define	SET(bit)	(A(bit) |= B(bit))
+#define	CLR(bit)	(A(bit) &= (~B(bit)))
+#define	TST(bit)	(A(bit) & B(bit))
+
+/* various options */
+int options;
+#define	F_FLOOD		0x001
+#define	F_INTERVAL	0x002
+#define	F_NUMERIC	0x004
+#define	F_PINGFILLED	0x008
+#define	F_QUIET		0x010
+#define	F_RROUTE	0x020
+#define	F_SO_DEBUG	0x040
+#define	F_SO_DONTROUTE	0x080
+#define	F_VERBOSE	0x100
+
+/*
+ * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
+ * number of received sequence numbers we can keep track of.  Change 128
+ * to 8192 for complete accuracy...
+ */
+#define	MAX_DUP_CHK	(8 * 128)
+int mx_dup_ck = MAX_DUP_CHK;
+char rcvd_tbl[MAX_DUP_CHK / 8];
+
+struct sockaddr whereto;	/* who to ping */
+int datalen = DEFDATALEN;
+int s;				/* socket file descriptor */
+u_char outpack[MAXPACKET];
+char BSPACE = '\b';		/* characters written for flood */
+char DOT = '.';
+char *hostname;
+int ident;			/* process id to identify our packets */
+
+/* counters */
+long npackets;			/* max packets to transmit */
+long nreceived;			/* # of packets we got back */
+long nrepeats;			/* number of duplicates */
+long ntransmitted;		/* sequence # for outbound packets = #sent */
+int interval = 1;		/* interval between packets */
+
+/* timing */
+int timing;			/* flag to do timing */
+double tmin = 999999999.0;	/* minimum round trip time */
+double tmax = 0.0;		/* maximum round trip time */
+double tsum = 0.0;		/* sum of all times, for doing average */
+
+char *pr_addr();
+void catcher(), finish();
+
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	extern int errno, optind;
+	extern char *optarg;
+	struct timeval timeout;
+	struct hostent *hp;
+	struct sockaddr_in *to;
+	struct protoent *proto;
+	register int i;
+	int ch, fdmask, hold, packlen, preload;
+	u_char *datap, *packet;
+	char *target, hnamebuf[MAXHOSTNAMELEN], *malloc();
+#ifdef IP_OPTIONS
+	char rspace[3 + 4 * NROUTES + 1];	/* record route space */
+#endif
+
+	preload = 0;
+	datap = &outpack[8 + sizeof(struct timeval)];
+	while ((ch = getopt(argc, argv, "Rc:dfh:i:l:np:qrs:v")) != EOF)
+		switch(ch) {
+		case 'c':
+			npackets = atoi(optarg);
+			if (npackets <= 0) {
+				(void)fprintf(stderr,
+				    "ping: bad number of packets to transmit.\n");
+				exit(1);
+			}
+			break;
+		case 'd':
+			options |= F_SO_DEBUG;
+			break;
+		case 'f':
+			if (getuid()) {
+				(void)fprintf(stderr,
+				    "ping: %s\n", strerror(EPERM));
+				exit(1);
+			}
+			options |= F_FLOOD;
+			setbuf(stdout, (char *)NULL);
+			break;
+		case 'i':		/* wait between sending packets */
+			interval = atoi(optarg);
+			if (interval <= 0) {
+				(void)fprintf(stderr,
+				    "ping: bad timing interval.\n");
+				exit(1);
+			}
+			options |= F_INTERVAL;
+			break;
+		case 'l':
+			if (getuid()) {
+				(void)fprintf(stderr,
+				    "ping: %s\n", strerror(EPERM));
+				exit(1);
+			}
+			preload = atoi(optarg);
+			if (preload < 0) {
+				(void)fprintf(stderr,
+				    "ping: bad preload value.\n");
+				exit(1);
+			}
+			break;
+		case 'n':
+			options |= F_NUMERIC;
+			break;
+		case 'p':		/* fill buffer with user pattern */
+			options |= F_PINGFILLED;
+			fill((char *)datap, optarg);
+				break;
+		case 'q':
+			options |= F_QUIET;
+			break;
+		case 'R':
+			options |= F_RROUTE;
+			break;
+		case 'r':
+			options |= F_SO_DONTROUTE;
+			break;
+		case 's':		/* size of packet to send */
+			datalen = atoi(optarg);
+			if (datalen > MAXPACKET) {
+				(void)fprintf(stderr,
+				    "ping: packet size too large.\n");
+				exit(1);
+			}
+			if (datalen <= 0) {
+				(void)fprintf(stderr,
+				    "ping: illegal packet size.\n");
+				exit(1);
+			}
+			break;
+		case 'v':
+			options |= F_VERBOSE;
+			break;
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 1)
+		usage();
+	target = *argv;
+
+	memset(&whereto, 0, sizeof(struct sockaddr));
+	to = (struct sockaddr_in *)&whereto;
+	to->sin_family = AF_INET;
+	to->sin_addr.s_addr = inet_addr(target);
+	if (to->sin_addr.s_addr != (u_int)-1)
+		hostname = target;
+	else {
+		hp = gethostbyname(target);
+		if (!hp) {
+			(void)fprintf(stderr,
+			    "ping: unknown host %s\n", target);
+			exit(1);
+		}
+		to->sin_family = hp->h_addrtype;
+		memmove(&to->sin_addr, hp->h_addr, hp->h_length);
+		(void)strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1);
+		hostname = hnamebuf;
+	}
+
+	if (options & F_FLOOD && options & F_INTERVAL) {
+		(void)fprintf(stderr,
+		    "ping: -f and -i incompatible options.\n");
+		exit(1);
+	}
+
+	if (datalen >= sizeof(struct timeval))	/* can we time transfer */
+		timing = 1;
+	packlen = datalen + MAXIPLEN + MAXICMPLEN;
+	if (!(packet = (u_char *)malloc((u_int)packlen))) {
+		(void)fprintf(stderr, "ping: out of memory.\n");
+		exit(1);
+	}
+	if (!(options & F_PINGFILLED))
+		for (i = 8; i < datalen; ++i)
+			*datap++ = i;
+
+	ident = getpid() & 0xFFFF;
+
+	if (!(proto = getprotobyname("icmp"))) {
+		(void)fprintf(stderr, "ping: unknown protocol icmp.\n");
+		exit(1);
+	}
+	if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) {
+		perror("ping: socket");
+		exit(1);
+	}
+	hold = 1;
+	if (options & F_SO_DEBUG)
+		(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+		    sizeof(hold));
+	if (options & F_SO_DONTROUTE)
+		(void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
+		    sizeof(hold));
+
+	/* record route option */
+	if (options & F_RROUTE) {
+#ifdef IP_OPTIONS
+		rspace[IPOPT_OPTVAL] = IPOPT_RR;
+		rspace[IPOPT_OLEN] = sizeof(rspace)-1;
+		rspace[IPOPT_OFFSET] = IPOPT_MINOFF;
+		if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, rspace,
+		    sizeof(rspace)) < 0) {
+			perror("ping: record route");
+			exit(1);
+		}
+#else
+		(void)fprintf(stderr,
+		  "ping: record route not available in this implementation.\n");
+		exit(1);
+#endif /* IP_OPTIONS */
+	}
+
+	/*
+	 * When pinging the broadcast address, you can get a lot of answers.
+	 * Doing something so evil is useful if you are trying to stress the
+	 * ethernet, or just want to fill the arp cache to get some stuff for
+	 * /etc/ethers.
+	 */
+	(void)setsockopt(s, SOL_SOCKET, SO_RCVBUF, &packlen, sizeof(packlen));
+
+	if (to->sin_family == AF_INET)
+		(void)printf("PING %s (%s): %d data bytes\n", hostname,
+		    inet_ntoa(*(struct in_addr *)&to->sin_addr.s_addr),
+		    datalen);
+	else
+		(void)printf("PING %s: %d data bytes\n", hostname, datalen);
+
+	(void)signal(SIGINT, finish);
+	(void)signal(SIGALRM, catcher);
+
+	while (preload--)		/* fire off them quickies */
+		pinger();
+
+	if ((options & F_FLOOD) == 0)
+		catcher();		/* start things going */
+
+	for (;;) {
+		struct sockaddr_in from;
+		register int cc;
+		int fromlen;
+		sigset_t omask, nmask;
+
+		if (options & F_FLOOD) {
+			pinger();
+			timeout.tv_sec = 0;
+			timeout.tv_usec = 10000;
+			fdmask = 1 << s;
+			if (select(s + 1, (fd_set *)&fdmask, (fd_set *)NULL,
+			    (fd_set *)NULL, &timeout) < 1)
+				continue;
+		}
+		fromlen = sizeof(from);
+		if ((cc = recvfrom(s, (char *)packet, packlen, 0,
+		    (struct sockaddr *)&from, &fromlen)) < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("ping: recvfrom");
+			continue;
+		}
+		sigemptyset(&nmask);
+		sigaddset(&nmask, SIGALRM);
+		sigprocmask(SIG_BLOCK, &nmask, &omask);
+		pr_pack((char *)packet, cc, &from);
+		sigprocmask(SIG_SETMASK, &omask, NULL);
+		if (npackets && nreceived >= npackets)
+			break;
+	}
+	finish();
+	/* NOTREACHED */
+}
+
+/*
+ * catcher --
+ *	This routine causes another PING to be transmitted, and then
+ * schedules another SIGALRM for 1 second from now.
+ *
+ * bug --
+ *	Our sense of time will slowly skew (i.e., packets will not be
+ * launched exactly at 1-second intervals).  This does not affect the
+ * quality of the delay and loss statistics.
+ */
+void
+catcher()
+{
+	int waittime;
+
+	pinger();
+	(void)signal(SIGALRM, catcher);
+	if (!npackets || ntransmitted < npackets)
+		alarm((u_int)interval);
+	else {
+		if (nreceived) {
+			waittime = 2 * tmax / 1000;
+			if (!waittime)
+				waittime = 1;
+		} else
+			waittime = MAXWAIT;
+		(void)signal(SIGALRM, finish);
+		(void)alarm((u_int)waittime);
+	}
+}
+
+/*
+ * pinger --
+ *	Compose and transmit an ICMP ECHO REQUEST packet.  The IP packet
+ * will be added on by the kernel.  The ID field is our UNIX process ID,
+ * and the sequence number is an ascending integer.  The first 8 bytes
+ * of the data portion are used to hold a UNIX "timeval" struct in VAX
+ * byte-order, to compute the round-trip time.
+ */
+pinger()
+{
+	register struct icmp *icp;
+	register int cc;
+	int i;
+
+	icp = (struct icmp *)outpack;
+	icp->icmp_type = ICMP_ECHO;
+	icp->icmp_code = 0;
+	icp->icmp_cksum = 0;
+	icp->icmp_seq = ntransmitted++;
+	icp->icmp_id = ident;			/* ID */
+
+	CLR(icp->icmp_seq % mx_dup_ck);
+
+	if (timing)
+		(void)gettimeofday((struct timeval *)&outpack[8],
+		    (struct timezone *)NULL);
+
+	cc = datalen + 8;			/* skips ICMP portion */
+
+	/* compute ICMP checksum here */
+	icp->icmp_cksum = in_cksum((u_short *)icp, cc);
+
+	i = sendto(s, (char *)outpack, cc, 0, &whereto,
+	    sizeof(struct sockaddr));
+
+	if (i < 0 || i != cc)  {
+		if (i < 0)
+			perror("ping: sendto");
+		(void)printf("ping: wrote %s %d chars, ret=%d\n",
+		    hostname, cc, i);
+	}
+	if (!(options & F_QUIET) && options & F_FLOOD)
+		(void)write(STDOUT_FILENO, &DOT, 1);
+}
+
+/*
+ * pr_pack --
+ *	Print out the packet, if it came from us.  This logic is necessary
+ * because ALL readers of the ICMP socket get a copy of ALL ICMP packets
+ * which arrive ('tis only fair).  This permits multiple copies of this
+ * program to be run without having intermingled output (or statistics!).
+ */
+pr_pack(buf, cc, from)
+	char *buf;
+	int cc;
+	struct sockaddr_in *from;
+{
+	register struct icmp *icp;
+	register u_long l;
+	register u_int i, j;
+	register u_char *cp,*dp;
+	static int old_rrlen;
+	static char old_rr[MAX_IPOPTLEN];
+	struct ip *ip;
+	struct timeval tv, *tp;
+	double triptime;
+	int hlen, dupflag;
+
+	(void)gettimeofday(&tv, (struct timezone *)NULL);
+
+	/* Check the IP header */
+	ip = (struct ip *)buf;
+	hlen = ip->ip_hl << 2;
+	if (cc < hlen + ICMP_MINLEN) {
+		if (options & F_VERBOSE)
+			(void)fprintf(stderr,
+			  "ping: packet too short (%d bytes) from %s\n", cc,
+			  inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr));
+		return;
+	}
+
+	/* Now the ICMP part */
+	cc -= hlen;
+	icp = (struct icmp *)(buf + hlen);
+	if (icp->icmp_type == ICMP_ECHOREPLY) {
+		if (icp->icmp_id != ident)
+			return;			/* 'Twas not our ECHO */
+		++nreceived;
+		if (timing) {
+#ifndef icmp_data
+			tp = (struct timeval *)&icp->icmp_ip;
+#else
+			tp = (struct timeval *)icp->icmp_data;
+#endif
+			tvsub(&tv, tp);
+			triptime = ((double)tv.tv_sec) * 1000.0 +
+			    ((double)tv.tv_usec) / 1000.0;
+			tsum += triptime;
+			if (triptime < tmin)
+				tmin = triptime;
+			if (triptime > tmax)
+				tmax = triptime;
+		}
+
+		if (TST(icp->icmp_seq % mx_dup_ck)) {
+			++nrepeats;
+			--nreceived;
+			dupflag = 1;
+		} else {
+			SET(icp->icmp_seq % mx_dup_ck);
+			dupflag = 0;
+		}
+
+		if (options & F_QUIET)
+			return;
+
+		if (options & F_FLOOD)
+			(void)write(STDOUT_FILENO, &BSPACE, 1);
+		else {
+			(void)printf("%d bytes from %s: icmp_seq=%u", cc,
+			   inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
+			   icp->icmp_seq);
+			(void)printf(" ttl=%d", ip->ip_ttl);
+			if (timing)
+				(void)printf(" time=%g ms", triptime);
+			if (dupflag)
+				(void)printf(" (DUP!)");
+			/* check the data */
+			cp = (u_char*)&icp->icmp_data[8];
+			dp = &outpack[8 + sizeof(struct timeval)];
+			for (i = 8; i < datalen; ++i, ++cp, ++dp) {
+				if (*cp != *dp) {
+	(void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
+	    i, *dp, *cp);
+					cp = (u_char*)&icp->icmp_data[0];
+					for (i = 8; i < datalen; ++i, ++cp) {
+						if ((i % 32) == 8)
+							(void)printf("\n\t");
+						(void)printf("%x ", *cp);
+					}
+					break;
+				}
+			}
+		}
+	} else {
+		/* We've got something other than an ECHOREPLY */
+		if (!(options & F_VERBOSE))
+			return;
+		(void)printf("%d bytes from %s: ", cc,
+		    pr_addr(from->sin_addr.s_addr));
+		pr_icmph(icp);
+	}
+
+	/* Display any IP options */
+	cp = (u_char *)buf + sizeof(struct ip);
+
+	for (; hlen > (int)sizeof(struct ip); --hlen, ++cp)
+		switch (*cp) {
+		case IPOPT_EOL:
+			hlen = 0;
+			break;
+		case IPOPT_LSRR:
+			(void)printf("\nLSRR: ");
+			hlen -= 2;
+			j = *++cp;
+			++cp;
+			if (j > IPOPT_MINOFF)
+				for (;;) {
+					l = *++cp;
+					l = (l<<8) + *++cp;
+					l = (l<<8) + *++cp;
+					l = (l<<8) + *++cp;
+					if (l == 0)
+						(void)printf("\t0.0.0.0");
+				else
+					(void)printf("\t%s", pr_addr(ntohl(l)));
+				hlen -= 4;
+				j -= 4;
+				if (j <= IPOPT_MINOFF)
+					break;
+				(void)putchar('\n');
+			}
+			break;
+		case IPOPT_RR:
+			j = *++cp;		/* get length */
+			i = *++cp;		/* and pointer */
+			hlen -= 2;
+			if (i > j)
+				i = j;
+			i -= IPOPT_MINOFF;
+			if (i <= 0)
+				continue;
+			if (i == old_rrlen
+			    && cp == (u_char *)buf + sizeof(struct ip) + 2
+			    && !memcmp(cp, old_rr, i)
+			    && !(options & F_FLOOD)) {
+				(void)printf("\t(same route)");
+				i = ((i + 3) / 4) * 4;
+				hlen -= i;
+				cp += i;
+				break;
+			}
+ 			if (i < MAX_IPOPTLEN) {
+ 				old_rrlen = i;
+ 				memcpy(old_rr, cp, i);
+ 			} else
+ 				old_rrlen = 0;
+
+			(void)printf("\nRR: ");
+			j = 0;
+			for (;;) {
+				l = *++cp;
+				l = (l<<8) + *++cp;
+				l = (l<<8) + *++cp;
+				l = (l<<8) + *++cp;
+				if (l == 0)
+					(void)printf("\t0.0.0.0");
+				else
+					(void)printf("\t%s", pr_addr(ntohl(l)));
+				hlen -= 4;
+				i -= 4;
+				j += 4;
+				if (i <= 0)
+					break;
+				if (j >= MAX_IPOPTLEN) {
+					(void)printf("\t(truncated route)");
+					break;
+				}
+				(void)putchar('\n');
+			}
+			break;
+		case IPOPT_NOP:
+			(void)printf("\nNOP");
+			break;
+		default:
+			(void)printf("\nunknown option %x", *cp);
+			break;
+		}
+	if (!(options & F_FLOOD)) {
+		(void)putchar('\n');
+		(void)fflush(stdout);
+	}
+}
+
+/*
+ * in_cksum --
+ *	Checksum routine for Internet Protocol family headers (C Version)
+ */
+in_cksum(addr, len)
+	u_short *addr;
+	int len;
+{
+	register int nleft = len;
+	register u_short *w = addr;
+	register int sum = 0;
+	u_short answer = 0;
+
+	/*
+	 * Our algorithm is simple, using a 32 bit accumulator (sum), we add
+	 * sequential 16 bit words to it, and at the end, fold back all the
+	 * carry bits from the top 16 bits into the lower 16 bits.
+	 */
+	while (nleft > 1)  {
+		sum += *w++;
+		nleft -= 2;
+	}
+
+	/* mop up an odd byte, if necessary */
+	if (nleft == 1) {
+		*(u_char *)(&answer) = *(u_char *)w ;
+		sum += answer;
+	}
+
+	/* add back carry outs from top 16 bits to low 16 bits */
+	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
+	sum += (sum >> 16);			/* add carry */
+	answer = ~sum;				/* truncate to 16 bits */
+	return(answer);
+}
+
+/*
+ * tvsub --
+ *	Subtract 2 timeval structs:  out = out - in.  Out is assumed to
+ * be >= in.
+ */
+tvsub(out, in)
+	register struct timeval *out, *in;
+{
+	if ((out->tv_usec -= in->tv_usec) < 0) {
+		--out->tv_sec;
+		out->tv_usec += 1000000;
+	}
+	out->tv_sec -= in->tv_sec;
+}
+
+/*
+ * finish --
+ *	Print out statistics, and give up.
+ */
+void
+finish()
+{
+	register int i;
+
+	(void)signal(SIGINT, SIG_IGN);
+	(void)putchar('\n');
+	(void)fflush(stdout);
+	(void)printf("--- %s ping statistics ---\n", hostname);
+	(void)printf("%ld packets transmitted, ", ntransmitted);
+	(void)printf("%ld packets received, ", nreceived);
+	if (nrepeats)
+		(void)printf("+%ld duplicates, ", nrepeats);
+	if (ntransmitted)
+		if (nreceived > ntransmitted)
+			(void)printf("-- somebody's printing up packets!");
+		else
+			(void)printf("%d%% packet loss",
+			    (int) (((ntransmitted - nreceived) * 100) /
+			    ntransmitted));
+	(void)putchar('\n');
+	if (nreceived && timing) {
+		/* Only display average to microseconds */
+		i = 1000.0 * tsum / (nreceived + nrepeats);
+		(void)printf("round-trip min/avg/max = %g/%g/%g ms\n",
+		    tmin, ((double)i) / 1000.0, tmax);
+	}
+	exit(0);
+}
+
+#ifdef notdef
+static char *ttab[] = {
+	"Echo Reply",		/* ip + seq + udata */
+	"Dest Unreachable",	/* net, host, proto, port, frag, sr + IP */
+	"Source Quench",	/* IP */
+	"Redirect",		/* redirect type, gateway, + IP  */
+	"Echo",
+	"Time Exceeded",	/* transit, frag reassem + IP */
+	"Parameter Problem",	/* pointer + IP */
+	"Timestamp",		/* id + seq + three timestamps */
+	"Timestamp Reply",	/* " */
+	"Info Request",		/* id + sq */
+	"Info Reply"		/* " */
+};
+#endif
+
+/*
+ * pr_icmph --
+ *	Print a descriptive string about an ICMP header.
+ */
+pr_icmph(icp)
+	struct icmp *icp;
+{
+	switch(icp->icmp_type) {
+	case ICMP_ECHOREPLY:
+		(void)printf("Echo Reply\n");
+		/* XXX ID + Seq + Data */
+		break;
+	case ICMP_UNREACH:
+		switch(icp->icmp_code) {
+		case ICMP_UNREACH_NET:
+			(void)printf("Destination Net Unreachable\n");
+			break;
+		case ICMP_UNREACH_HOST:
+			(void)printf("Destination Host Unreachable\n");
+			break;
+		case ICMP_UNREACH_PROTOCOL:
+			(void)printf("Destination Protocol Unreachable\n");
+			break;
+		case ICMP_UNREACH_PORT:
+			(void)printf("Destination Port Unreachable\n");
+			break;
+		case ICMP_UNREACH_NEEDFRAG:
+			(void)printf("frag needed and DF set\n");
+			break;
+		case ICMP_UNREACH_SRCFAIL:
+			(void)printf("Source Route Failed\n");
+			break;
+		default:
+			(void)printf("Dest Unreachable, Bad Code: %d\n",
+			    icp->icmp_code);
+			break;
+		}
+		/* Print returned IP header information */
+#ifndef icmp_data
+		pr_retip(&icp->icmp_ip);
+#else
+		pr_retip((struct ip *)icp->icmp_data);
+#endif
+		break;
+	case ICMP_SOURCEQUENCH:
+		(void)printf("Source Quench\n");
+#ifndef icmp_data
+		pr_retip(&icp->icmp_ip);
+#else
+		pr_retip((struct ip *)icp->icmp_data);
+#endif
+		break;
+	case ICMP_REDIRECT:
+		switch(icp->icmp_code) {
+		case ICMP_REDIRECT_NET:
+			(void)printf("Redirect Network");
+			break;
+		case ICMP_REDIRECT_HOST:
+			(void)printf("Redirect Host");
+			break;
+		case ICMP_REDIRECT_TOSNET:
+			(void)printf("Redirect Type of Service and Network");
+			break;
+		case ICMP_REDIRECT_TOSHOST:
+			(void)printf("Redirect Type of Service and Host");
+			break;
+		default:
+			(void)printf("Redirect, Bad Code: %d", icp->icmp_code);
+			break;
+		}
+		(void)printf("(New addr: 0x%08lx)\n", icp->icmp_gwaddr.s_addr);
+#ifndef icmp_data
+		pr_retip(&icp->icmp_ip);
+#else
+		pr_retip((struct ip *)icp->icmp_data);
+#endif
+		break;
+	case ICMP_ECHO:
+		(void)printf("Echo Request\n");
+		/* XXX ID + Seq + Data */
+		break;
+	case ICMP_TIMXCEED:
+		switch(icp->icmp_code) {
+		case ICMP_TIMXCEED_INTRANS:
+			(void)printf("Time to live exceeded\n");
+			break;
+		case ICMP_TIMXCEED_REASS:
+			(void)printf("Frag reassembly time exceeded\n");
+			break;
+		default:
+			(void)printf("Time exceeded, Bad Code: %d\n",
+			    icp->icmp_code);
+			break;
+		}
+#ifndef icmp_data
+		pr_retip(&icp->icmp_ip);
+#else
+		pr_retip((struct ip *)icp->icmp_data);
+#endif
+		break;
+	case ICMP_PARAMPROB:
+		(void)printf("Parameter problem: pointer = 0x%02x\n",
+		    icp->icmp_hun.ih_pptr);
+#ifndef icmp_data
+		pr_retip(&icp->icmp_ip);
+#else
+		pr_retip((struct ip *)icp->icmp_data);
+#endif
+		break;
+	case ICMP_TSTAMP:
+		(void)printf("Timestamp\n");
+		/* XXX ID + Seq + 3 timestamps */
+		break;
+	case ICMP_TSTAMPREPLY:
+		(void)printf("Timestamp Reply\n");
+		/* XXX ID + Seq + 3 timestamps */
+		break;
+	case ICMP_IREQ:
+		(void)printf("Information Request\n");
+		/* XXX ID + Seq */
+		break;
+	case ICMP_IREQREPLY:
+		(void)printf("Information Reply\n");
+		/* XXX ID + Seq */
+		break;
+#ifdef ICMP_MASKREQ
+	case ICMP_MASKREQ:
+		(void)printf("Address Mask Request\n");
+		break;
+#endif
+#ifdef ICMP_MASKREPLY
+	case ICMP_MASKREPLY:
+		(void)printf("Address Mask Reply\n");
+		break;
+#endif
+	default:
+		(void)printf("Bad ICMP type: %d\n", icp->icmp_type);
+	}
+}
+
+/*
+ * pr_iph --
+ *	Print an IP header with options.
+ */
+pr_iph(ip)
+	struct ip *ip;
+{
+	int hlen;
+	u_char *cp;
+
+	hlen = ip->ip_hl << 2;
+	cp = (u_char *)ip + 20;		/* point to options */
+
+	(void)printf("Vr HL TOS  Len   ID Flg  off TTL Pro  cks      Src      Dst Data\n");
+	(void)printf(" %1x  %1x  %02x %04x %04x",
+	    ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id);
+	(void)printf("   %1x %04x", ((ip->ip_off) & 0xe000) >> 13,
+	    (ip->ip_off) & 0x1fff);
+	(void)printf("  %02x  %02x %04x", ip->ip_ttl, ip->ip_p, ip->ip_sum);
+	(void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr));
+	(void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr));
+	/* dump and option bytes */
+	while (hlen-- > 20) {
+		(void)printf("%02x", *cp++);
+	}
+	(void)putchar('\n');
+}
+
+/*
+ * pr_addr --
+ *	Return an ascii host address as a dotted quad and optionally with
+ * a hostname.
+ */
+char *
+pr_addr(l)
+	u_long l;
+{
+	struct hostent *hp;
+	static char buf[80];
+
+	if ((options & F_NUMERIC) ||
+	    !(hp = gethostbyaddr((char *)&l, 4, AF_INET)))
+		(void)sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)&l));
+	else
+		(void)sprintf(buf, "%s (%s)", hp->h_name,
+		    inet_ntoa(*(struct in_addr *)&l));
+	return(buf);
+}
+
+/*
+ * pr_retip --
+ *	Dump some info on a returned (via ICMP) IP packet.
+ */
+pr_retip(ip)
+	struct ip *ip;
+{
+	int hlen;
+	u_char *cp;
+
+	pr_iph(ip);
+	hlen = ip->ip_hl << 2;
+	cp = (u_char *)ip + hlen;
+
+	if (ip->ip_p == 6)
+		(void)printf("TCP: from port %u, to port %u (decimal)\n",
+		    (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
+	else if (ip->ip_p == 17)
+		(void)printf("UDP: from port %u, to port %u (decimal)\n",
+			(*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
+}
+
+fill(bp, patp)
+	char *bp, *patp;
+{
+	register int ii, jj, kk;
+	int pat[16];
+	char *cp;
+
+	for (cp = patp; *cp; cp++)
+		if (!isxdigit(*cp)) {
+			(void)fprintf(stderr,
+			    "ping: patterns must be specified as hex digits.\n");
+			exit(1);
+		}
+	ii = sscanf(patp,
+	    "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
+	    &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6],
+	    &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12],
+	    &pat[13], &pat[14], &pat[15]);
+
+	if (ii > 0)
+		for (kk = 0;
+		    kk <= MAXPACKET - (8 + sizeof(struct timeval) + ii);
+		    kk += ii)
+			for (jj = 0; jj < ii; ++jj)
+				bp[jj + kk] = pat[jj];
+	if (!(options & F_QUIET)) {
+		(void)printf("PATTERN: 0x");
+		for (jj = 0; jj < ii; ++jj)
+			(void)printf("%02x", bp[jj] & 0xFF);
+		(void)printf("\n");
+	}
+}
+
+usage()
+{
+	(void)fprintf(stderr,
+	    "usage: ping [-Rdfnqrv] [-c count] [-i wait] [-l preload]\n\t[-p pattern] [-s packetsize] host\n");
+	exit(1);
+}
diff --git a/portmap.tproj/Makefile b/portmap.tproj/Makefile
new file mode 100644
index 0000000..5a91e65
--- /dev/null
+++ b/portmap.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = portmap
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = portmap.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble portmap.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/portmap.tproj/Makefile.postamble b/portmap.tproj/Makefile.postamble
new file mode 100644
index 0000000..f5c79e2
--- /dev/null
+++ b/portmap.tproj/Makefile.postamble
@@ -0,0 +1,110 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app)
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+
+
+# Change defaults assumed by the standard app makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if
+# you would like changes to them to invalidate previous builds.  The project
+# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build.
+#MAKEFILES = Makefile 
+
+# Optimization flag passed to compiler:
+#OPTIMIZATION_CFLAG = -O
+
+# Flags always passed to compiler:
+#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall  
+
+# Flags passed to compiler in normal 'app' compiles:
+#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG)
+
+# Flags passed to compiler in 'debug' compiles:
+#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG
+
+# Flags passed to compiler in 'profile' compiles
+#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User to chown app to
+#INSTALL_AS_GROUP = wheel      # Group to chgrp app to 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for bundles, apps with bundles, and apps without bundles, 
+# respectively.
+#RELOCATABLE_STRIP_OPTS = -x -u
+#DYLD_APP_STRIP_OPTS = -A -n
+#APP_STRIP_OPTS = 
+#TOOL_STRIP_OPTS = 
+#LIBRARY_STRIP_OPTS = -x -S   # Note: -S strips debugging symbols
+# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but
+#  developers doing their own dynamic loading should set this to 
+#  $(DYLD_APP_STRIP_OPTS)).
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Typical 
+# user-defined rules are before_install and after_install (please don't 
+# redefine things like install or app, as they are owned by the top-level 
+# Makefile API), which are rules that get invoked before and after the install 
+# target runs.  Such rules should be specified with the '::' syntax rather than 
+# a single colon.
diff --git a/portmap.tproj/Makefile.preamble b/portmap.tproj/Makefile.preamble
new file mode 100644
index 0000000..2c9003c
--- /dev/null
+++ b/portmap.tproj/Makefile.preamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags here.  To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+
+BUNDLELDFLAGS =            # use iff project is a bundle
+PALETTELDFLAGS =           # use iff project is a palette
+
+## Specify which headers in this project should be published to the outside 
+## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be 
+## prepended by DSTROOT, below.  Any subset of these public headers can be
+## precompiled automatically after installation, with extra user-defined flags.
+PUBLIC_HEADER_DIR = 
+PUBLIC_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+## Configure what is linked in at each level here.  Libraries are only used in
+## the final 'app' linking step.  Final 'app' linking is only done via the
+## 'app', 'debug', and 'profile' targets when they are invoked for
+## the top-level app.
+
+# Additional relocatables to be linked in at this level
+OTHER_OFILES = 
+# Additional libs to link apps against ('app' target)
+#OTHER_LIBS = 
+# Additional libs to link apps against ('debug' target)
+OTHER_DEBUG_LIBS = 
+# Additional libs to link apps against ('profile' target)
+OTHER_PROF_LIBS = 
+
+# More 'app' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# More 'debug' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_DEBUG_LIBS = 
+# More 'profile' libs when $(JAPANESE) = "YES"
+OTHER_JAPANESE_PROF_LIBS = 
+
+# If this is a bundle, and you *know* the enclosing application will not
+# be linking with a library which you require in your bundle code, then
+# mention it here so that it gets linked into the bundle.  Note that this
+# is wasteful but sometimes necessary.
+BUNDLE_LIBS = 
+
+## Configure how things get built here.  Additional dependencies, sourcefiles, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+# Precompiled headers to be built before any compilation occurs (e.g., draw.p)
+PRECOMPS = 
+
+# Targets to be built before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# Set the following to "YES" if you want the old behavior of recursively
+# cleaning all nested subprojects during 'make clean'.
+CLEAN_ALL_SUBPROJECTS =
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+# To include a version string, project source must exist in a directory named
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/portmap.tproj/PB.project b/portmap.tproj/PB.project
new file mode 100644
index 0000000..b9275bb
--- /dev/null
+++ b/portmap.tproj/PB.project
@@ -0,0 +1,41 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (portmap.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, portmap.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = portmap; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/portmap.tproj/portmap.8 b/portmap.tproj/portmap.8
new file mode 100644
index 0000000..a651f5f
--- /dev/null
+++ b/portmap.tproj/portmap.8
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1987 Sun Microsystems
+.\" Copyright (c) 1990, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)portmap.8	8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt PORTMAP 8
+.Os BSD 4.3
+.Sh NAME
+.Nm portmap
+.Nd
+.Tn DARPA
+port to
+.Tn RPC
+program number mapper
+.Sh SYNOPSIS
+.Nm portmap
+.Op Fl d
+.Sh DESCRIPTION
+.Nm Portmap
+is a server that converts
+.Tn RPC
+program numbers into
+.Tn DARPA
+protocol port numbers.
+It must be running in order to make
+.Tn RPC
+calls.
+.Pp
+When an
+.Tn RPC
+server is started, it will tell
+.Nm portmap
+what port number it is listening to, and what
+.Tn RPC
+program numbers it is prepared to serve.
+When a client wishes to make an
+.Tn RPC
+call to a given program number,
+it will first contact
+.Nm portmap
+on the server machine to determine
+the port number where
+.Tn RPC
+packets should be sent.
+.Pp
+.Nm Portmap
+must be started before any
+.Tn RPC
+servers are invoked.
+.Pp
+Normally
+.Nm portmap
+forks and dissociates itself from the terminal
+like any other daemon.
+.Nm Portmap
+then logs errors using
+.Xr syslog 3 .
+.Pp
+Option available:
+.Bl -tag -width Ds
+.It Fl d
+(debug) prevents
+.Nm portmap
+from running as a daemon,
+and causes errors and debugging information
+to be printed to the standard error output.
+.El
+.Sh SEE ALSO
+.Xr inetd.conf 5 ,
+.Xr rpcinfo 8 ,
+.Xr inetd 8
+.Sh BUGS
+If
+.Nm portmap
+crashes, all servers must be restarted.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3
diff --git a/portmap.tproj/portmap.c b/portmap.tproj/portmap.c
new file mode 100644
index 0000000..8a6c53c
--- /dev/null
+++ b/portmap.tproj/portmap.c
@@ -0,0 +1,661 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)portmap.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+@(#)portmap.c	2.3 88/08/11 4.0 RPCSRC
+static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro";
+*/
+
+/*
+ * portmap.c, Implements the program,version to port number mapping for
+ * rpc.
+ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#include <errno.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <netinfo/nibind_prot.h>
+
+#define NETINFO_TAG_NETWORK "network"
+#define NETINFO_NETWORK_DIR_PATH "/var/db/netinfo/network.nidb"
+#define NETINFO_STAT_LATENCY 30
+
+static int have_tag_network = 0;
+static struct timeval last_network_stat = {0, 0};
+
+void reg_service();
+void reap();
+static void callit();
+struct pmaplist *pmaplist;
+int debugging = 0;
+extern int errno;
+extern int svc_maxfd;
+
+extern int get_myaddress();
+
+static void
+portmap_svc_run()
+{
+	fd_set readfds;
+	int status;
+	
+	for (;;)
+	{
+		readfds = svc_fdset;
+		switch ((status = select(svc_maxfd+1, &readfds, NULL, NULL, NULL)))
+		{
+			case -1:
+				if (errno == EINTR) continue;
+
+				if ((errno == EFAULT) || (errno == EINVAL))
+				{
+					syslog(LOG_ERR, "aborting - select error %d (%s)",
+						errno, strerror(errno));
+					return;
+				}
+
+				syslog(LOG_NOTICE, "ignoring select error %d (%s)",
+					errno, strerror(errno));
+				continue;
+
+			case 0:
+				continue;
+
+			default:
+				svc_getreqset(&readfds);
+		}
+	}
+}
+
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	SVCXPRT *xprt;
+	int sock, c;
+	struct sockaddr_in addr;
+	int len = sizeof(struct sockaddr_in);
+	register struct pmaplist *pml;
+
+	while ((c = getopt(argc, argv, "d")) != EOF) {
+		switch (c) {
+
+		case 'd':
+			debugging = 1;
+			break;
+
+		default:
+			(void) fprintf(stderr, "usage: %s [-d]\n", argv[0]);
+			exit(1);
+		}
+	}
+
+	if (!debugging && daemon(0, 0)) {
+		(void) fprintf(stderr, "portmap: fork: %s", strerror(errno));
+		exit(1);
+	}
+
+	openlog("portmap", debugging ? LOG_PID | LOG_PERROR : LOG_PID,
+	    LOG_DAEMON);
+
+	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+		syslog(LOG_ERR, "cannot create udp socket: %m");
+		exit(1);
+	}
+
+	addr.sin_addr.s_addr = 0;
+	addr.sin_family = AF_INET;
+	addr.sin_port = htons(PMAPPORT);
+	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+		syslog(LOG_ERR, "cannot bind udp: %m");
+		exit(1);
+	}
+
+	if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
+		syslog(LOG_ERR, "couldn't do udp_create");
+		exit(1);
+	}
+	/* make an entry for ourself */
+	pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist));
+	pml->pml_next = 0;
+	pml->pml_map.pm_prog = PMAPPROG;
+	pml->pml_map.pm_vers = PMAPVERS;
+	pml->pml_map.pm_prot = IPPROTO_UDP;
+	pml->pml_map.pm_port = PMAPPORT;
+	pmaplist = pml;
+
+	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+		syslog(LOG_ERR, "cannot create tcp socket: %m");
+		exit(1);
+	}
+	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+		syslog(LOG_ERR, "cannot bind udp: %m");
+		exit(1);
+	}
+	if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))
+	    == (SVCXPRT *)NULL) {
+		syslog(LOG_ERR, "couldn't do tcp_create");
+		exit(1);
+	}
+	/* make an entry for ourself */
+	pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist));
+	pml->pml_map.pm_prog = PMAPPROG;
+	pml->pml_map.pm_vers = PMAPVERS;
+	pml->pml_map.pm_prot = IPPROTO_TCP;
+	pml->pml_map.pm_port = PMAPPORT;
+	pml->pml_next = pmaplist;
+	pmaplist = pml;
+
+	(void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
+
+	/* initialize "network.nidb" timer */
+	gettimeofday(&last_network_stat, NULL);
+
+	(void)signal(SIGCHLD, reap);
+	portmap_svc_run();
+	syslog(LOG_ERR, "run_svc returned unexpectedly");
+	abort();
+}
+
+#ifndef lint
+/* need to override perror calls in rpc library */
+__private_extern__
+void
+perror(what)
+	const char *what;
+{
+
+	syslog(LOG_ERR, "%s: %m", what);
+}
+#endif
+
+static struct pmaplist *
+find_service(prog, vers, prot)
+	u_long prog, vers, prot;
+{
+	register struct pmaplist *hit = NULL;
+	register struct pmaplist *pml;
+
+	for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
+		if ((pml->pml_map.pm_prog != prog) ||
+			(pml->pml_map.pm_prot != prot))
+			continue;
+		hit = pml;
+		if (pml->pml_map.pm_vers == vers)
+		    break;
+	}
+	return (hit);
+}
+
+/* 
+ * 1 OK, 0 not
+ */
+void
+reg_service(rqstp, xprt)
+	struct svc_req *rqstp;
+	SVCXPRT *xprt;
+{
+	struct pmap reg;
+	struct pmaplist *pml, *prevpml, *fnd;
+	int ans, port;
+	caddr_t t;
+	
+	if (debugging)
+		(void) fprintf(stderr, "server: about do a switch\n");
+	switch (rqstp->rq_proc) {
+
+	case PMAPPROC_NULL:
+		/*
+		 * Null proc call
+		 */
+		if (!svc_sendreply(xprt, xdr_void, (caddr_t)0) && debugging) {
+			abort();
+		}
+		break;
+
+	case PMAPPROC_SET:
+		/*
+		 * Set a program,version to port mapping
+		 */
+		if (!svc_getargs(xprt, xdr_pmap, &reg))
+			svcerr_decode(xprt);
+		else {
+			/*
+			 * check to see if already used
+			 * find_service returns a hit even if
+			 * the versions don't match, so check for it
+			 */
+			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+			if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
+				if (fnd->pml_map.pm_port == reg.pm_port) {
+					ans = 1;
+					goto done;
+				}
+				else {
+					ans = 0;
+					goto done;
+				}
+			} else {
+				/* 
+				 * add to END of list
+				 */
+				pml = (struct pmaplist *)
+				    malloc((u_int)sizeof(struct pmaplist));
+				pml->pml_map = reg;
+				pml->pml_next = 0;
+				if (pmaplist == 0) {
+					pmaplist = pml;
+				} else {
+					for (fnd= pmaplist; fnd->pml_next != 0;
+					    fnd = fnd->pml_next);
+					fnd->pml_next = pml;
+				}
+				ans = 1;
+			}
+		done:
+			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
+			    debugging) {
+				(void) fprintf(stderr, "svc_sendreply\n");
+				abort();
+			}
+		}
+		break;
+
+	case PMAPPROC_UNSET:
+		/*
+		 * Remove a program,version to port mapping.
+		 */
+		if (!svc_getargs(xprt, xdr_pmap, &reg))
+			svcerr_decode(xprt);
+		else {
+			ans = 0;
+			for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
+				if ((pml->pml_map.pm_prog != reg.pm_prog) ||
+					(pml->pml_map.pm_vers != reg.pm_vers)) {
+					/* both pml & prevpml move forwards */
+					prevpml = pml;
+					pml = pml->pml_next;
+					continue;
+				}
+				/* found it; pml moves forward, prevpml stays */
+				ans = 1;
+				t = (caddr_t)pml;
+				pml = pml->pml_next;
+				if (prevpml == NULL)
+					pmaplist = pml;
+				else
+					prevpml->pml_next = pml;
+				free(t);
+			}
+			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
+			    debugging) {
+				(void) fprintf(stderr, "svc_sendreply\n");
+				abort();
+			}
+		}
+		break;
+
+	case PMAPPROC_GETPORT:
+		/*
+		 * Lookup the mapping for a program,version and return its port
+		 */
+		if (!svc_getargs(xprt, xdr_pmap, &reg))
+			svcerr_decode(xprt);
+		else {
+			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+			if (fnd)
+				port = fnd->pml_map.pm_port;
+			else
+				port = 0;
+			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) &&
+			    debugging) {
+				(void) fprintf(stderr, "svc_sendreply\n");
+				abort();
+			}
+		}
+		break;
+
+	case PMAPPROC_DUMP:
+		/*
+		 * Return the current set of mapped program,version
+		 */
+		if (!svc_getargs(xprt, xdr_void, NULL))
+			svcerr_decode(xprt);
+		else {
+			if ((!svc_sendreply(xprt, xdr_pmaplist,
+			    (caddr_t)&pmaplist)) && debugging) {
+				(void) fprintf(stderr, "svc_sendreply\n");
+				abort();
+			}
+		}
+		break;
+
+	case PMAPPROC_CALLIT:
+		/*
+		 * Calls a procedure on the local machine.  If the requested
+		 * procedure is not registered this procedure does not return
+		 * error information!!
+		 * This procedure is only supported on rpc/udp and calls via 
+		 * rpc/udp.  It passes null authentication parameters.
+		 */
+		callit(rqstp, xprt);
+		break;
+
+	default:
+		svcerr_noproc(xprt);
+		break;
+	}
+}
+
+
+/*
+ * Stuff for the rmtcall service
+ */
+#define ARGSIZE 9000
+
+struct encap_parms {
+	u_long arglen;
+	char *args;
+};
+
+static bool_t
+xdr_encap_parms(xdrs, epp)
+	XDR *xdrs;
+	struct encap_parms *epp;
+{
+	return (xdr_bytes(xdrs, &(epp->args), (int *)&(epp->arglen), ARGSIZE));
+}
+
+struct rmtcallargs {
+	u_long	rmt_prog;
+	u_long	rmt_vers;
+	u_long	rmt_port;
+	u_long	rmt_proc;
+	struct encap_parms rmt_args;
+};
+
+static bool_t
+xdr_rmtcall_args(xdrs, cap)
+	register XDR *xdrs;
+	register struct rmtcallargs *cap;
+{
+
+	/* does not get a port number */
+	if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
+	    xdr_u_long(xdrs, &(cap->rmt_vers)) &&
+	    xdr_u_long(xdrs, &(cap->rmt_proc))) {
+		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+	}
+	return (FALSE);
+}
+
+static bool_t
+xdr_rmtcall_result(xdrs, cap)
+	register XDR *xdrs;
+	register struct rmtcallargs *cap;
+{
+	if (xdr_u_long(xdrs, &(cap->rmt_port)))
+		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+	return (FALSE);
+}
+
+/*
+ * only worries about the struct encap_parms part of struct rmtcallargs.
+ * The arglen must already be set!!
+ */
+static bool_t
+xdr_opaque_parms(xdrs, cap)
+	XDR *xdrs;
+	struct rmtcallargs *cap;
+{
+
+	return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
+}
+
+/*
+ * This routine finds and sets the length of incoming opaque paraters
+ * and then calls xdr_opaque_parms.
+ */
+static bool_t
+xdr_len_opaque_parms(xdrs, cap)
+	register XDR *xdrs;
+	struct rmtcallargs *cap;
+{
+	register u_int beginpos, lowpos, highpos, currpos, pos;
+
+	beginpos = lowpos = pos = xdr_getpos(xdrs);
+	highpos = lowpos + ARGSIZE;
+	while ((int)(highpos - lowpos) >= 0) {
+		currpos = (lowpos + highpos) / 2;
+		if (xdr_setpos(xdrs, currpos)) {
+			pos = currpos;
+			lowpos = currpos + 1;
+		} else {
+			highpos = currpos - 1;
+		}
+	}
+	xdr_setpos(xdrs, beginpos);
+	cap->rmt_args.arglen = pos - beginpos;
+	return (xdr_opaque_parms(xdrs, cap));
+}
+
+/*
+ * Call a remote procedure service
+ * This procedure is very quiet when things go wrong.
+ * The proc is written to support broadcast rpc.  In the broadcast case,
+ * a machine should shut-up instead of complain, less the requestor be
+ * overrun with complaints at the expense of not hearing a valid reply ...
+ *
+ * This now forks so that the program & process that it calls can call 
+ * back to the portmapper.
+ */
+static void
+callit(rqstp, xprt)
+	struct svc_req *rqstp;
+	SVCXPRT *xprt;
+{
+	struct rmtcallargs a;
+	struct pmaplist *pml;
+	u_short port;
+	struct sockaddr_in me;
+	int pid, so = -1;
+	CLIENT *client;
+	struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
+	struct timeval timeout;
+	char buf[ARGSIZE];
+	char tag[MAXPATHLEN];
+	int off, taglen;
+	unsigned int delta;
+	struct stat sb;
+	struct timeval now;
+
+	timeout.tv_sec = 5;
+	timeout.tv_usec = 0;
+	a.rmt_args.args = buf;
+	if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
+		return;
+
+	/*
+	 * Drop NIBIND_BIND calls for the parent tag "network" if the database 
+	 * doesn't exist.  This prevents excessive fork() calls.
+	 */
+	if ((have_tag_network == 0) && (a.rmt_prog == NIBIND_PROG) && (a.rmt_proc == NIBIND_BIND))
+	{
+		/* Skip sender address and child tag */
+		memmove(&taglen, a.rmt_args.args + 4, 4);
+		taglen = ntohl(taglen);
+		off = 8 + (((taglen + 3) / 4) * 4);
+
+		/* Get parent tag */
+		memmove(&taglen, a.rmt_args.args + off, 4);
+		taglen = ntohl(taglen);
+		if (taglen >= MAXPATHLEN) return;
+
+		off += 4;
+		memmove(tag, a.rmt_args.args + off, taglen);
+		tag[taglen] = '\0';
+
+		/*
+		 * If there was no network.nidb a few seconds ago, drop the requset.
+		 */
+		if (!strcmp(tag, NETINFO_TAG_NETWORK))
+		{
+			gettimeofday(&now, NULL);
+			delta = now.tv_sec - last_network_stat.tv_sec;
+			if (delta < NETINFO_STAT_LATENCY) return;
+
+			if (stat(NETINFO_NETWORK_DIR_PATH, &sb) < 0)
+			{
+				last_network_stat = now;
+				return;
+			}
+
+			have_tag_network = 1;
+		}
+	}
+
+	if ((pml = find_service(a.rmt_prog, a.rmt_vers,
+	    (u_long)IPPROTO_UDP)) == NULL)
+		return;
+	/*
+	 * fork a child to do the work.  Parent immediately returns.
+	 * Child exits upon completion.
+	 */
+	if ((pid = fork()) != 0) {
+		if (pid < 0)
+			syslog(LOG_ERR, "CALLIT (prog %lu): fork: %m",
+			    a.rmt_prog);
+		return;
+	}
+	port = pml->pml_map.pm_port;
+	get_myaddress(&me);
+	me.sin_port = htons(port);
+	client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &so);
+	if (client != (CLIENT *)NULL) {
+		if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
+			client->cl_auth = authunix_create(au->aup_machname,
+			   au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
+		}
+		a.rmt_port = (u_long)port;
+		if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
+		    xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
+			svc_sendreply(xprt, xdr_rmtcall_result, (caddr_t)&a);
+		}
+		AUTH_DESTROY(client->cl_auth);
+		clnt_destroy(client);
+	}
+	(void)close(so);
+	exit(0);
+}
+
+void
+reap()
+{
+	while (wait3((int *)NULL, WNOHANG, (struct rusage *)NULL) > 0);
+}
diff --git a/rarpd.tproj/Makefile b/rarpd.tproj/Makefile
new file mode 100644
index 0000000..34700cd
--- /dev/null
+++ b/rarpd.tproj/Makefile
@@ -0,0 +1,52 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rarpd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = rarpd.c
+
+OTHERSRCS = Makefile.dist Makefile.preamble rarpd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+HEADER_PATHS = -I.
+NEXTSTEP_PB_CFLAGS = -DTFTP_DIR=\"/tftpboot\"
+WINDOWS_PB_CFLAGS = -DTFTP_DIR=\"/tftpboot\"
+PDO_UNIX_PB_CFLAGS = -DTFTP_DIR=\"/tftpboot\"
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rarpd.tproj/Makefile.dist b/rarpd.tproj/Makefile.dist
new file mode 100644
index 0000000..2c02ca5
--- /dev/null
+++ b/rarpd.tproj/Makefile.dist
@@ -0,0 +1,10 @@
+# @(#) $Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:57:59 wsanchez Exp $
+
+PROG=	rarpd
+SRCS=	rarpd.c
+
+CFLAGS+=-I${.CURDIR} -DTFTP_DIR=\"/tftpboot\"
+
+MAN8=	rarpd.0
+
+.include <bsd.prog.mk>
diff --git a/rarpd.tproj/Makefile.preamble b/rarpd.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/rarpd.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/rarpd.tproj/PB.project b/rarpd.tproj/PB.project
new file mode 100644
index 0000000..8c54327
--- /dev/null
+++ b/rarpd.tproj/PB.project
@@ -0,0 +1,37 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        HEADERSEARCH = (.); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LINKED = (rarpd.c); 
+        OTHER_SOURCES = (Makefile.dist, Makefile.preamble, rarpd.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = "-DTFTP_DIR=\\\"/tftpboot\\\""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = "-DTFTP_DIR=\\\"/tftpboot\\\""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rarpd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = "-DTFTP_DIR=\\\"/tftpboot\\\""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rarpd.tproj/rarpd.8 b/rarpd.tproj/rarpd.8
new file mode 100644
index 0000000..f090c47
--- /dev/null
+++ b/rarpd.tproj/rarpd.8
@@ -0,0 +1,92 @@
+.\"
+.\" Copyright (c) 1988-1990 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that: (1) source code distributions
+.\" retain the above copyright notice and this paragraph in its entirety, (2)
+.\" distributions including binary code include the above copyright notice and
+.\" this paragraph in its entirety in the documentation or other materials
+.\" provided with the distribution, and (3) all advertising materials mentioning
+.\" features or use of this software display the following acknowledgement:
+.\" ``This product includes software developed by the University of California,
+.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+.\" the University nor the names of its contributors may be used to endorse
+.\" or promote products derived from this software without specific prior
+.\" written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\" @(#) $Id: rarpd.8,v 1.1.1.1 1999/05/02 03:57:59 wsanchez Exp $
+.\"
+.Dd October 26, 1990
+.Dt RARPD 8
+.Sh NAME
+.Nm rarpd 
+.Nd Reverse ARP Daemon
+.Sh SYNOPSIS
+.Nm rarpd 
+.Op Fl adf
+.Op Ar interface
+.Sh DESCRIPTION
+.Nm Rarpd
+services Reverse ARP requests on the Ethernet connected to
+.Ar interface.
+Upon receiving a request, 
+.Nm rarpd
+maps the target hardware address to an IP address via its name, which 
+must be present in both the
+.Xr ethers 5
+and 
+.Xr hosts 5
+databases.
+If a host does not exist in both databases, the translation cannot
+proceed and a reply will not be sent.
+.Pp
+Additionally, a request is honored only if the server
+(i.e., the host that rarpd is running on)
+can "boot" the target; that is, if the directory 
+.Pa /tftpboot/ Ns Em ipaddr
+exists, where 
+.Rm ipaddr
+is the target IP address.
+.Pp
+In normal operation, 
+.Nm rarpd
+forks a copy of itself and runs in
+the background.  Anomalies and errors are reported via 
+.Xr syslog 3 .
+.Sh OPTIONS
+.Bl -tag -width indent
+.It Fl a
+Listen on all the Ethernets attached to the system.
+If 
+.Sq Fl a 
+is omitted, an interface must be specified.
+.It Fl d
+Run in debug mode, with all the output to stderr.
+This option implies the 
+.Fl f
+option.
+.It Fl f
+Run in the foreground.
+.El
+.Sh FILES
+.Bl -tag -width Pa -compact
+.It Pa /etc/ethers
+.It Pa /etc/hosts
+.It Pa /tftpboot
+.El
+.Sh SEE ALSO
+.Xr bpf 4 ,
+.Rs 
+.%R A Reverse Address  Resolution Protocol
+.%N RFC 903
+.%A Finlayson, R.
+.%A Mann, T.
+.%A Mogul, J.C.
+.%A Theimer, M.
+.Re
+.Sh AUTHORS
+Craig Leres (leres@ee.lbl.gov) and Steven McCanne (mccanne@ee.lbl.gov).
+Lawrence Berkeley Laboratory, University of California, Berkeley, CA.
diff --git a/rarpd.tproj/rarpd.c b/rarpd.tproj/rarpd.c
new file mode 100644
index 0000000..890be78
--- /dev/null
+++ b/rarpd.tproj/rarpd.c
@@ -0,0 +1,831 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+char    copyright[] =
+"@(#) Copyright (c) 1990 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif				/* not lint */
+
+#ifndef lint
+static char rcsid[] =
+"@(#) $Id: rarpd.c,v 1.1.1.1 1999/05/02 03:57:59 wsanchez Exp $";
+#endif
+
+
+/*
+ * rarpd - Reverse ARP Daemon
+ *
+ * Usage:	rarpd -a [ -d -f ]
+ *		rarpd [ -d -f ] interface
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <net/bpf.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <sys/errno.h>
+#include <sys/file.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <dirent.h>
+
+#define FATAL		1	/* fatal error occurred */
+#define NONFATAL	0	/* non fatal error occurred */
+
+/*
+ * The structure for each interface.
+ */
+struct if_info {
+	int     ii_fd;		/* BPF file descriptor */
+	u_char  ii_eaddr[6];	/* Ethernet address of this interface */
+	u_long  ii_ipaddr;	/* IP address of this interface */
+	u_long  ii_netmask;	/* subnet or net mask */
+	struct if_info *ii_next;
+};
+/*
+ * The list of all interfaces that are being listened to.  rarp_loop()
+ * "selects" on the descriptors in this list.
+ */
+struct if_info *iflist;
+
+int    rarp_open     __P((char *));
+int    rarp_bootable __P((u_long));
+void   init_one      __P((char *));
+void   init_all      __P((void));
+void   rarp_loop     __P((void));
+void   lookup_eaddr  __P((char *, u_char *));
+void   lookup_ipaddr __P((char *, u_long *, u_long *));
+void   usage         __P((void));
+void   rarp_process  __P((struct if_info *, u_char *));
+void   rarp_reply    __P((struct if_info *, struct ether_header *, u_long));
+void   update_arptab __P((u_char *, u_long));
+void   err           __P((int, const char *,...));
+void   debug         __P((const char *,...));
+u_long ipaddrtonetmask __P((u_long));
+
+int     aflag = 0;		/* listen on "all" interfaces  */
+int     dflag = 0;		/* print debugging messages */
+int     fflag = 0;		/* don't fork */
+
+void
+main(argc, argv)
+	int     argc;
+	char  **argv;
+{
+	int     op, pid, devnull, f;
+	char   *ifname, *hostname, *name;
+
+	extern char *optarg;
+	extern int optind, opterr;
+
+	if (name = strrchr(argv[0], '/'))
+		++name;
+	else
+		name = argv[0];
+	if (*name == '-')
+		++name;
+
+	/* All error reporting is done through syslogs. */
+	openlog(name, LOG_PID | LOG_CONS, LOG_DAEMON);
+
+	opterr = 0;
+	while ((op = getopt(argc, argv, "adf")) != EOF) {
+		switch (op) {
+		case 'a':
+			++aflag;
+			break;
+
+		case 'd':
+			++dflag;
+			break;
+
+		case 'f':
+			++fflag;
+			break;
+
+		default:
+			usage();
+			/* NOTREACHED */
+		}
+	}
+	ifname = argv[optind++];
+	hostname = ifname ? argv[optind] : 0;
+	if ((aflag && ifname) || (!aflag && ifname == 0))
+		usage();
+
+	if (aflag)
+		init_all();
+	else
+		init_one(ifname);
+
+	if ((!fflag) && (!dflag)) {
+		pid = fork();
+		if (pid > 0)
+			/* Parent exits, leaving child in background. */
+			exit(0);
+		else
+			if (pid == -1) {
+				err(FATAL, "cannot fork");
+				/* NOTREACHED */
+			}
+		/* Fade into the background */
+		f = open("/dev/tty", O_RDWR);
+		if (f >= 0) {
+			if (ioctl(f, TIOCNOTTY, 0) < 0) {
+				err(FATAL, "TIOCNOTTY: %s", strerror(errno));
+				/* NOTREACHED */
+			}
+			(void) close(f);
+		}
+		(void) chdir("/");
+		(void) setpgrp(0, getpid());
+		devnull = open("/dev/null", O_RDWR);
+		if (devnull >= 0) {
+			(void) dup2(devnull, 0);
+			(void) dup2(devnull, 1);
+			(void) dup2(devnull, 2);
+			if (devnull > 2)
+				(void) close(devnull);
+		}
+	}
+	rarp_loop();
+}
+/*
+ * Add 'ifname' to the interface list.  Lookup its IP address and network
+ * mask and Ethernet address, and open a BPF file for it.
+ */
+void
+init_one(ifname)
+	char   *ifname;
+{
+	struct if_info *p;
+
+	p = (struct if_info *)malloc(sizeof(*p));
+	if (p == 0) {
+		err(FATAL, "malloc: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	p->ii_next = iflist;
+	iflist = p;
+
+	p->ii_fd = rarp_open(ifname);
+	lookup_eaddr(ifname, p->ii_eaddr);
+	lookup_ipaddr(ifname, &p->ii_ipaddr, &p->ii_netmask);
+}
+/*
+ * Initialize all "candidate" interfaces that are in the system
+ * configuration list.  A "candidate" is up, not loopback and not
+ * point to point.
+ */
+void
+init_all()
+{
+	char inbuf[8192];
+	struct ifconf ifc;
+	struct ifreq *ifr;
+	int fd;
+	int i, len;
+
+	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+		err(FATAL, "socket: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+
+	ifc.ifc_len = sizeof(inbuf);
+	ifc.ifc_buf = inbuf;
+	if (ioctl(fd, SIOCGIFCONF, (caddr_t)&ifc) < 0 ||
+	    ifc.ifc_len < sizeof(struct ifreq)) {
+		err(FATAL, "init_all: SIOCGIFCONF: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	ifr = ifc.ifc_req;
+	for (i = 0; i < ifc.ifc_len;
+	     i += len, ifr = (struct ifreq *)((caddr_t)ifr + len)) {
+		len = sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
+		if (ioctl(fd, SIOCGIFFLAGS, (caddr_t)ifr) < 0) {
+			err(FATAL, "init_all: SIOCGIFFLAGS: %s",
+			    strerror(errno));
+			/* NOTREACHED */
+		}
+		if ((ifr->ifr_flags &
+		    (IFF_UP | IFF_LOOPBACK | IFF_POINTOPOINT)) != IFF_UP)
+			continue;
+		init_one(ifr->ifr_name);
+	}
+	(void) close(fd);
+}
+
+void
+usage()
+{
+	(void) fprintf(stderr, "usage: rarpd -a [ -d -f ]\n");
+	(void) fprintf(stderr, "       rarpd [ -d -f ] interface\n");
+	exit(1);
+}
+
+static int
+bpf_open()
+{
+	int     fd;
+	int     n = 0;
+	char    device[sizeof "/dev/bpf000"];
+
+	/* Go through all the minors and find one that isn't in use. */
+	do {
+		(void) sprintf(device, "/dev/bpf%d", n++);
+		fd = open(device, O_RDWR);
+	} while (fd < 0 && errno == EBUSY);
+
+	if (fd < 0) {
+		err(FATAL, "%s: %s", device, strerror(errno));
+		/* NOTREACHED */
+	}
+	return fd;
+}
+/*
+ * Open a BPF file and attach it to the interface named 'device'.
+ * Set immediate mode, and set a filter that accepts only RARP requests.
+ */
+int
+rarp_open(device)
+	char   *device;
+{
+	int     fd;
+	struct ifreq ifr;
+	u_int   dlt;
+	int     immediate;
+
+	static struct bpf_insn insns[] = {
+		BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 12),
+		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ETHERTYPE_REVARP, 0, 3),
+		BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 20),
+		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ARPOP_REVREQUEST, 0, 1),
+		BPF_STMT(BPF_RET | BPF_K, sizeof(struct ether_arp) +
+		    sizeof(struct ether_header)),
+		BPF_STMT(BPF_RET | BPF_K, 0),
+	};
+	static struct bpf_program filter = {
+		sizeof insns / sizeof(insns[0]),
+		insns
+	};
+
+	fd = bpf_open();
+
+	/* Set immediate mode so packets are processed as they arrive. */
+	immediate = 1;
+	if (ioctl(fd, BIOCIMMEDIATE, &immediate) < 0) {
+		err(FATAL, "BIOCIMMEDIATE: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	(void) strncpy(ifr.ifr_name, device, sizeof ifr.ifr_name);
+	if (ioctl(fd, BIOCSETIF, (caddr_t) & ifr) < 0) {
+		err(FATAL, "BIOCSETIF: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	/* Check that the data link layer is an Ethernet; this code won't work
+	 * with anything else. */
+	if (ioctl(fd, BIOCGDLT, (caddr_t) & dlt) < 0) {
+		err(FATAL, "BIOCGDLT: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	if (dlt != DLT_EN10MB) {
+		err(FATAL, "%s is not an ethernet", device);
+		/* NOTREACHED */
+	}
+	/* Set filter program. */
+	if (ioctl(fd, BIOCSETF, (caddr_t) & filter) < 0) {
+		err(FATAL, "BIOCSETF: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	return fd;
+}
+/*
+ * Perform various sanity checks on the RARP request packet.  Return
+ * false on failure and log the reason.
+ */
+static int
+rarp_check(p, len)
+	u_char *p;
+	int     len;
+{
+	struct ether_header *ep = (struct ether_header *) p;
+	struct ether_arp *ap = (struct ether_arp *) (p + sizeof(*ep));
+
+	(void) debug("got a packet");
+
+	if (len < sizeof(*ep) + sizeof(*ap)) {
+		err(NONFATAL, "truncated request");
+		return 0;
+	}
+	/* XXX This test might be better off broken out... */
+	if (ntohs (ep->ether_type) != ETHERTYPE_REVARP ||
+	    ntohs (ap->arp_hrd) != ARPHRD_ETHER ||
+	    ntohs (ap->arp_op) != ARPOP_REVREQUEST ||
+	    ntohs (ap->arp_pro) != ETHERTYPE_IP ||
+	    ap->arp_hln != 6 || ap->arp_pln != 4) {
+		err(NONFATAL, "request fails sanity check");
+		return 0;
+	}
+	if (bcmp((char *) &ep->ether_shost, (char *) &ap->arp_sha, 6) != 0) {
+		err(NONFATAL, "ether/arp sender address mismatch");
+		return 0;
+	}
+	if (bcmp((char *) &ap->arp_sha, (char *) &ap->arp_tha, 6) != 0) {
+		err(NONFATAL, "ether/arp target address mismatch");
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Loop indefinitely listening for RARP requests on the
+ * interfaces in 'iflist'.
+ */
+void
+rarp_loop()
+{
+	u_char *buf, *bp, *ep;
+	int     cc, fd;
+	fd_set  fds, listeners;
+	int     bufsize, maxfd = 0;
+	struct if_info *ii;
+
+	if (iflist == 0) {
+		err(FATAL, "no interfaces");
+		/* NOTREACHED */
+	}
+	if (ioctl(iflist->ii_fd, BIOCGBLEN, (caddr_t) & bufsize) < 0) {
+		err(FATAL, "BIOCGBLEN: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	buf = (u_char *) malloc((unsigned) bufsize);
+	if (buf == 0) {
+		err(FATAL, "malloc: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	/*
+         * Find the highest numbered file descriptor for select().
+         * Initialize the set of descriptors to listen to.
+         */
+	FD_ZERO(&fds);
+	for (ii = iflist; ii; ii = ii->ii_next) {
+		FD_SET(ii->ii_fd, &fds);
+		if (ii->ii_fd > maxfd)
+			maxfd = ii->ii_fd;
+	}
+	while (1) {
+		listeners = fds;
+		if (select(maxfd + 1, &listeners, (struct fd_set *) 0,
+			(struct fd_set *) 0, (struct timeval *) 0) < 0) {
+			err(FATAL, "select: %s", strerror(errno));
+			/* NOTREACHED */
+		}
+		for (ii = iflist; ii; ii = ii->ii_next) {
+			fd = ii->ii_fd;
+			if (!FD_ISSET(fd, &listeners))
+				continue;
+	again:
+			cc = read(fd, (char *) buf, bufsize);
+			/* Don't choke when we get ptraced */
+			if (cc < 0 && errno == EINTR)
+				goto again;
+			/* Due to a SunOS bug, after 2^31 bytes, the file
+			 * offset overflows and read fails with EINVAL.  The
+			 * lseek() to 0 will fix things. */
+			if (cc < 0) {
+				if (errno == EINVAL &&
+				    (lseek(fd, 0, SEEK_CUR) + bufsize) < 0) {
+					(void) lseek(fd, 0, 0);
+					goto again;
+				}
+				err(FATAL, "read: %s", strerror(errno));
+				/* NOTREACHED */
+			}
+			/* Loop through the packet(s) */
+#define bhp ((struct bpf_hdr *)bp)
+			bp = buf;
+			ep = bp + cc;
+			while (bp < ep) {
+				register int caplen, hdrlen;
+
+				caplen = bhp->bh_caplen;
+				hdrlen = bhp->bh_hdrlen;
+				if (rarp_check(bp + hdrlen, caplen))
+					rarp_process(ii, bp + hdrlen);
+				bp += BPF_WORDALIGN(hdrlen + caplen);
+			}
+		}
+	}
+}
+#ifndef TFTP_DIR
+#define TFTP_DIR "/tftpboot"
+#endif
+
+/*
+ * True if this server can boot the host whose IP address is 'addr'.
+ * This check is made by looking in the tftp directory for the
+ * configuration file.
+ */
+int
+rarp_bootable(addr)
+	u_long  addr;
+{
+	register struct dirent *dent;
+	register DIR *d;
+	char    ipname[9];
+	static DIR *dd = 0;
+
+	(void) sprintf(ipname, "%08X", addr);
+	/* If directory is already open, rewind it.  Otherwise, open it. */
+	if (d = dd)
+		rewinddir(d);
+	else {
+		if (chdir(TFTP_DIR) == -1) {
+			err(FATAL, "chdir: %s", strerror(errno));
+			/* NOTREACHED */
+		}
+		d = opendir(".");
+		if (d == 0) {
+			err(FATAL, "opendir: %s", strerror(errno));
+			/* NOTREACHED */
+		}
+		dd = d;
+	}
+	while (dent = readdir(d))
+		if (strncmp(dent->d_name, ipname, 8) == 0)
+			return 1;
+	return 0;
+}
+/*
+ * Given a list of IP addresses, 'alist', return the first address that
+ * is on network 'net'; 'netmask' is a mask indicating the network portion
+ * of the address.
+ */
+u_long
+choose_ipaddr(alist, net, netmask)
+	u_long **alist;
+	u_long  net;
+	u_long  netmask;
+{
+	for (; *alist; ++alist) {
+		if ((**alist & netmask) == net)
+			return **alist;
+	}
+	return 0;
+}
+/*
+ * Answer the RARP request in 'pkt', on the interface 'ii'.  'pkt' has
+ * already been checked for validity.  The reply is overlaid on the request.
+ */
+void
+rarp_process(ii, pkt)
+	struct if_info *ii;
+	u_char *pkt;
+{
+	struct ether_header *ep;
+	struct hostent *hp;
+	u_long  target_ipaddr;
+	char    ename[256];
+	struct	in_addr in;
+
+	ep = (struct ether_header *) pkt;
+
+	if (ether_ntohost(ename, &ep->ether_shost) != 0 ||
+	    (hp = gethostbyname(ename)) == 0)
+		return;
+
+	/* Choose correct address from list. */
+	if (hp->h_addrtype != AF_INET) {
+		err(FATAL, "cannot handle non IP addresses");
+		/* NOTREACHED */
+	}
+	target_ipaddr = choose_ipaddr((u_long **) hp->h_addr_list,
+	    ii->ii_ipaddr & ii->ii_netmask, ii->ii_netmask);
+
+	if (target_ipaddr == 0) {
+		in.s_addr = ii->ii_ipaddr & ii->ii_netmask;
+		err(NONFATAL, "cannot find %s on net %s\n",
+		    ename, inet_ntoa(in));
+		return;
+	}
+	if (rarp_bootable(htonl(target_ipaddr)))
+		rarp_reply(ii, ep, target_ipaddr);
+}
+/*
+ * Lookup the ethernet address of the interface attached to the BPF
+ * file descriptor 'fd'; return it in 'eaddr'.
+ */
+void
+lookup_eaddr(ifname, eaddr)
+	char *ifname;
+	u_char *eaddr;
+{
+	char inbuf[8192];
+	struct ifconf ifc;
+	struct ifreq *ifr;
+	struct sockaddr_dl *sdl;
+	int fd;
+	int i, len;
+
+	/* We cannot use SIOCGIFADDR on the BPF descriptor.
+	   We must instead get all the interfaces with SIOCGIFCONF
+	   and find the right one.  */
+
+	/* Use datagram socket to get Ethernet address. */
+	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+		err(FATAL, "socket: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+
+	ifc.ifc_len = sizeof(inbuf);
+	ifc.ifc_buf = inbuf;
+	if (ioctl(fd, SIOCGIFCONF, (caddr_t)&ifc) < 0 ||
+	    ifc.ifc_len < sizeof(struct ifreq)) {
+		err(FATAL, "lookup_eaddr: SIOGIFCONF: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	ifr = ifc.ifc_req;
+	for (i = 0; i < ifc.ifc_len;
+	     i += len, ifr = (struct ifreq *)((caddr_t)ifr + len)) {
+		len = sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
+		sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
+		if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER ||
+		    sdl->sdl_alen != 6)
+			continue;
+		if (!strncmp(ifr->ifr_name, ifname, sizeof(ifr->ifr_name))) {
+			bcopy((caddr_t)LLADDR(sdl), (caddr_t)eaddr, 6);
+			if (dflag)
+				fprintf(stderr, "%s: %x:%x:%x:%x:%x:%x\n",
+				    ifr->ifr_name, eaddr[0], eaddr[1],
+				    eaddr[2], eaddr[3], eaddr[4], eaddr[5]);
+			return;
+		}
+	}
+
+	err(FATAL, "lookup_eaddr: Never saw interface `%s'!", ifname);
+}
+/*
+ * Lookup the IP address and network mask of the interface named 'ifname'.
+ */
+void
+lookup_ipaddr(ifname, addrp, netmaskp)
+	char   *ifname;
+	u_long *addrp;
+	u_long *netmaskp;
+{
+	int     fd;
+	struct ifreq ifr;
+
+	/* Use datagram socket to get IP address. */
+	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+		err(FATAL, "socket: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	(void) strncpy(ifr.ifr_name, ifname, sizeof ifr.ifr_name);
+	if (ioctl(fd, SIOCGIFADDR, (char *) &ifr) < 0) {
+		err(FATAL, "SIOCGIFADDR: %s", strerror(errno));
+		/* NOTREACHED */
+	}
+	*addrp = ((struct sockaddr_in *) & ifr.ifr_addr)->sin_addr.s_addr;
+	if (ioctl(fd, SIOCGIFNETMASK, (char *) &ifr) < 0) {
+		perror("SIOCGIFNETMASK");
+		exit(1);
+	}
+	*netmaskp = ((struct sockaddr_in *) & ifr.ifr_addr)->sin_addr.s_addr;
+	/* If SIOCGIFNETMASK didn't work, figure out a mask from the IP
+	 * address class. */
+	if (*netmaskp == 0)
+		*netmaskp = ipaddrtonetmask(*addrp);
+
+	(void) close(fd);
+}
+/*
+ * Poke the kernel arp tables with the ethernet/ip address combinataion
+ * given.  When processing a reply, we must do this so that the booting
+ * host (i.e. the guy running rarpd), won't try to ARP for the hardware
+ * address of the guy being booted (he cannot answer the ARP).
+ */
+void
+update_arptab(ep, ipaddr)
+	u_char *ep;
+	u_long  ipaddr;
+{
+	int     s;
+	struct arpreq request;
+	struct sockaddr_in *sin;
+
+	request.arp_flags = 0;
+	sin = (struct sockaddr_in *) & request.arp_pa;
+	sin->sin_family = AF_INET;
+	sin->sin_addr.s_addr = ipaddr;
+	request.arp_ha.sa_family = AF_UNSPEC;
+	/* This is needed #if defined(COMPAT_43) && BYTE_ORDER != BIG_ENDIAN,
+	   because AF_UNSPEC is zero and the kernel assumes that a zero
+	   sa_family means that the real sa_family value is in sa_len.  */
+	request.arp_ha.sa_len = 16; /* XXX */
+	bcopy((char *) ep, (char *) request.arp_ha.sa_data, 6);
+
+#if 0
+	s = socket(AF_INET, SOCK_DGRAM, 0);
+	if (ioctl(s, SIOCSARP, (caddr_t) & request) < 0) {
+		err(NONFATAL, "SIOCSARP: %s", strerror(errno));
+	}
+	(void) close(s);
+#endif
+}
+/*
+ * Build a reverse ARP packet and sent it out on the interface.
+ * 'ep' points to a valid ARPOP_REVREQUEST.  The ARPOP_REVREPLY is built
+ * on top of the request, then written to the network.
+ *
+ * RFC 903 defines the ether_arp fields as follows.  The following comments
+ * are taken (more or less) straight from this document.
+ *
+ * ARPOP_REVREQUEST
+ *
+ * arp_sha is the hardware address of the sender of the packet.
+ * arp_spa is undefined.
+ * arp_tha is the 'target' hardware address.
+ *   In the case where the sender wishes to determine his own
+ *   protocol address, this, like arp_sha, will be the hardware
+ *   address of the sender.
+ * arp_tpa is undefined.
+ *
+ * ARPOP_REVREPLY
+ *
+ * arp_sha is the hardware address of the responder (the sender of the
+ *   reply packet).
+ * arp_spa is the protocol address of the responder (see the note below).
+ * arp_tha is the hardware address of the target, and should be the same as
+ *   that which was given in the request.
+ * arp_tpa is the protocol address of the target, that is, the desired address.
+ *
+ * Note that the requirement that arp_spa be filled in with the responder's
+ * protocol is purely for convenience.  For instance, if a system were to use
+ * both ARP and RARP, then the inclusion of the valid protocol-hardware
+ * address pair (arp_spa, arp_sha) may eliminate the need for a subsequent
+ * ARP request.
+ */
+void
+rarp_reply(ii, ep, ipaddr)
+	struct if_info *ii;
+	struct ether_header *ep;
+	u_long  ipaddr;
+{
+	int     n;
+	struct ether_arp *ap = (struct ether_arp *) (ep + 1);
+	int     len;
+
+	update_arptab((u_char *) & ap->arp_sha, ipaddr);
+
+	/* Build the rarp reply by modifying the rarp request in place. */
+	ep->ether_type = htons(ETHERTYPE_REVARP);
+	ap->ea_hdr.ar_hrd = htons(ARPHRD_ETHER);
+	ap->ea_hdr.ar_pro = htons(ETHERTYPE_IP);
+	ap->arp_op = htons(ARPOP_REVREPLY);
+
+	bcopy((char *) &ap->arp_sha, (char *) &ep->ether_dhost, 6);
+	bcopy((char *) ii->ii_eaddr, (char *) &ep->ether_shost, 6);
+	bcopy((char *) ii->ii_eaddr, (char *) &ap->arp_sha, 6);
+
+	bcopy((char *) &ipaddr, (char *) ap->arp_tpa, 4);
+	/* Target hardware is unchanged. */
+	bcopy((char *) &ii->ii_ipaddr, (char *) ap->arp_spa, 4);
+
+	len = sizeof(*ep) + sizeof(*ap);
+	n = write(ii->ii_fd, (char *) ep, len);
+	if (n != len) {
+		err(NONFATAL, "write: only %d of %d bytes written", n, len);
+	}
+}
+/*
+ * Get the netmask of an IP address.  This routine is used if
+ * SIOCGIFNETMASK doesn't work.
+ */
+u_long
+ipaddrtonetmask(addr)
+	u_long  addr;
+{
+	if (IN_CLASSA(addr))
+		return IN_CLASSA_NET;
+	if (IN_CLASSB(addr))
+		return IN_CLASSB_NET;
+	if (IN_CLASSC(addr))
+		return IN_CLASSC_NET;
+	err(FATAL, "unknown IP address class: %08X", addr);
+	/* NOTREACHED */
+}
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+err(int fatal, const char *fmt,...)
+#else
+err(fmt, va_alist)
+	int     fatal;
+	char   *fmt;
+va_dcl
+#endif
+{
+	va_list ap;
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	if (dflag) {
+		if (fatal)
+			(void) fprintf(stderr, "rarpd: error: ");
+		else
+			(void) fprintf(stderr, "rarpd: warning: ");
+		(void) vfprintf(stderr, fmt, ap);
+		(void) fprintf(stderr, "\n");
+	}
+	vsyslog(LOG_ERR, fmt, ap);
+	va_end(ap);
+	if (fatal)
+		exit(1);
+	/* NOTREACHED */
+}
+
+void
+#if __STDC__
+debug(const char *fmt,...)
+#else
+debug(fmt, va_alist)
+	char   *fmt;
+va_dcl
+#endif
+{
+	va_list ap;
+
+	if (dflag) {
+#if __STDC__
+		va_start(ap, fmt);
+#else
+		va_start(ap);
+#endif
+		(void) fprintf(stderr, "rarpd: ");
+		(void) vfprintf(stderr, fmt, ap);
+		va_end(ap);
+		(void) fprintf(stderr, "\n");
+	}
+}
diff --git a/rbootd.tproj/Makefile b/rbootd.tproj/Makefile
new file mode 100644
index 0000000..6a4e127
--- /dev/null
+++ b/rbootd.tproj/Makefile
@@ -0,0 +1,50 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rbootd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = defs.h pathnames.h rmp.h rmp_var.h
+
+CFILES = bpf.c conf.c parseconf.c rbootd.c rmpproto.c utils.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble rbootd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rbootd.tproj/Makefile.postamble b/rbootd.tproj/Makefile.postamble
new file mode 100644
index 0000000..7ede358
--- /dev/null
+++ b/rbootd.tproj/Makefile.postamble
@@ -0,0 +1,111 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
diff --git a/rbootd.tproj/Makefile.preamble b/rbootd.tproj/Makefile.preamble
new file mode 100644
index 0000000..dcbd1c8
--- /dev/null
+++ b/rbootd.tproj/Makefile.preamble
@@ -0,0 +1,119 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS = 
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR = 
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+-include ../Makefile.include
diff --git a/rbootd.tproj/PB.project b/rbootd.tproj/PB.project
new file mode 100644
index 0000000..4423a10
--- /dev/null
+++ b/rbootd.tproj/PB.project
@@ -0,0 +1,39 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (defs.h, pathnames.h, rmp.h, rmp_var.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (bpf.c, conf.c, parseconf.c, rbootd.c, rmpproto.c, utils.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, rbootd.8); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_DOCUMENTEXTENSIONS = (); 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rbootd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rbootd.tproj/bpf.c b/rbootd.tproj/bpf.c
new file mode 100644
index 0000000..ed21480
--- /dev/null
+++ b/rbootd.tproj/bpf.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)bpf.c	8.1 (Berkeley) 6/4/93
+ *
+ * Utah $Hdr: bpf.c 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)bpf.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/bpf.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include "defs.h"
+#include "pathnames.h"
+
+static int BpfFd = -1;
+static unsigned BpfLen = 0;
+static u_char *BpfPkt = NULL;
+
+/*
+**  BpfOpen -- Open and initialize a BPF device.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		File descriptor of opened BPF device (for select() etc).
+**
+**	Side Effects:
+**		If an error is encountered, the program terminates here.
+*/
+int
+BpfOpen()
+{
+	struct ifreq ifr;
+	char bpfdev[32];
+	int n = 0;
+
+	/*
+	 *  Open the first available BPF device.
+	 */
+	do {
+		(void) sprintf(bpfdev, _PATH_BPF, n++);
+		BpfFd = open(bpfdev, O_RDWR);
+	} while (BpfFd < 0 && (errno == EBUSY || errno == EPERM));
+
+	if (BpfFd < 0) {
+		syslog(LOG_ERR, "bpf: no available devices: %m");
+		Exit(0);
+	}
+
+	/*
+	 *  Set interface name for bpf device, get data link layer
+	 *  type and make sure it's type Ethernet.
+	 */
+	(void) strncpy(ifr.ifr_name, IntfName, sizeof(ifr.ifr_name));
+	if (ioctl(BpfFd, BIOCSETIF, (caddr_t)&ifr) < 0) {
+		syslog(LOG_ERR, "bpf: ioctl(BIOCSETIF,%s): %m", IntfName);
+		Exit(0);
+	}
+
+	/*
+	 *  Make sure we are dealing with an Ethernet device.
+	 */
+	if (ioctl(BpfFd, BIOCGDLT, (caddr_t)&n) < 0) {
+		syslog(LOG_ERR, "bpf: ioctl(BIOCGDLT): %m");
+		Exit(0);
+	}
+	if (n != DLT_EN10MB) {
+		syslog(LOG_ERR,"bpf: %s: data-link type %d unsupported",
+		       IntfName, n);
+		Exit(0);
+	}
+
+	/*
+	 *  On read(), return packets immediately (do not buffer them).
+	 */
+	n = 1;
+	if (ioctl(BpfFd, BIOCIMMEDIATE, (caddr_t)&n) < 0) {
+		syslog(LOG_ERR, "bpf: ioctl(BIOCIMMEDIATE): %m");
+		Exit(0);
+	}
+
+	/*
+	 *  Try to enable the chip/driver's multicast address filter to
+	 *  grab our RMP address.  If this fails, try promiscuous mode.
+	 *  If this fails, there's no way we are going to get any RMP
+	 *  packets so just exit here.
+	 */
+#ifdef MSG_EOR
+	ifr.ifr_addr.sa_len = RMP_ADDRLEN + 2;
+#endif
+	ifr.ifr_addr.sa_family = AF_UNSPEC;
+	bcopy(&RmpMcastAddr[0], (char *)&ifr.ifr_addr.sa_data[0], RMP_ADDRLEN);
+	if (ioctl(BpfFd, SIOCADDMULTI, (caddr_t)&ifr) < 0) {
+		syslog(LOG_WARNING,
+		    "bpf: can't add mcast addr (%m), setting promiscuous mode");
+
+		if (ioctl(BpfFd, BIOCPROMISC, (caddr_t)0) < 0) {
+			syslog(LOG_ERR, "bpf: can't set promiscuous mode: %m");
+			Exit(0);
+		}
+	}
+
+	/*
+	 *  Ask BPF how much buffer space it requires and allocate one.
+	 */
+	if (ioctl(BpfFd, BIOCGBLEN, (caddr_t)&BpfLen) < 0) {
+		syslog(LOG_ERR, "bpf: ioctl(BIOCGBLEN): %m");
+		Exit(0);
+	}
+	if (BpfPkt == NULL)
+		BpfPkt = (u_char *)malloc(BpfLen);
+
+	if (BpfPkt == NULL) {
+		syslog(LOG_ERR, "bpf: out of memory (%u bytes for bpfpkt)",
+		       BpfLen);
+		Exit(0);
+	}
+
+	/*
+	 *  Write a little program to snarf RMP Boot packets and stuff
+	 *  it down BPF's throat (i.e. set up the packet filter).
+	 */
+	{
+#define	RMP	((struct rmp_packet *)0)
+		static struct bpf_insn bpf_insn[] = {
+		    { BPF_LD|BPF_B|BPF_ABS,  0, 0, (long)&RMP->hp_llc.dsap },
+		    { BPF_JMP|BPF_JEQ|BPF_K, 0, 5, IEEE_DSAP_HP },
+		    { BPF_LD|BPF_H|BPF_ABS,  0, 0, (long)&RMP->hp_llc.cntrl },
+		    { BPF_JMP|BPF_JEQ|BPF_K, 0, 3, IEEE_CNTL_HP },
+		    { BPF_LD|BPF_H|BPF_ABS,  0, 0, (long)&RMP->hp_llc.dxsap },
+		    { BPF_JMP|BPF_JEQ|BPF_K, 0, 1, HPEXT_DXSAP },
+		    { BPF_RET|BPF_K,         0, 0, RMP_MAX_PACKET },
+		    { BPF_RET|BPF_K,         0, 0, 0x0 }
+		};
+#undef	RMP
+		static struct bpf_program bpf_pgm = {
+		    sizeof(bpf_insn)/sizeof(bpf_insn[0]), bpf_insn
+		};
+
+		if (ioctl(BpfFd, BIOCSETF, (caddr_t)&bpf_pgm) < 0) {
+			syslog(LOG_ERR, "bpf: ioctl(BIOCSETF): %m");
+			Exit(0);
+		}
+	}
+
+	return(BpfFd);
+}
+
+/*
+**  BPF GetIntfName -- Return the name of a network interface attached to
+**		the system, or 0 if none can be found.  The interface
+**		must be configured up; the lowest unit number is
+**		preferred; loopback is ignored.
+**
+**	Parameters:
+**		errmsg - if no network interface found, *errmsg explains why.
+**
+**	Returns:
+**		A (static) pointer to interface name, or NULL on error.
+**
+**	Side Effects:
+**		None.
+*/
+char *
+BpfGetIntfName(errmsg)
+	char **errmsg;
+{
+	struct ifreq ibuf[8], *ifrp, *ifend, *mp;
+	struct ifconf ifc;
+	int fd;
+	int minunit, n;
+	char *cp;
+	static char device[sizeof(ifrp->ifr_name)];
+	static char errbuf[128] = "No Error!";
+
+	if (errmsg != NULL)
+		*errmsg = errbuf;
+
+	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+		(void) strcpy(errbuf, "bpf: socket: %m");
+		return(NULL);
+	}
+	ifc.ifc_len = sizeof ibuf;
+	ifc.ifc_buf = (caddr_t)ibuf;
+
+#ifdef OSIOCGIFCONF
+	if (ioctl(fd, OSIOCGIFCONF, (char *)&ifc) < 0 ||
+	    ifc.ifc_len < sizeof(struct ifreq)) {
+		(void) strcpy(errbuf, "bpf: ioctl(OSIOCGIFCONF): %m");
+		return(NULL);
+	}
+#else
+	if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
+	    ifc.ifc_len < sizeof(struct ifreq)) {
+		(void) strcpy(errbuf, "bpf: ioctl(SIOCGIFCONF): %m");
+		return(NULL);
+	}
+#endif
+	ifrp = ibuf;
+	ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
+	
+	mp = 0;
+	minunit = 666;
+	for (; ifrp < ifend; ++ifrp) {
+		if (ioctl(fd, SIOCGIFFLAGS, (char *)ifrp) < 0) {
+			(void) strcpy(errbuf, "bpf: ioctl(SIOCGIFFLAGS): %m");
+			return(NULL);
+		}
+
+		/*
+		 *  If interface is down or this is the loopback interface,
+		 *  ignore it.
+		 */
+		if ((ifrp->ifr_flags & IFF_UP) == 0 ||
+#ifdef IFF_LOOPBACK
+		    (ifrp->ifr_flags & IFF_LOOPBACK))
+#else
+		    (strcmp(ifrp->ifr_name, "lo0") == 0))
+#endif
+			continue;
+
+		for (cp = ifrp->ifr_name; !isdigit(*cp); ++cp)
+			;
+		n = atoi(cp);
+		if (n < minunit) {
+			minunit = n;
+			mp = ifrp;
+		}
+	}
+
+	(void) close(fd);
+	if (mp == 0) {
+		(void) strcpy(errbuf, "bpf: no interfaces found");
+		return(NULL);
+	}
+
+	(void) strcpy(device, mp->ifr_name);
+	return(device);
+}
+
+/*
+**  BpfRead -- Read packets from a BPF device and fill in `rconn'.
+**
+**	Parameters:
+**		rconn - filled in with next packet.
+**		doread - is True if we can issue a read() syscall.
+**
+**	Returns:
+**		True if `rconn' contains a new packet, False otherwise.
+**
+**	Side Effects:
+**		None.
+*/
+int
+BpfRead(rconn, doread)
+	RMPCONN *rconn;
+	int doread;
+{
+	register int datlen, caplen, hdrlen;
+	static u_char *bp = NULL, *ep = NULL;
+	int cc;
+
+	/*
+	 *  The read() may block, or it may return one or more packets.
+	 *  We let the caller decide whether or not we can issue a read().
+	 */
+	if (doread) {
+		if ((cc = read(BpfFd, (char *)BpfPkt, (int)BpfLen)) < 0) {
+			syslog(LOG_ERR, "bpf: read: %m");
+			return(0);
+		} else {
+			bp = BpfPkt;
+			ep = BpfPkt + cc;
+		}
+	}
+
+#define bhp ((struct bpf_hdr *)bp)
+	/*
+	 *  If there is a new packet in the buffer, stuff it into `rconn'
+	 *  and return a success indication.
+	 */
+	if (bp < ep) {
+		datlen = bhp->bh_datalen;
+		caplen = bhp->bh_caplen;
+		hdrlen = bhp->bh_hdrlen;
+
+		if (caplen != datlen)
+			syslog(LOG_ERR,
+			       "bpf: short packet dropped (%d of %d bytes)",
+			       caplen, datlen);
+		else if (caplen > sizeof(struct rmp_packet))
+			syslog(LOG_ERR, "bpf: large packet dropped (%d bytes)",
+			       caplen);
+		else {
+			rconn->rmplen = caplen;
+			bcopy((char *)&bhp->bh_tstamp, (char *)&rconn->tstamp,
+			      sizeof(struct timeval));
+			bcopy((char *)bp + hdrlen, (char *)&rconn->rmp, caplen);
+		}
+		bp += BPF_WORDALIGN(caplen + hdrlen);
+		return(1);
+	}
+#undef bhp
+
+	return(0);
+}
+
+/*
+**  BpfWrite -- Write packet to BPF device.
+**
+**	Parameters:
+**		rconn - packet to send.
+**
+**	Returns:
+**		True if write succeeded, False otherwise.
+**
+**	Side Effects:
+**		None.
+*/
+int
+BpfWrite(rconn)
+	RMPCONN *rconn;
+{
+	if (write(BpfFd, (char *)&rconn->rmp, rconn->rmplen) < 0) {
+		syslog(LOG_ERR, "write: %s: %m", EnetStr(rconn));
+		return(0);
+	}
+
+	return(1);
+}
+
+/*
+**  BpfClose -- Close a BPF device.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		None.
+*/
+void
+BpfClose()
+{
+	struct ifreq ifr;
+
+	if (BpfPkt != NULL) {
+		free((char *)BpfPkt);
+		BpfPkt = NULL;
+	}
+
+	if (BpfFd == -1)
+		return;
+
+#ifdef MSG_EOR
+	ifr.ifr_addr.sa_len = RMP_ADDRLEN + 2;
+#endif
+	ifr.ifr_addr.sa_family = AF_UNSPEC;
+	bcopy(&RmpMcastAddr[0], (char *)&ifr.ifr_addr.sa_data[0], RMP_ADDRLEN);
+	if (ioctl(BpfFd, SIOCDELMULTI, (caddr_t)&ifr) < 0)
+		(void) ioctl(BpfFd, BIOCPROMISC, (caddr_t)0);
+
+	(void) close(BpfFd);
+	BpfFd = -1;
+}
diff --git a/rbootd.tproj/conf.c b/rbootd.tproj/conf.c
new file mode 100644
index 0000000..e61a0f3
--- /dev/null
+++ b/rbootd.tproj/conf.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)conf.c	8.1 (Berkeley) 6/4/93
+ *
+ * Utah $Hdr: conf.c 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)conf.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+#include "defs.h"
+#include "pathnames.h"
+
+/*
+**  Define (and possibly initialize) global variables here.
+**
+**  Caveat:
+**	The maximum number of bootable files (`char *BootFiles[]') is
+**	limited to C_MAXFILE (i.e. the maximum number of files that
+**	can be spec'd in the configuration file).  This was done to
+**	simplify the boot file search code.
+*/
+
+char	*ProgName;				/* path-stripped argv[0] */
+char	MyHost[MAXHOSTNAMELEN+1];		/* host name */
+int	MyPid;					/* process id */
+int	DebugFlg = 0;				/* set true if debugging */
+int	BootAny = 0;				/* set true if we boot anyone */
+
+char	*ConfigFile = NULL;			/* configuration file */
+char	*DfltConfig = _PATH_RBOOTDCONF;		/* default configuration file */
+char	*PidFile = _PATH_RBOOTDPID;		/* file w/pid of server */
+char	*BootDir = _PATH_RBOOTDLIB;		/* directory w/boot files */
+char	*DbgFile = _PATH_RBOOTDDBG;		/* debug output file */
+
+FILE	*DbgFp = NULL;				/* debug file pointer */
+char	*IntfName = NULL;			/* intf we are attached to */
+
+u_short	SessionID = 0;				/* generated session ID */
+
+char	*BootFiles[C_MAXFILE];			/* list of boot files */
+
+CLIENT	*Clients = NULL;			/* list of addrs we'll accept */
+RMPCONN	*RmpConns = NULL;			/* list of active connections */
+
+char	RmpMcastAddr[RMP_ADDRLEN] = RMP_ADDR;	/* RMP multicast address */
diff --git a/rbootd.tproj/defs.h b/rbootd.tproj/defs.h
new file mode 100644
index 0000000..976ffc1
--- /dev/null
+++ b/rbootd.tproj/defs.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/4/93
+ *
+ * Utah $Hdr: defs.h 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+#include "rmp.h"
+#include "rmp_var.h"
+
+/*
+**  Common #define's and external variables.  All other files should
+**  include this.
+*/
+
+/*
+ *  This may be defined in <sys/param.h>, if not, it's defined here.
+ */
+#ifndef	MAXHOSTNAMELEN
+#define	MAXHOSTNAMELEN 64
+#endif
+
+/*
+ *  SIGUSR1 and SIGUSR2 are defined in <signal.h> for 4.3BSD systems.
+ */
+#ifndef SIGUSR1
+#define	SIGUSR1 SIGEMT
+#endif
+#ifndef SIGUSR2
+#define	SIGUSR2 SIGFPE
+#endif
+
+/*
+ *  These can be faster & more efficient than strcmp()/strncmp()...
+ */
+#define	STREQN(s1,s2)		((*s1 == *s2) && (strcmp(s1,s2) == 0))
+#define	STRNEQN(s1,s2,n)	((*s1 == *s2) && (strncmp(s1,s2,n) == 0))
+
+/*
+ *  Configuration file limitations.
+ */
+#define	C_MAXFILE	10		/* max number of boot-able files */
+#define	C_LINELEN	1024		/* max length of line */
+
+/*
+ *  Direction of packet (used as argument to DispPkt).
+ */
+#define	DIR_RCVD	0
+#define	DIR_SENT	1
+#define	DIR_NONE	2
+
+/*
+ *  These need not be functions, so...
+ */
+#define	FreeStr(str)	free(str)
+#define	FreeClient(cli)	free(cli)
+#define	GenSessID()	(++SessionID ? SessionID: ++SessionID)
+
+/*
+ *  Converting an Ethernet address to a string is done in many routines.
+ *  Using `rmp.hp_hdr.saddr' works because this field is *never* changed;
+ *  it will *always* contain the source address of the packet.
+ */
+#define	EnetStr(rptr)	GetEtherAddr(&(rptr)->rmp.hp_hdr.saddr[0])
+
+/*
+ *  Every machine we can boot will have one of these allocated for it
+ *  (unless there are no restrictions on who we can boot).
+ */
+typedef struct client_s {
+	u_char			addr[RMP_ADDRLEN];	/* addr of machine */
+	char			*files[C_MAXFILE];	/* boot-able files */
+	struct client_s		*next;			/* ptr to next */
+} CLIENT;
+
+/*
+ *  Every active connection has one of these allocated for it.
+ */
+typedef struct rmpconn_s {
+	struct rmp_packet	rmp;			/* RMP packet */
+	int			rmplen;			/* length of packet */
+	struct timeval		tstamp;			/* last time active */
+	int			bootfd;			/* open boot file */
+	struct rmpconn_s	*next;			/* ptr to next */
+} RMPCONN;
+
+/*
+ *  All these variables are defined in "conf.c".
+ */
+extern	char	*ProgName;		/* path-stripped argv[0] */
+extern	char	MyHost[];		/* this hosts' name */
+extern	int	MyPid;			/* this processes' ID */
+extern	int	DebugFlg;		/* set true if debugging */
+extern	int	BootAny;		/* set true if we can boot anyone */
+
+extern	char	*ConfigFile;		/* configuration file */
+extern	char	*DfltConfig;		/* default configuration file */
+extern	char	*DbgFile;		/* debug output file */
+extern	char	*PidFile;		/* file containing pid of server */
+extern	char	*BootDir;		/* directory w/boot files */
+
+extern	FILE	*DbgFp;			/* debug file pointer */
+extern	char	*IntfName;		/* interface we are attached to */
+
+extern	u_short	SessionID;		/* generated session ID */
+
+extern	char	*BootFiles[];		/* list of boot files */
+
+extern	CLIENT	*Clients;		/* list of addrs we'll accept */
+extern	RMPCONN	*RmpConns;		/* list of active connections */
+
+extern	char	RmpMcastAddr[];		/* RMP multicast address */
+
+void	 AddConn __P((RMPCONN *));
+int	 BootDone __P((RMPCONN *));
+void	 BpfClose __P((void));
+char	*BpfGetIntfName __P((char **));
+int	 BpfOpen __P((void));
+int	 BpfRead __P((RMPCONN *, int));
+int	 BpfWrite __P((RMPCONN *));
+void	 DebugOff __P((int));
+void	 DebugOn __P((int));
+void	 DispPkt __P((RMPCONN *, int));
+void	 DoTimeout __P((void));
+void	 DspFlnm __P((u_int, char *));
+void	 Exit __P((int));
+CLIENT	*FindClient __P((RMPCONN *));
+RMPCONN	*FindConn __P((RMPCONN *));
+void	 FreeClients __P((void));
+void	 FreeConn __P((RMPCONN *));
+void	 FreeConns __P((void));
+int	 GetBootFiles __P((void));
+char	*GetEtherAddr __P((u_char *));
+CLIENT	*NewClient __P((u_char *));
+RMPCONN	*NewConn __P((RMPCONN *));
+char	*NewStr __P((char *));
+u_char	*ParseAddr __P((char *));
+int	 ParseConfig __P((void));
+void	 ProcessPacket __P((RMPCONN *, CLIENT *));
+void	 ReConfig __P((int));
+void	 RemoveConn __P((RMPCONN *));
+int	 SendBootRepl __P((struct rmp_packet *, RMPCONN *, char *[]));
+int	 SendFileNo __P((struct rmp_packet *, RMPCONN *, char *[]));
+int	 SendPacket __P((RMPCONN *));
+int	 SendReadRepl __P((RMPCONN *));
+int	 SendServerID __P((RMPCONN *));
diff --git a/rbootd.tproj/parseconf.c b/rbootd.tproj/parseconf.c
new file mode 100644
index 0000000..ddf2f19
--- /dev/null
+++ b/rbootd.tproj/parseconf.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)parseconf.c	8.1 (Berkeley) 6/4/93
+ *
+ * Utah $Hdr: parseconf.c 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)parseconf.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include "defs.h"
+
+/*
+**  ParseConfig -- parse the config file into linked list of clients.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		1 on success, 0 otherwise.
+**
+**	Side Effects:
+**		- Linked list of clients will be (re)allocated.
+**
+**	Warnings:
+**		- GetBootFiles() must be called before this routine
+**		  to create a linked list of default boot files.
+*/
+int
+ParseConfig()
+{
+	FILE *fp;
+	CLIENT *client;
+	u_char *addr;
+	char line[C_LINELEN];
+	register char *cp, *bcp;
+	register int i, j;
+	int omask, linecnt = 0;
+
+	if (BootAny)				/* ignore config file */
+		return(1);
+
+	FreeClients();				/* delete old list of clients */
+
+	if ((fp = fopen(ConfigFile, "r")) == NULL) {
+		syslog(LOG_ERR, "ParseConfig: can't open config file (%s)",
+		       ConfigFile);
+		return(0);
+	}
+
+	/*
+	 *  We've got to block SIGHUP to prevent reconfiguration while
+	 *  dealing with the linked list of Clients.  This can be done
+	 *  when actually linking the new client into the list, but
+	 *  this could have unexpected results if the server was HUP'd
+	 *  whilst reconfiguring.  Hence, it is done here.
+	 */
+	omask = sigblock(sigmask(SIGHUP));
+
+	/*
+	 *  GETSTR positions `bcp' at the start of the current token,
+	 *  and null terminates it.  `cp' is positioned at the start
+	 *  of the next token.  spaces & commas are separators.
+	 */
+#define GETSTR	while (isspace(*cp) || *cp == ',') cp++;	\
+		bcp = cp;					\
+		while (*cp && *cp!=',' && !isspace(*cp)) cp++;	\
+		if (*cp) *cp++ = '\0'
+
+	/*
+	 *  For each line, parse it into a new CLIENT struct.
+	 */
+	while (fgets(line, C_LINELEN, fp) != NULL) {
+		linecnt++;				/* line counter */
+
+		if (*line == '\0' || *line == '#')	/* ignore comment */
+			continue;
+
+		if ((cp = index(line,'#')) != NULL)	/* trash comments */
+			*cp = '\0';
+
+		cp = line;				/* init `cp' */
+		GETSTR;					/* get RMP addr */
+		if (bcp == cp)				/* all delimiters */
+			continue;
+
+		/*
+		 *  Get an RMP address from a string.  Abort on failure.
+		 */
+		if ((addr = ParseAddr(bcp)) == NULL) {
+			syslog(LOG_ERR,
+			       "ParseConfig: line %d: cant parse <%s>",
+			       linecnt, bcp);
+			continue;
+		}
+
+		if ((client = NewClient(addr)) == NULL)	/* alloc new client */
+			continue;
+
+		GETSTR;					/* get first file */
+
+		/*
+		 *  If no boot files are spec'd, use the default list.
+		 *  Otherwise, validate each file (`bcp') against the
+		 *  list of boot-able files.
+		 */
+		i = 0;
+		if (bcp == cp)				/* no files spec'd */
+			for (; i < C_MAXFILE && BootFiles[i] != NULL; i++)
+				client->files[i] = BootFiles[i];
+		else {
+			do {
+				/*
+				 *  For each boot file spec'd, make sure it's
+				 *  in our list.  If so, include a pointer to
+				 *  it in the CLIENT's list of boot files.
+				 */
+				for (j = 0; ; j++) {
+					if (j==C_MAXFILE||BootFiles[j]==NULL) {
+						syslog(LOG_ERR, "ParseConfig: line %d: no boot file (%s)",
+						       linecnt, bcp);
+						break;
+					}
+					if (STREQN(BootFiles[j], bcp)) {
+						if (i < C_MAXFILE)
+							client->files[i++] =
+							    BootFiles[j];
+						else
+							syslog(LOG_ERR, "ParseConfig: line %d: too many boot files (%s)",
+							       linecnt, bcp);
+						break;
+					}
+				}
+				GETSTR;			/* get next file */
+			} while (bcp != cp);
+
+			/*
+			 *  Restricted list of boot files were spec'd,
+			 *  however, none of them were found.  Since we
+			 *  apparently cant let them boot "just anything",
+			 *  the entire record is invalidated.
+			 */
+			if (i == 0) {
+				FreeClient(client);	
+				continue;
+			}
+		}
+
+		/*
+		 *  Link this client into the linked list of clients.
+		 *  SIGHUP has already been blocked.
+		 */
+		if (Clients)
+			client->next = Clients;
+		Clients = client;
+	}
+
+	(void) fclose(fp);				/* close config file */
+
+	(void) sigsetmask(omask);			/* reset signal mask */
+
+	return(1);					/* return success */
+}
+
+/*
+**  ParseAddr -- Parse a string containing an RMP address.
+**
+**	This routine is fairly liberal at parsing an RMP address.  The
+**	address must contain 6 octets consisting of between 0 and 2 hex
+**	chars (upper/lower case) separated by colons.  If two colons are
+**	together (e.g. "::", the octet between them is recorded as being
+**	zero.  Hence, the following addrs are all valid and parse to the
+**	same thing:
+**
+**		08:00:09:00:66:ad	8::9:0:66:AD	8::9::66:aD
+**
+**	For clarity, an RMP address is really an Ethernet address, but
+**	since the HP boot code uses IEEE 802.3, it's really an IEEE
+**	802.3 address.  Of course, all of these are identical.
+**
+**	Parameters:
+**		str - string representation of an RMP address.
+**
+**	Returns:
+**		pointer to a static array of RMP_ADDRLEN bytes.
+**
+**	Side Effects:
+**		None.
+**
+**	Warnings:
+**		- The return value points to a static buffer; it must
+**		  be copied if it's to be saved.
+**		- For speed, we assume a u_char consists of 8 bits.
+*/
+u_char *
+ParseAddr(str)
+	char *str;
+{
+	static u_char addr[RMP_ADDRLEN];
+	register char *cp;
+	register unsigned i;
+	register int part, subpart;
+
+	bzero((char *)&addr[0], RMP_ADDRLEN);	/* zero static buffer */
+
+	part = subpart = 0;
+	for (cp = str; *cp; cp++) {
+		/*
+		 *  A colon (`:') must be used to delimit each octet.
+		 */
+		if (*cp == ':') {
+			if (++part == RMP_ADDRLEN)	/* too many parts */
+				return(NULL);
+			subpart = 0;
+			continue;
+		}
+
+		/*
+		 *  Convert hex character to an integer.
+		 */
+		if (isdigit(*cp))
+			i = *cp - '0';
+		else {
+			i = (isupper(*cp)? tolower(*cp): *cp) - 'a' + 10;
+			if (i < 10 || i > 15)		/* not a hex char */
+				return(NULL);
+		}
+
+		if (subpart++) {
+			if (subpart > 2)		/* too many hex chars */
+				return(NULL);
+			addr[part] <<= 4;
+		}
+		addr[part] |= i;
+	}
+
+	if (part != (RMP_ADDRLEN-1))			/* too few parts */
+		return(NULL);
+
+	return(&addr[0]);
+}
+
+/*
+**  GetBootFiles -- record list of files in current (boot) directory.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		Number of boot files on success, 0 on failure.
+**
+**	Side Effects:
+**		Strings in `BootFiles' are freed/allocated.
+**
+**	Warnings:
+**		- After this routine is called, ParseConfig() must be
+**		  called to re-order it's list of boot file pointers.
+*/
+int
+GetBootFiles()
+{
+	DIR *dfd;
+	struct stat statb;
+	register struct dirent *dp;
+	register int i;
+
+	/*
+	 *  Free the current list of boot files.
+	 */
+	for (i = 0; i < C_MAXFILE && BootFiles[i] != NULL; i++) {
+		FreeStr(BootFiles[i]);
+		BootFiles[i] = NULL;
+	}
+
+	/*
+	 *  Open current directory to read boot file names.
+	 */
+	if ((dfd = opendir(".")) == NULL) {	/* open BootDir */
+		syslog(LOG_ERR, "GetBootFiles: can't open directory (%s)\n",
+		       BootDir);
+		return(0);
+	}
+
+	/*
+	 *  Read each boot file name and allocate space for it in the
+	 *  list of boot files (BootFiles).  All boot files read after
+	 *  C_MAXFILE will be ignored.
+	 */
+	i = 0;
+	for (dp = readdir(dfd); dp != NULL; dp = readdir(dfd)) {
+		if (stat(dp->d_name, &statb) < 0 ||
+		    (statb.st_mode & S_IFMT) != S_IFREG)
+			continue;
+		if (i == C_MAXFILE)
+			syslog(LOG_ERR,
+			       "GetBootFiles: too many boot files (%s ignored)",
+			       dp->d_name);
+		else if ((BootFiles[i] = NewStr(dp->d_name)) != NULL)
+			i++;
+	}
+
+	(void) closedir(dfd);			/* close BootDir */
+
+	if (i == 0)				/* cant find any boot files */
+		syslog(LOG_ERR, "GetBootFiles: no boot files (%s)\n", BootDir);
+
+	return(i);
+}
diff --git a/rbootd.tproj/pathnames.h b/rbootd.tproj/pathnames.h
new file mode 100644
index 0000000..15765da
--- /dev/null
+++ b/rbootd.tproj/pathnames.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/4/93
+ *
+ * Utah $Hdr: pathnames.h 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+#define	_PATH_BPF		"/dev/bpf%d"
+#define	_PATH_RBOOTDCONF	"/etc/rbootd.conf"
+#define	_PATH_RBOOTDDBG		"/tmp/rbootd.dbg"
+#define	_PATH_RBOOTDLIB		"/usr/mdec/rbootd"
+#define	_PATH_RBOOTDPID		"/var/run/rbootd.pid"
diff --git a/rbootd.tproj/rbootd.8 b/rbootd.tproj/rbootd.8
new file mode 100644
index 0000000..f4eb364
--- /dev/null
+++ b/rbootd.tproj/rbootd.8
@@ -0,0 +1,156 @@
+.\" Copyright (c) 1988, 1992 The University of Utah and the Center
+.\"	for Software Science (CSS).
+.\" Copyright (c) 1992, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Center for Software Science of the University of Utah Computer
+.\" Science Department.  CSS requests users of this software to return
+.\" to css-dist@cs.utah.edu any improvements that they make and grant
+.\" CSS redistribution rights.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)rbootd.8	8.2 (Berkeley) 12/11/93
+.\"
+.\" Utah $Hdr: rbootd.man 3.1 92/07/06$
+.\" Author: Jeff Forys, University of Utah CSS
+.\"
+.Dd "December 11, 1993"
+.Dt RBOOTD 8
+.Os
+.Sh NAME
+.Nm rbootd
+.Nd HP remote boot server
+.Sh SYNOPSIS
+.Nm rbootd
+.Op Fl ad
+.Op Fl i Ar interface
+.Op config_file
+.Sh DESCRIPTION
+The
+.Nm rbootd
+utility services boot requests from Hewlett-Packard workstations over a
+local area network.
+All boot files must reside in the boot file directory; further, if a
+client supplies path information in its boot request, it will be silently
+stripped away before processing.
+By default,
+.Nm rbootd
+only responds to requests from machines listed in its configuration file.
+.Pp
+The options are as follows:
+.Bl -tag -width Fl
+.It Fl a
+Respond to boot requests from any machine.
+The configuration file is ignored if this option is specified.
+.It Fl d
+Run
+.Nm rbootd
+in debug mode.
+Packets sent and received are displayed to the terminal.
+.It Fl i Ar interface
+Service boot requests on specified interface.
+If unspecified,
+.Nm rbootd
+searches the system interface list for the lowest numbered, configured
+``up'' interface (excluding loopback).
+Ties are broken by choosing the earliest match.
+.El
+.Pp
+Specifying
+.Ar config_file
+on the command line causes
+.Nm rbootd
+to use a different configuration file from the default.
+.Pp
+The configuration file is a text file where each line describes a particular
+machine.
+A line must start with a machine's Ethernet address followed by an optional
+list of boot file names.
+An Ethernet address is specified in hexadecimal with each of its six octets
+separated by a colon.
+The boot file names come from the boot file directory.
+The ethernet address and boot file(s) must be separated by white-space
+and/or comma characters.
+A pound sign causes the remainder of a line to be ignored.
+.Pp
+Here is a sample configuration file:
+.Bl -column 08:00:09:0:66:ad SYSHPBSD,SYSHPUX "# vandy (anything)"
+.It #
+.It # ethernet addr	boot file(s)	comments
+.It #
+.It 08:00:09:0:66:ad	SYSHPBSD	# snake (4.3BSD)
+.It 08:00:09:0:59:5b		# vandy (anything)
+.It 8::9:1:C6:75	SYSHPBSD,SYSHPUX	# jaguar (either)
+.El
+.Pp
+.Nm Rbootd
+logs status and error messages via
+.Xr syslog 3 .
+A startup message is always logged, and in the case of fatal errors (or
+deadly signals) a message is logged announcing the server's termination.
+In general, a non-fatal error is handled by ignoring the event that caused
+it (e.g. an invalid Ethernet address in the config file causes that line
+to be invalidated).
+.Pp
+The following signals have the specified effect when sent to the server
+process using the
+.Xr kill 1
+command:
+.Bl -tag -width SIGUSR1 -offset -compact
+.It SIGHUP
+Drop all active connections and reconfigure.
+.It SIGUSR1
+Turn on debugging, do nothing if already on.
+.It SIGUSR2
+Turn off debugging, do nothing if already off.
+.El
+.Sh "FILES"
+.Bl -tag -width /usr/libexec/rbootd -compact
+.It /dev/bpf#
+packet-filter device
+.It /etc/rbootd.conf
+configuration file
+.It /tmp/rbootd.dbg
+debug output
+.It /usr/mdec/rbootd
+directory containing boot files
+.It /var/run/rbootd.pid
+process id
+.El
+.Sh SEE ALSO
+.Xr kill 1 ,
+.Xr socket 2 ,
+.Xr signal 3 ,
+.Xr syslog 3 ,
+.Xr rmp 4
+.Sh BUGS
+If multiple servers are started on the same interface, each will receive
+and respond to the same boot packets.
diff --git a/rbootd.tproj/rbootd.c b/rbootd.tproj/rbootd.c
new file mode 100644
index 0000000..cf661b2
--- /dev/null
+++ b/rbootd.tproj/rbootd.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)rbootd.c	8.2 (Berkeley) 2/22/94
+ *
+ * Utah $Hdr: rbootd.c 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1992, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)rbootd.c	8.2 (Berkeley) 2/22/94";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include "defs.h"
+
+
+/* fd mask macros (backward compatibility with 4.2BSD) */
+#ifndef	FD_SET
+#ifdef	notdef
+typedef	struct fd_set {		/* this should already be in 4.2 */
+	int fds_bits[1];
+} fd_set;
+#endif
+#define	FD_ZERO(p)	((p)->fds_bits[0] = 0)
+#define	FD_SET(n, p)	((p)->fds_bits[0] |= (1 << (n)))
+#define	FD_CLR(n, p)	((p)->fds_bits[0] &= ~(1 << (n)))
+#define	FD_ISSET(n, p)	((p)->fds_bits[0] & (1 << (n)))
+#endif
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int c, fd, omask, maxfds;
+	fd_set rset;
+
+	/*
+	 *  Find what name we are running under.
+	 */
+	ProgName = (ProgName = rindex(argv[0],'/')) ? ++ProgName : *argv;
+
+	/*
+	 *  Close any open file descriptors.
+	 *  Temporarily leave stdin & stdout open for `-d',
+	 *  and stderr open for any pre-syslog error messages.
+	 */
+	{
+		int i, nfds = getdtablesize();
+
+		for (i = 0; i < nfds; i++)
+			if (i != fileno(stdin) && i != fileno(stdout) &&
+			    i != fileno(stderr))
+				(void) close(i);
+	}
+
+	/*
+	 *  Parse any arguments.
+	 */
+	while ((c = getopt(argc, argv, "adi:")) != EOF)
+		switch(c) {
+		    case 'a':
+			BootAny++;
+			break;
+		    case 'd':
+			DebugFlg++;
+			break;
+		    case 'i':
+			IntfName = optarg;
+			break;
+		}
+	for (; optind < argc; optind++) {
+		if (ConfigFile == NULL)
+			ConfigFile = argv[optind];
+		else {
+			fprintf(stderr,
+			        "%s: too many config files (`%s' ignored)\n",
+			        ProgName, argv[optind]);
+		}
+	}
+
+	if (ConfigFile == NULL)			/* use default config file */
+		ConfigFile = DfltConfig;
+
+	if (DebugFlg) {
+		DbgFp = stdout;				/* output to stdout */
+
+		(void) signal(SIGUSR1, SIG_IGN);	/* dont muck w/DbgFp */
+		(void) signal(SIGUSR2, SIG_IGN);
+	} else {
+		(void) fclose(stdin);			/* dont need these */
+		(void) fclose(stdout);
+
+		/*
+		 *  Fork off a child to do the work & exit.
+		 */
+		switch(fork()) {
+			case -1:	/* fork failed */
+				fprintf(stderr, "%s: ", ProgName);
+				perror("fork");
+				Exit(0);
+			case 0:		/* this is the CHILD */
+				break;
+			default:	/* this is the PARENT */
+				_exit(0);
+		}
+
+		/*
+		 *  Try to disassociate from the current tty.
+		 */
+		{
+			char *devtty = "/dev/tty";
+			int i;
+
+			if ((i = open(devtty, O_RDWR)) < 0) {
+				/* probably already disassociated */
+				if (setpgrp(0, 0) < 0) {
+					fprintf(stderr, "%s: ", ProgName);
+					perror("setpgrp");
+				}
+			} else {
+				if (ioctl(i, (u_long)TIOCNOTTY, (char *)0) < 0){
+					fprintf(stderr, "%s: ", ProgName);
+					perror("ioctl");
+				}
+				(void) close(i);
+			}
+		}
+
+		(void) signal(SIGUSR1, DebugOn);
+		(void) signal(SIGUSR2, DebugOff);
+	}
+
+	(void) fclose(stderr);		/* finished with it */
+
+#ifdef SYSLOG4_2
+	openlog(ProgName, LOG_PID);
+#else
+	openlog(ProgName, LOG_PID, LOG_DAEMON);
+#endif
+
+	/*
+	 *  If no interface was specified, get one now.
+	 *
+	 *  This is convoluted because we want to get the default interface
+	 *  name for the syslog("restarted") message.  If BpfGetIntfName()
+	 *  runs into an error, it will return a syslog-able error message
+	 *  (in `errmsg') which will be displayed here.
+	 */
+	if (IntfName == NULL) {
+		char *errmsg;
+
+		if ((IntfName = BpfGetIntfName(&errmsg)) == NULL) {
+			syslog(LOG_NOTICE, "restarted (??)");
+			syslog(LOG_ERR, errmsg);
+			Exit(0);
+		}
+	}
+
+	syslog(LOG_NOTICE, "restarted (%s)", IntfName);
+
+	(void) signal(SIGHUP, ReConfig);
+	(void) signal(SIGINT, Exit);
+	(void) signal(SIGTERM, Exit);
+
+	/*
+	 *  Grab our host name and pid.
+	 */
+	if (gethostname(MyHost, MAXHOSTNAMELEN) < 0) {
+		syslog(LOG_ERR, "gethostname: %m");
+		Exit(0);
+	}
+	MyHost[MAXHOSTNAMELEN] = '\0';
+
+	MyPid = getpid();
+
+	/*
+	 *  Write proc's pid to a file.
+	 */
+	{
+		FILE *fp;
+
+		if ((fp = fopen(PidFile, "w")) != NULL) {
+			(void) fprintf(fp, "%d\n", MyPid);
+			(void) fclose(fp);
+		} else {
+			syslog(LOG_WARNING, "fopen: failed (%s)", PidFile);
+		}
+	}
+
+	/*
+	 *  All boot files are relative to the boot directory, we might
+	 *  as well chdir() there to make life easier.
+	 */
+	if (chdir(BootDir) < 0) {
+		syslog(LOG_ERR, "chdir: %m (%s)", BootDir);
+		Exit(0);
+	}
+
+	/*
+	 *  Initial configuration.
+	 */
+	omask = sigblock(sigmask(SIGHUP));	/* prevent reconfig's */
+	if (GetBootFiles() == 0)		/* get list of boot files */
+		Exit(0);
+	if (ParseConfig() == 0)			/* parse config file */
+		Exit(0);
+
+	/*
+	 *  Open and initialize a BPF device for the appropriate interface.
+	 *  If an error is encountered, a message is displayed and Exit()
+	 *  is called.
+	 */
+	fd = BpfOpen();
+
+	(void) sigsetmask(omask);		/* allow reconfig's */
+
+	/*
+	 *  Main loop: receive a packet, determine where it came from,
+	 *  and if we service this host, call routine to handle request.
+	 */
+	maxfds = fd + 1;
+	FD_ZERO(&rset);
+	FD_SET(fd, &rset);
+	for (;;) {
+		struct timeval timeout;
+		fd_set r;
+		int nsel;
+
+		r = rset;
+
+		if (RmpConns == NULL) {		/* timeout isnt necessary */
+			nsel = select(maxfds, &r, (fd_set *)0, (fd_set *)0,
+			              (struct timeval *)0);
+		} else {
+			timeout.tv_sec = RMP_TIMEOUT;
+			timeout.tv_usec = 0;
+			nsel = select(maxfds, &r, (fd_set *)0, (fd_set *)0,
+			              &timeout);
+		}
+
+		if (nsel < 0) {
+			if (errno == EINTR)
+				continue;
+			syslog(LOG_ERR, "select: %m");
+			Exit(0);
+		} else if (nsel == 0) {		/* timeout */
+			DoTimeout();			/* clear stale conns */
+			continue;
+		}
+
+		if (FD_ISSET(fd, &r)) {
+			RMPCONN rconn;
+			CLIENT *client, *FindClient();
+			int doread = 1;
+
+			while (BpfRead(&rconn, doread)) {
+				doread = 0;
+
+				if (DbgFp != NULL)	/* display packet */
+					DispPkt(&rconn,DIR_RCVD);
+
+				omask = sigblock(sigmask(SIGHUP));
+
+				/*
+				 *  If we do not restrict service, set the
+				 *  client to NULL (ProcessPacket() handles
+				 *  this).  Otherwise, check that we can
+				 *  service this host; if not, log a message
+				 *  and ignore the packet.
+				 */
+				if (BootAny) {
+					client = NULL;
+				} else if ((client=FindClient(&rconn))==NULL) {
+					syslog(LOG_INFO,
+					       "%s: boot packet ignored",
+					       EnetStr(&rconn));
+					(void) sigsetmask(omask);
+					continue;
+				}
+
+				ProcessPacket(&rconn,client);
+
+				(void) sigsetmask(omask);
+			}
+		}
+	}
+}
+
+/*
+**  DoTimeout -- Free any connections that have timed out.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- Timed out connections in `RmpConns' will be freed.
+*/
+void
+DoTimeout()
+{
+	register RMPCONN *rtmp;
+	struct timeval now;
+
+	(void) gettimeofday(&now, (struct timezone *)0);
+
+	/*
+	 *  For each active connection, if RMP_TIMEOUT seconds have passed
+	 *  since the last packet was sent, delete the connection.
+	 */
+	for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next)
+		if ((rtmp->tstamp.tv_sec + RMP_TIMEOUT) < now.tv_sec) {
+			syslog(LOG_WARNING, "%s: connection timed out (%u)",
+			       EnetStr(rtmp), rtmp->rmp.r_type);
+			RemoveConn(rtmp);
+		}
+}
+
+/*
+**  FindClient -- Find client associated with a packet.
+**
+**	Parameters:
+**		rconn - the new packet. 
+**
+**	Returns:
+**		Pointer to client info if found, NULL otherwise.
+**
+**	Side Effects:
+**		None.
+**
+**	Warnings:
+**		- This routine must be called with SIGHUP blocked since
+**		  a reconfigure can invalidate the information returned.
+*/
+
+CLIENT *
+FindClient(rconn)
+	register RMPCONN *rconn;
+{
+	register CLIENT *ctmp;
+
+	for (ctmp = Clients; ctmp != NULL; ctmp = ctmp->next)
+		if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0],
+		         (char *)&ctmp->addr[0], RMP_ADDRLEN) == 0)
+			break;
+
+	return(ctmp);
+}
+
+/*
+**  Exit -- Log an error message and exit.
+**
+**	Parameters:
+**		sig - caught signal (or zero if not dying on a signal).
+**
+**	Returns:
+**		Does not return.
+**
+**	Side Effects:
+**		- This process ceases to exist.
+*/
+void
+Exit(sig)
+	int sig;
+{
+	if (sig > 0)
+		syslog(LOG_ERR, "going down on signal %d", sig);
+	else
+		syslog(LOG_ERR, "going down with fatal error");
+	BpfClose();
+	exit(1);
+}
+
+/*
+**  ReConfig -- Get new list of boot files and reread config files.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- All active connections are dropped.
+**		- List of boot-able files is changed.
+**		- List of clients is changed.
+**
+**	Warnings:
+**		- This routine must be called with SIGHUP blocked.
+*/
+void
+ReConfig(signo)
+	int signo;
+{
+	syslog(LOG_NOTICE, "reconfiguring boot server");
+
+	FreeConns();
+
+	if (GetBootFiles() == 0)
+		Exit(0);
+
+	if (ParseConfig() == 0)
+		Exit(0);
+}
+
+/*
+**  DebugOff -- Turn off debugging.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- Debug file is closed.
+*/
+void
+DebugOff(signo)
+	int signo;
+{
+	if (DbgFp != NULL)
+		(void) fclose(DbgFp);
+
+	DbgFp = NULL;
+}
+
+/*
+**  DebugOn -- Turn on debugging.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- Debug file is opened/truncated if not already opened,
+**		  otherwise do nothing.
+*/
+void
+DebugOn(signo)
+	int signo;
+{
+	if (DbgFp == NULL) {
+		if ((DbgFp = fopen(DbgFile, "w")) == NULL)
+			syslog(LOG_ERR, "can't open debug file (%s)", DbgFile);
+	}
+}
diff --git a/rbootd.tproj/rmp.h b/rbootd.tproj/rmp.h
new file mode 100644
index 0000000..31b9440
--- /dev/null
+++ b/rbootd.tproj/rmp.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)rmp.h	8.1 (Berkeley) 6/4/93
+ *
+ * Utah $Hdr: rmp.h 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+/*
+ *  Define MIN/MAX sizes of RMP (ethernet) packet.
+ *  For ease of computation, the 4 octet CRC field is not included.
+ *
+ *  MCLBYTES is for bpfwrite(); it is adamant about using a cluster.
+ */
+
+#define	RMP_MAX_PACKET	MIN(1514,MCLBYTES)
+#define	RMP_MIN_PACKET	60
+
+/*
+ *  Define RMP/Ethernet Multicast address (9:0:9:0:0:4) and its length.
+ */
+#define	RMP_ADDR	{ 0x9, 0x0, 0x9, 0x0, 0x0, 0x4 }
+#define	RMP_ADDRLEN	6
+
+/*
+ *  Define IEEE802.2 (Logical Link Control) information.
+ */
+#define	IEEE_DSAP_HP	0xF8	/* Destination Service Access Point */
+#define	IEEE_SSAP_HP	0xF8	/* Source Service Access Point */
+#define	IEEE_CNTL_HP	0x0300	/* Type 1 / I format control information */
+
+#define	HPEXT_DXSAP	0x608	/* HP Destination Service Access Point */
+#define	HPEXT_SXSAP	0x609	/* HP Source Service Access Point */
+
+/*
+ *  802.3-style "Ethernet" header.
+ */
+
+struct hp_hdr {
+	u_char	daddr[RMP_ADDRLEN];
+	u_char	saddr[RMP_ADDRLEN];
+	u_short	len;
+};
+
+/*
+ * HP uses 802.2 LLC with their own local extensions.  This struct makes
+ * sence out of this data (encapsulated in the above 802.3 packet).
+ */
+
+struct hp_llc {
+	u_char	dsap;		/* 802.2 DSAP */
+	u_char	ssap;		/* 802.2 SSAP */
+	u_short	cntrl;		/* 802.2 control field */
+	u_short	filler;		/* HP filler (must be zero) */
+	u_short	dxsap;		/* HP extended DSAP */
+	u_short	sxsap;		/* HP extended SSAP */
+};
diff --git a/rbootd.tproj/rmp_var.h b/rbootd.tproj/rmp_var.h
new file mode 100644
index 0000000..adecc85
--- /dev/null
+++ b/rbootd.tproj/rmp_var.h
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)rmp_var.h	8.1 (Berkeley) 6/4/93
+ *
+ * Utah $Hdr: rmp_var.h 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+/*
+ *  Possible values for "rmp_type" fields.
+ */
+
+#define	RMP_BOOT_REQ	1	/* boot request packet */
+#define	RMP_BOOT_REPL	129	/* boot reply packet */
+#define	RMP_READ_REQ	2	/* read request packet */
+#define	RMP_READ_REPL	130	/* read reply packet */
+#define	RMP_BOOT_DONE	3	/* boot complete packet */
+
+/*
+ *  Useful constants.
+ */
+
+#define RMP_VERSION	2	/* protocol version */
+#define RMP_TIMEOUT	600	/* timeout connection after ten minutes */
+#define	RMP_PROBESID	0xffff	/* session ID for probes */
+#define	RMP_HOSTLEN	13	/* max length of server's name */
+#define	RMP_MACHLEN	20	/* length of machine type field */
+
+/*
+ *  RMP error codes
+ */
+
+#define	RMP_E_OKAY	0
+#define	RMP_E_EOF	2	/* read reply: returned end of file */
+#define	RMP_E_ABORT	3	/* abort operation */
+#define	RMP_E_BUSY	4	/* boot reply: server busy */
+#define	RMP_E_TIMEOUT	5	/* lengthen time out (not implemented) */
+#define	RMP_E_NOFILE	16	/* boot reply: file does not exist */
+#define RMP_E_OPENFILE	17	/* boot reply: file open failed */
+#define	RMP_E_NODFLT	18	/* boot reply: default file does not exist */
+#define RMP_E_OPENDFLT	19	/* boot reply: default file open failed */
+#define	RMP_E_BADSID	25	/* read reply: bad session ID */
+#define RMP_E_BADPACKET	27 	/* Bad packet detected */
+
+/*
+ *  RMPDATALEN is the maximum number of data octets that can be stuffed
+ *  into an RMP packet.  This excludes the 802.2 LLC w/HP extensions.
+ */
+#define RMPDATALEN	(RMP_MAX_PACKET - (sizeof(struct hp_hdr) + \
+			                   sizeof(struct hp_llc)))
+
+/*
+ *  Define sizes of packets we send.  Boot and Read replies are variable
+ *  in length depending on the length of `s'.
+ *
+ *  Also, define how much space `restofpkt' can take up for outgoing
+ *  Boot and Read replies.  Boot Request packets are effectively
+ *  limited to 255 bytes due to the preceding 1-byte length field.
+ */
+
+#define	RMPBOOTSIZE(s)	(sizeof(struct hp_hdr) + sizeof(struct hp_llc) + \
+			 sizeof(struct rmp_boot_repl) + s - sizeof(restofpkt))
+#define	RMPREADSIZE(s)	(sizeof(struct hp_hdr) + sizeof(struct hp_llc) + \
+			 sizeof(struct rmp_read_repl) + s - sizeof(restofpkt) \
+			 - sizeof(u_char))
+#define	RMPDONESIZE	(sizeof(struct hp_hdr) + sizeof(struct hp_llc) + \
+			 sizeof(struct rmp_boot_done))
+#define	RMPBOOTDATA	255
+#define	RMPREADDATA	(RMPDATALEN - \
+			 (2*sizeof(u_char)+sizeof(u_short)+sizeof(u_word)))
+
+/*
+ * This protocol defines some field sizes as "rest of ethernet packet".
+ * There is no easy way to specify this in C, so we use a one character
+ * field to denote it, and index past it to the end of the packet.
+ */
+
+typedef char	restofpkt;
+
+/*
+ * Due to the RMP packet layout, we'll run into alignment problems
+ * on machines that cant access words on half-word boundaries.  If
+ * you know that your machine does not suffer from this problem,
+ * add it to the hp300 #define below.
+ *
+ * The following macros are used to deal with this problem:
+ *	WORDZE(w)	Return True if u_word `w' is zero, False otherwise.
+ *	ZEROWORD(w)	Set u_word `w' to zero.
+ *	COPYWORD(w1,w2)	Copy u_word `w1' to `w2'.
+ *	GETWORD(w,i)	Copy u_word `w' into int `i'.
+ *	PUTWORD(i,w)	Copy int `i' into u_word `w'.
+ *
+ * N.B. We do not support little endian alignment-challenged machines.
+ */
+#if defined(vax) || defined(tahoe) || defined(hp300)
+
+typedef	u_int		u_word;
+
+#define	WORDZE(w)	((w) == 0)
+#define	ZEROWORD(w)	(w) = 0
+#define	COPYWORD(w1,w2)	(w2) = (w1)
+#define	GETWORD(w, i)	(i) = (w)
+#define	PUTWORD(i, w)	(w) = (i)
+
+#else
+
+#define	_WORD_HIGHPART	0	/* XXX: assume Big Endian for now */
+#define	_WORD_LOWPART	1
+
+typedef	struct _uword { u_short val[2]; }	u_word;
+
+#define	WORDZE(w) \
+	((w.val[_WORD_HIGHPART] == 0) && (w.val[_WORD_LOWPART] == 0))
+#define	ZEROWORD(w) \
+	(w).val[_WORD_HIGHPART] = (w).val[_WORD_LOWPART] = 0
+#define	COPYWORD(w1, w2) \
+	{ (w2).val[_WORD_HIGHPART] = (w1).val[_WORD_HIGHPART]; \
+	  (w2).val[_WORD_LOWPART] = (w1).val[_WORD_LOWPART]; \
+	}
+#define	GETWORD(w, i) \
+	(i) = (((u_int)(w).val[_WORD_HIGHPART]) << 16) | (w).val[_WORD_LOWPART]
+#define	PUTWORD(i, w) \
+	{ (w).val[_WORD_HIGHPART] = (u_short) (((i) >> 16) & 0xffff); \
+	  (w).val[_WORD_LOWPART] = (u_short) (i & 0xffff); \
+	}
+
+#endif
+
+/*
+ * Packet structures.
+ */
+
+struct rmp_raw {		/* generic RMP packet */
+	u_char	rmp_type;		/* packet type */
+	u_char	rmp_rawdata[RMPDATALEN-1];
+};
+
+struct rmp_boot_req {		/* boot request */
+	u_char	rmp_type;		/* packet type (RMP_BOOT_REQ) */
+	u_char	rmp_retcode;		/* return code (0) */
+	u_word	rmp_seqno;		/* sequence number (real time clock) */
+	u_short	rmp_session;		/* session id (normally 0) */
+	u_short	rmp_version;		/* protocol version (RMP_VERSION) */
+	char	rmp_machtype[RMP_MACHLEN];	/* machine type */
+	u_char	rmp_flnmsize;		/* length of rmp_flnm */
+	restofpkt rmp_flnm;		/* name of file to be read */
+};
+
+struct rmp_boot_repl {		/* boot reply */
+	u_char	rmp_type;		/* packet type (RMP_BOOT_REPL) */
+	u_char	rmp_retcode;		/* return code (normally 0) */
+	u_word	rmp_seqno;		/* sequence number (from boot req) */
+	u_short	rmp_session;		/* session id (generated) */
+	u_short	rmp_version;		/* protocol version (RMP_VERSION) */
+	u_char	rmp_flnmsize;		/* length of rmp_flnm */
+	restofpkt rmp_flnm;		/* name of file (from boot req) */
+};
+
+struct rmp_read_req {		/* read request */
+	u_char	rmp_type;		/* packet type (RMP_READ_REQ) */
+	u_char	rmp_retcode;		/* return code (0) */
+	u_word	rmp_offset;		/* file relative byte offset */
+	u_short	rmp_session;		/* session id (from boot repl) */
+	u_short	rmp_size;		/* max no of bytes to send */
+};
+
+struct rmp_read_repl {		/* read reply */
+	u_char	rmp_type;		/* packet type (RMP_READ_REPL) */
+	u_char	rmp_retcode;		/* return code (normally 0) */
+	u_word	rmp_offset;		/* byte offset (from read req) */
+	u_short	rmp_session;		/* session id (from read req) */
+	restofpkt rmp_data;		/* data (max size from read req) */
+	u_char	rmp_unused;		/* padding to 16-bit boundary */
+};
+
+struct rmp_boot_done {		/* boot complete */
+	u_char	rmp_type;		/* packet type (RMP_BOOT_DONE) */
+	u_char	rmp_retcode;		/* return code (0) */
+	u_word	rmp_unused;		/* not used (0) */
+	u_short	rmp_session;		/* session id (from read repl) */
+};
+
+struct rmp_packet {
+	struct hp_hdr hp_hdr;
+	struct hp_llc hp_llc;
+	union {
+		struct rmp_boot_req	rmp_brq;	/* boot request */
+		struct rmp_boot_repl	rmp_brpl;	/* boot reply */
+		struct rmp_read_req	rmp_rrq;	/* read request */
+		struct rmp_read_repl	rmp_rrpl;	/* read reply */
+		struct rmp_boot_done	rmp_done;	/* boot complete */
+		struct rmp_raw		rmp_raw;	/* raw data */
+	} rmp_proto;
+};
+
+/*
+ *  Make life easier...
+ */
+
+#define	r_type	rmp_proto.rmp_raw.rmp_type
+#define	r_data	rmp_proto.rmp_raw.rmp_data
+#define	r_brq	rmp_proto.rmp_brq
+#define	r_brpl	rmp_proto.rmp_brpl
+#define	r_rrq	rmp_proto.rmp_rrq
+#define	r_rrpl	rmp_proto.rmp_rrpl
+#define	r_done	rmp_proto.rmp_done
diff --git a/rbootd.tproj/rmpproto.c b/rbootd.tproj/rmpproto.c
new file mode 100644
index 0000000..d8f676c
--- /dev/null
+++ b/rbootd.tproj/rmpproto.c
@@ -0,0 +1,616 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)rmpproto.c	8.1 (Berkeley) 6/4/93
+ *
+ * Utah $Hdr: rmpproto.c 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)rmpproto.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include "defs.h"
+
+/*
+**  ProcessPacket -- determine packet type and do what's required.
+**
+**	An RMP BOOT packet has been received.  Look at the type field
+**	and process Boot Requests, Read Requests, and Boot Complete
+**	packets.  Any other type will be dropped with a warning msg.
+**
+**	Parameters:
+**		rconn - the new connection
+**		client - list of files available to this host
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- If this is a valid boot request, it will be added to
+**		  the linked list of outstanding requests (RmpConns).
+**		- If this is a valid boot complete, its associated
+**		  entry in RmpConns will be deleted.
+**		- Also, unless we run out of memory, a reply will be
+**		  sent to the host that sent the packet.
+*/
+void
+ProcessPacket(rconn, client)
+	RMPCONN *rconn;
+	CLIENT *client;
+{
+	struct rmp_packet *rmp;
+	RMPCONN *rconnout;
+
+	rmp = &rconn->rmp;		/* cache pointer to RMP packet */
+
+	switch(rmp->r_type) {		/* do what we came here to do */
+		case RMP_BOOT_REQ:		/* boot request */
+			if ((rconnout = NewConn(rconn)) == NULL)
+				return;
+
+			/*
+			 *  If the Session ID is 0xffff, this is a "probe"
+			 *  packet and we do not want to add the connection
+			 *  to the linked list of active connections.  There
+			 *  are two types of probe packets, if the Sequence
+			 *  Number is 0 they want to know our host name, o/w
+			 *  they want the name of the file associated with
+			 *  the number spec'd by the Sequence Number.
+			 *
+			 *  If this is an actual boot request, open the file
+			 *  and send a reply.  If SendBootRepl() does not
+			 *  return 0, add the connection to the linked list
+			 *  of active connections, otherwise delete it since
+			 *  an error was encountered.
+			 */
+			if (rmp->r_brq.rmp_session == RMP_PROBESID) {
+				if (WORDZE(rmp->r_brq.rmp_seqno))
+					(void) SendServerID(rconnout);
+				else
+					(void) SendFileNo(rmp, rconnout,
+					                  client? client->files:
+					                          BootFiles);
+				FreeConn(rconnout);
+			} else {
+				if (SendBootRepl(rmp, rconnout,
+				    client? client->files: BootFiles))
+					AddConn(rconnout);
+				else
+					FreeConn(rconnout);
+			}
+			break;
+
+		case RMP_BOOT_REPL:		/* boot reply (not valid) */
+			syslog(LOG_WARNING, "%s: sent a boot reply",
+			       EnetStr(rconn));
+			break;
+
+		case RMP_READ_REQ:		/* read request */
+			/*
+			 *  Send a portion of the boot file.
+			 */
+			(void) SendReadRepl(rconn);
+			break;
+
+		case RMP_READ_REPL:		/* read reply (not valid) */
+			syslog(LOG_WARNING, "%s: sent a read reply",
+			       EnetStr(rconn));
+			break;
+
+		case RMP_BOOT_DONE:		/* boot complete */
+			/*
+			 *  Remove the entry from the linked list of active
+			 *  connections.
+			 */
+			(void) BootDone(rconn);
+			break;
+
+		default:			/* unknown RMP packet type */
+			syslog(LOG_WARNING, "%s: unknown packet type (%u)",
+			       EnetStr(rconn), rmp->r_type);
+	}
+}
+
+/*
+**  SendServerID -- send our host name to who ever requested it.
+**
+**	Parameters:
+**		rconn - the reply packet to be formatted.
+**
+**	Returns:
+**		1 on success, 0 on failure.
+**
+**	Side Effects:
+**		none.
+*/
+int
+SendServerID(rconn)
+	RMPCONN *rconn;
+{
+	register struct rmp_packet *rpl;
+	register char *src, *dst;
+	register u_char *size;
+
+	rpl = &rconn->rmp;			/* cache ptr to RMP packet */
+
+	/*
+	 *  Set up assorted fields in reply packet.
+	 */
+	rpl->r_brpl.rmp_type = RMP_BOOT_REPL;
+	rpl->r_brpl.rmp_retcode = RMP_E_OKAY;
+	ZEROWORD(rpl->r_brpl.rmp_seqno);
+	rpl->r_brpl.rmp_session = 0;
+	rpl->r_brpl.rmp_version = RMP_VERSION;
+
+	size = &rpl->r_brpl.rmp_flnmsize;	/* ptr to length of host name */
+
+	/*
+	 *  Copy our host name into the reply packet incrementing the
+	 *  length as we go.  Stop at RMP_HOSTLEN or the first dot.
+	 */
+	src = MyHost;
+	dst = (char *) &rpl->r_brpl.rmp_flnm;
+	for (*size = 0; *size < RMP_HOSTLEN; (*size)++) {
+		if (*src == '.' || *src == '\0')
+			break;
+		*dst++ = *src++;
+	}
+
+	rconn->rmplen = RMPBOOTSIZE(*size);	/* set packet length */
+
+	return(SendPacket(rconn));		/* send packet */
+}
+
+/*
+**  SendFileNo -- send the name of a bootable file to the requester.
+**
+**	Parameters:
+**		req - RMP BOOT packet containing the request.
+**		rconn - the reply packet to be formatted.
+**		filelist - list of files available to the requester.
+**
+**	Returns:
+**		1 on success, 0 on failure.
+**
+**	Side Effects:
+**		none.
+*/
+int
+SendFileNo(req, rconn, filelist)
+	struct rmp_packet *req;
+	RMPCONN *rconn;
+	char *filelist[];
+{
+	register struct rmp_packet *rpl;
+	register char *src, *dst;
+	register u_char *size, i;
+
+	GETWORD(req->r_brpl.rmp_seqno, i);	/* SeqNo is really FileNo */
+	rpl = &rconn->rmp;			/* cache ptr to RMP packet */
+
+	/*
+	 *  Set up assorted fields in reply packet.
+	 */
+	rpl->r_brpl.rmp_type = RMP_BOOT_REPL;
+	PUTWORD(i, rpl->r_brpl.rmp_seqno);
+	i--;
+	rpl->r_brpl.rmp_session = 0;
+	rpl->r_brpl.rmp_version = RMP_VERSION;
+
+	size = &rpl->r_brpl.rmp_flnmsize;	/* ptr to length of filename */
+	*size = 0;				/* init length to zero */
+
+	/*
+	 *  Copy the file name into the reply packet incrementing the
+	 *  length as we go.  Stop at end of string or when RMPBOOTDATA
+	 *  characters have been copied.  Also, set return code to
+	 *  indicate success or "no more files".
+	 */
+	if (i < C_MAXFILE && filelist[i] != NULL) {
+		src = filelist[i];
+		dst = (char *)&rpl->r_brpl.rmp_flnm;
+		for (; *src && *size < RMPBOOTDATA; (*size)++) {
+			if (*src == '\0')
+				break;
+			*dst++ = *src++;
+		}
+		rpl->r_brpl.rmp_retcode = RMP_E_OKAY;
+	} else
+		rpl->r_brpl.rmp_retcode = RMP_E_NODFLT;
+
+	rconn->rmplen = RMPBOOTSIZE(*size);	/* set packet length */
+
+	return(SendPacket(rconn));		/* send packet */
+}
+
+/*
+**  SendBootRepl -- open boot file and respond to boot request.
+**
+**	Parameters:
+**		req - RMP BOOT packet containing the request.
+**		rconn - the reply packet to be formatted.
+**		filelist - list of files available to the requester.
+**
+**	Returns:
+**		1 on success, 0 on failure.
+**
+**	Side Effects:
+**		none.
+*/
+int
+SendBootRepl(req, rconn, filelist)
+	struct rmp_packet *req;
+	RMPCONN *rconn;
+	char *filelist[];
+{
+	int retval;
+	char *filename, filepath[RMPBOOTDATA+1];
+	RMPCONN *oldconn;
+	register struct rmp_packet *rpl;
+	register char *src, *dst1, *dst2;
+	register u_char i;
+
+	/*
+	 *  If another connection already exists, delete it since we
+	 *  are obviously starting again.
+	 */
+	if ((oldconn = FindConn(rconn)) != NULL) {
+		syslog(LOG_WARNING, "%s: dropping existing connection",
+		       EnetStr(oldconn));
+		RemoveConn(oldconn);
+	}
+
+	rpl = &rconn->rmp;			/* cache ptr to RMP packet */
+
+	/*
+	 *  Set up assorted fields in reply packet.
+	 */
+	rpl->r_brpl.rmp_type = RMP_BOOT_REPL;
+	COPYWORD(req->r_brq.rmp_seqno, rpl->r_brpl.rmp_seqno);
+	rpl->r_brpl.rmp_session = GenSessID();
+	rpl->r_brpl.rmp_version = RMP_VERSION;
+	rpl->r_brpl.rmp_flnmsize = req->r_brq.rmp_flnmsize;
+
+	/*
+	 *  Copy file name to `filepath' string, and into reply packet.
+	 */
+	src = &req->r_brq.rmp_flnm;
+	dst1 = filepath;
+	dst2 = &rpl->r_brpl.rmp_flnm;
+	for (i = 0; i < req->r_brq.rmp_flnmsize; i++)
+		*dst1++ = *dst2++ = *src++;
+	*dst1 = '\0';
+
+	/*
+	 *  If we are booting HP-UX machines, their secondary loader will
+	 *  ask for files like "/hp-ux".  As a security measure, we do not
+	 *  allow boot files to lay outside the boot directory (unless they
+	 *  are purposely link'd out.  So, make `filename' become the path-
+	 *  stripped file name and spoof the client into thinking that it
+	 *  really got what it wanted.
+	 */
+	filename = (filename = rindex(filepath,'/'))? ++filename: filepath;
+
+	/*
+	 *  Check that this is a valid boot file name.
+	 */
+	for (i = 0; i < C_MAXFILE && filelist[i] != NULL; i++)
+		if (STREQN(filename, filelist[i]))
+			goto match;
+
+	/*
+	 *  Invalid boot file name, set error and send reply packet.
+	 */
+	rpl->r_brpl.rmp_retcode = RMP_E_NOFILE;
+	retval = 0;
+	goto sendpkt;
+
+match:
+	/*
+	 *  This is a valid boot file.  Open the file and save the file
+	 *  descriptor associated with this connection and set success
+	 *  indication.  If the file couldnt be opened, set error:
+	 *  	"no such file or dir" - RMP_E_NOFILE
+	 *	"file table overflow" - RMP_E_BUSY
+	 *	"too many open files" - RMP_E_BUSY
+	 *	anything else         - RMP_E_OPENFILE
+	 */
+	if ((rconn->bootfd = open(filename, O_RDONLY, 0600)) < 0) {
+		rpl->r_brpl.rmp_retcode = (errno == ENOENT)? RMP_E_NOFILE:
+			(errno == EMFILE || errno == ENFILE)? RMP_E_BUSY:
+			RMP_E_OPENFILE;
+		retval = 0;
+	} else {
+		rpl->r_brpl.rmp_retcode = RMP_E_OKAY;
+		retval = 1;
+	}
+
+sendpkt:
+	syslog(LOG_INFO, "%s: request to boot %s (%s)",
+	       EnetStr(rconn), filename, retval? "granted": "denied");
+
+	rconn->rmplen = RMPBOOTSIZE(rpl->r_brpl.rmp_flnmsize);
+
+	return (retval & SendPacket(rconn));
+}
+
+/*
+**  SendReadRepl -- send a portion of the boot file to the requester.
+**
+**	Parameters:
+**		rconn - the reply packet to be formatted.
+**
+**	Returns:
+**		1 on success, 0 on failure.
+**
+**	Side Effects:
+**		none.
+*/
+int
+SendReadRepl(rconn)
+	RMPCONN *rconn;
+{
+	int retval;
+	RMPCONN *oldconn;
+	register struct rmp_packet *rpl, *req;
+	register int size = 0;
+	int madeconn = 0;
+
+	/*
+	 *  Find the old connection.  If one doesnt exist, create one only
+	 *  to return the error code.
+	 */
+	if ((oldconn = FindConn(rconn)) == NULL) {
+		if ((oldconn = NewConn(rconn)) == NULL)
+			return(0);
+		syslog(LOG_ERR, "SendReadRepl: no active connection (%s)",
+		       EnetStr(rconn));
+		madeconn++;
+	}
+
+	req = &rconn->rmp;		/* cache ptr to request packet */
+	rpl = &oldconn->rmp;		/* cache ptr to reply packet */
+
+	if (madeconn) {			/* no active connection above; abort */
+		rpl->r_rrpl.rmp_retcode = RMP_E_ABORT;
+		retval = 1;
+		goto sendpkt;
+	}
+
+	/*
+	 *  Make sure Session ID's match.
+	 */
+	if (req->r_rrq.rmp_session !=
+	    ((rpl->r_type == RMP_BOOT_REPL)? rpl->r_brpl.rmp_session:
+	                                    rpl->r_rrpl.rmp_session)) {
+		syslog(LOG_ERR, "SendReadRepl: bad session id (%s)",
+		       EnetStr(rconn));
+		rpl->r_rrpl.rmp_retcode = RMP_E_BADSID;
+		retval = 1;
+		goto sendpkt;
+	}
+
+	/*
+	 *  If the requester asks for more data than we can fit,
+	 *  silently clamp the request size down to RMPREADDATA.
+	 *
+	 *  N.B. I do not know if this is "legal", however it seems
+	 *  to work.  This is necessary for bpfwrite() on machines
+	 *  with MCLBYTES less than 1514.
+	 */
+	if (req->r_rrq.rmp_size > RMPREADDATA)
+		req->r_rrq.rmp_size = RMPREADDATA;
+
+	/*
+	 *  Position read head on file according to info in request packet.
+	 */
+	GETWORD(req->r_rrq.rmp_offset, size);
+	if (lseek(oldconn->bootfd, (off_t)size, L_SET) < 0) {
+		syslog(LOG_ERR, "SendReadRepl: lseek: %m (%s)",
+		       EnetStr(rconn));
+		rpl->r_rrpl.rmp_retcode = RMP_E_ABORT;
+		retval = 1;
+		goto sendpkt;
+	}
+
+	/*
+	 *  Read data directly into reply packet.
+	 */
+	if ((size = read(oldconn->bootfd, &rpl->r_rrpl.rmp_data,
+	                 (int) req->r_rrq.rmp_size)) <= 0) {
+		if (size < 0) {
+			syslog(LOG_ERR, "SendReadRepl: read: %m (%s)",
+			       EnetStr(rconn));
+			rpl->r_rrpl.rmp_retcode = RMP_E_ABORT;
+		} else {
+			rpl->r_rrpl.rmp_retcode = RMP_E_EOF;
+		}
+		retval = 1;
+		goto sendpkt;
+	}
+
+	/*
+	 *  Set success indication.
+	 */
+	rpl->r_rrpl.rmp_retcode = RMP_E_OKAY;
+
+sendpkt:
+	/*
+	 *  Set up assorted fields in reply packet.
+	 */
+	rpl->r_rrpl.rmp_type = RMP_READ_REPL;
+	COPYWORD(req->r_rrq.rmp_offset, rpl->r_rrpl.rmp_offset);
+	rpl->r_rrpl.rmp_session = req->r_rrq.rmp_session;
+
+	oldconn->rmplen = RMPREADSIZE(size);	/* set size of packet */
+
+	retval &= SendPacket(oldconn);		/* send packet */
+
+	if (madeconn)				/* clean up after ourself */
+		FreeConn(oldconn);
+
+	return (retval);
+}
+
+/*
+**  BootDone -- free up memory allocated for a connection.
+**
+**	Parameters:
+**		rconn - incoming boot complete packet.
+**
+**	Returns:
+**		1 on success, 0 on failure.
+**
+**	Side Effects:
+**		none.
+*/
+int
+BootDone(rconn)
+	RMPCONN *rconn;
+{
+	RMPCONN *oldconn;
+	struct rmp_packet *rpl;
+
+	/*
+	 *  If we cant find the connection, ignore the request.
+	 */
+	if ((oldconn = FindConn(rconn)) == NULL) {
+		syslog(LOG_ERR, "BootDone: no existing connection (%s)",
+		       EnetStr(rconn));
+		return(0);
+	}
+
+	rpl = &oldconn->rmp;			/* cache ptr to RMP packet */
+
+	/*
+	 *  Make sure Session ID's match.
+	 */
+	if (rconn->rmp.r_rrq.rmp_session !=
+	    ((rpl->r_type == RMP_BOOT_REPL)? rpl->r_brpl.rmp_session:
+	                                    rpl->r_rrpl.rmp_session)) {
+		syslog(LOG_ERR, "BootDone: bad session id (%s)",
+		       EnetStr(rconn));
+		return(0);
+	}
+
+	RemoveConn(oldconn);			/* remove connection */
+
+	syslog(LOG_INFO, "%s: boot complete", EnetStr(rconn));
+
+	return(1);
+}
+
+/*
+**  SendPacket -- send an RMP packet to a remote host.
+**
+**	Parameters:
+**		rconn - packet to be sent.
+**
+**	Returns:
+**		1 on success, 0 on failure.
+**
+**	Side Effects:
+**		none.
+*/
+int
+SendPacket(rconn)
+	register RMPCONN *rconn;
+{
+	/*
+	 *  Set Ethernet Destination address to Source (BPF and the enet
+	 *  driver will take care of getting our source address set).
+	 */
+	bcopy((char *)&rconn->rmp.hp_hdr.saddr[0],
+	      (char *)&rconn->rmp.hp_hdr.daddr[0], RMP_ADDRLEN);
+	rconn->rmp.hp_hdr.len = rconn->rmplen - sizeof(struct hp_hdr);
+
+	/*
+	 *  Reverse 802.2/HP Extended Source & Destination Access Pts.
+	 */
+	rconn->rmp.hp_llc.dxsap = HPEXT_SXSAP;
+	rconn->rmp.hp_llc.sxsap = HPEXT_DXSAP;
+
+	/*
+	 *  Last time this connection was active.
+	 */
+	(void) gettimeofday(&rconn->tstamp, (struct timezone *)0);
+
+	if (DbgFp != NULL)			/* display packet */
+		DispPkt(rconn,DIR_SENT);
+
+	/*
+	 *  Send RMP packet to remote host.
+	 */
+	return(BpfWrite(rconn));
+}
diff --git a/rbootd.tproj/utils.c b/rbootd.tproj/utils.c
new file mode 100644
index 0000000..7837471
--- /dev/null
+++ b/rbootd.tproj/utils.c
@@ -0,0 +1,580 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1992 The University of Utah and the Center
+ *	for Software Science (CSS).
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Center for Software Science of the University of Utah Computer
+ * Science Department.  CSS requests users of this software to return
+ * to css-dist@cs.utah.edu any improvements that they make and grant
+ * CSS redistribution rights.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)utils.c	8.2 (Berkeley) 2/22/94
+ *
+ * Utah $Hdr: utils.c 3.1 92/07/06$
+ * Author: Jeff Forys, University of Utah CSS
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)utils.c	8.2 (Berkeley) 2/22/94";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+#include "defs.h"
+
+/*
+**  DispPkt -- Display the contents of an RMPCONN packet.
+**
+**	Parameters:
+**		rconn - packet to be displayed.
+**		direct - direction packet is going (DIR_*).
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		None.
+*/
+void
+DispPkt(rconn, direct)
+	RMPCONN *rconn;
+	int direct;
+{
+	static char BootFmt[] = "\t\tRetCode:%u SeqNo:%lx SessID:%x Vers:%u";
+	static char ReadFmt[] = "\t\tRetCode:%u Offset:%lx SessID:%x\n";
+
+	struct tm *tmp;
+	register struct rmp_packet *rmp;
+	int i, omask;
+	u_int t;
+
+	/*
+	 *  Since we will be working with RmpConns as well as DbgFp, we
+	 *  must block signals that can affect either.
+	 */
+	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2));
+
+	if (DbgFp == NULL) {			/* sanity */
+		(void) sigsetmask(omask);
+		return;
+	}
+
+	/* display direction packet is going using '>>>' or '<<<' */
+	fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp);
+
+	/* display packet timestamp */
+	tmp = localtime((time_t *)&rconn->tstamp.tv_sec);
+	fprintf(DbgFp, "%02d:%02d:%02d.%06ld   ", tmp->tm_hour, tmp->tm_min,
+	        tmp->tm_sec, rconn->tstamp.tv_usec);
+
+	/* display src or dst addr and information about network interface */
+	fprintf(DbgFp, "Addr: %s   Intf: %s\n", EnetStr(rconn), IntfName);
+
+	rmp = &rconn->rmp;
+
+	/* display IEEE 802.2 Logical Link Control header */
+	(void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n",
+	               rmp->hp_llc.dsap, rmp->hp_llc.ssap, rmp->hp_llc.cntrl);
+
+	/* display HP extensions to 802.2 Logical Link Control header */
+	(void) fprintf(DbgFp, "\tHP Ext:    DXSAP:%x SXSAP:%x\n",
+	               rmp->hp_llc.dxsap, rmp->hp_llc.sxsap);
+
+	/*
+	 *  Display information about RMP packet using type field to
+	 *  determine what kind of packet this is.
+	 */
+	switch(rmp->r_type) {
+		case RMP_BOOT_REQ:		/* boot request */
+			(void) fprintf(DbgFp, "\tBoot Request:");
+			GETWORD(rmp->r_brq.rmp_seqno, t);
+			if (rmp->r_brq.rmp_session == RMP_PROBESID) {
+				if (WORDZE(rmp->r_brq.rmp_seqno))
+					fputs(" (Send Server ID)", DbgFp);
+				else
+					fprintf(DbgFp," (Send Filename #%u)",t);
+			}
+			(void) fputc('\n', DbgFp);
+			(void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode,
+			        t, rmp->r_brq.rmp_session,
+			        rmp->r_brq.rmp_version);
+			(void) fprintf(DbgFp, "\n\t\tMachine Type: ");
+			for (i = 0; i < RMP_MACHLEN; i++)
+				(void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp);
+			DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm);
+			break;
+		case RMP_BOOT_REPL:		/* boot reply */
+			fprintf(DbgFp, "\tBoot Reply:\n");
+			GETWORD(rmp->r_brpl.rmp_seqno, t);
+			(void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode,
+			        t, rmp->r_brpl.rmp_session,
+			        rmp->r_brpl.rmp_version);
+			DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm);
+			break;
+		case RMP_READ_REQ:		/* read request */
+			(void) fprintf(DbgFp, "\tRead Request:\n");
+			GETWORD(rmp->r_rrq.rmp_offset, t);
+			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode,
+			        t, rmp->r_rrq.rmp_session);
+			(void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n",
+			        rmp->r_rrq.rmp_size);
+			break;
+		case RMP_READ_REPL:		/* read reply */
+			(void) fprintf(DbgFp, "\tRead Reply:\n");
+			GETWORD(rmp->r_rrpl.rmp_offset, t);
+			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode,
+			        t, rmp->r_rrpl.rmp_session);
+			(void) fprintf(DbgFp, "\t\tNoOfBytesSent: %d\n",
+			        rconn->rmplen - RMPREADSIZE(0));
+			break;
+		case RMP_BOOT_DONE:		/* boot complete */
+			(void) fprintf(DbgFp, "\tBoot Complete:\n");
+			(void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n",
+			        rmp->r_done.rmp_retcode,
+			        rmp->r_done.rmp_session);
+			break;
+		default:			/* ??? */
+			(void) fprintf(DbgFp, "\tUnknown Type:(%d)\n",
+				rmp->r_type);
+	}
+	(void) fputc('\n', DbgFp);
+	(void) fflush(DbgFp);
+
+	(void) sigsetmask(omask);		/* reset old signal mask */
+}
+
+
+/*
+**  GetEtherAddr -- convert an RMP (Ethernet) address into a string.
+**
+**	An RMP BOOT packet has been received.  Look at the type field
+**	and process Boot Requests, Read Requests, and Boot Complete
+**	packets.  Any other type will be dropped with a warning msg.
+**
+**	Parameters:
+**		addr - array of RMP_ADDRLEN bytes.
+**
+**	Returns:
+**		Pointer to static string representation of `addr'.
+**
+**	Side Effects:
+**		None.
+**
+**	Warnings:
+**		- The return value points to a static buffer; it must
+**		  be copied if it's to be saved.
+**		- For speed, we assume a u_char consists of 8 bits.
+*/
+char *
+GetEtherAddr(addr)
+	u_char *addr;
+{
+	static char Hex[] = "0123456789abcdef";
+	static char etherstr[RMP_ADDRLEN*3];
+	register int i;
+	register char *cp1, *cp2;
+
+	/*
+	 *  For each byte in `addr', convert it to "<hexchar><hexchar>:".
+	 *  The last byte does not get a trailing `:' appended.
+	 */
+	i = 0;
+	cp1 = (char *)addr;
+	cp2 = etherstr;
+	for(;;) {
+		*cp2++ = Hex[*cp1 >> 4 & 0xf];
+		*cp2++ = Hex[*cp1++ & 0xf];
+		if (++i == RMP_ADDRLEN)
+			break;
+		*cp2++ = ':';
+	}
+	*cp2 = '\0';
+
+	return(etherstr);
+}
+
+
+/*
+**  DispFlnm -- Print a string of bytes to DbgFp (often, a file name).
+**
+**	Parameters:
+**		size - number of bytes to print.
+**		flnm - address of first byte.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- Characters are sent to `DbgFp'.
+*/
+void
+DspFlnm(size, flnm)
+	register u_int size;
+	register char *flnm;
+{
+	register int i;
+
+	(void) fprintf(DbgFp, "\n\t\tFile Name (%d): <", size);
+	for (i = 0; i < size; i++)
+		(void) fputc(*flnm++, DbgFp);
+	(void) fputs(">\n", DbgFp);
+}
+
+
+/*
+**  NewClient -- allocate memory for a new CLIENT.
+**
+**	Parameters:
+**		addr - RMP (Ethernet) address of new client.
+**
+**	Returns:
+**		Ptr to new CLIENT or NULL if we ran out of memory.
+**
+**	Side Effects:
+**		- Memory will be malloc'd for the new CLIENT.
+**		- If malloc() fails, a log message will be generated.
+*/
+CLIENT *
+NewClient(addr)
+	u_char *addr;
+{
+	CLIENT *ctmp;
+
+	if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) {
+		syslog(LOG_ERR, "NewClient: out of memory (%s)",
+		       GetEtherAddr(addr));
+		return(NULL);
+	}
+
+	bzero(ctmp, sizeof(CLIENT));
+	bcopy(addr, &ctmp->addr[0], RMP_ADDRLEN);
+	return(ctmp);
+}
+
+/*
+**  FreeClient -- free linked list of Clients.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- All malloc'd memory associated with the linked list of
+**		  CLIENTS will be free'd; `Clients' will be set to NULL.
+**
+**	Warnings:
+**		- This routine must be called with SIGHUP blocked.
+*/
+void
+FreeClients()
+{
+	register CLIENT *ctmp;
+
+	while (Clients != NULL) {
+		ctmp = Clients;
+		Clients = Clients->next;
+		FreeClient(ctmp);
+	}
+}
+
+/*
+**  NewStr -- allocate memory for a character array.
+**
+**	Parameters:
+**		str - null terminated character array.
+**
+**	Returns:
+**		Ptr to new character array or NULL if we ran out of memory.
+**
+**	Side Effects:
+**		- Memory will be malloc'd for the new character array.
+**		- If malloc() fails, a log message will be generated.
+*/
+char *
+NewStr(str)
+	char *str;
+{
+	char *stmp;
+
+	if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) {
+		syslog(LOG_ERR, "NewStr: out of memory (%s)", str);
+		return(NULL);
+	}
+
+	(void) strcpy(stmp, str);
+	return(stmp);
+}
+
+/*
+**  To save time, NewConn and FreeConn maintain a cache of one RMPCONN
+**  in `LastFree' (defined below).
+*/
+
+static RMPCONN *LastFree = NULL;
+
+/*
+**  NewConn -- allocate memory for a new RMPCONN connection.
+**
+**	Parameters:
+**		rconn - initialization template for new connection.
+**
+**	Returns:
+**		Ptr to new RMPCONN or NULL if we ran out of memory.
+**
+**	Side Effects:
+**		- Memory may be malloc'd for the new RMPCONN (if not cached).
+**		- If malloc() fails, a log message will be generated.
+*/
+RMPCONN *
+NewConn(rconn)
+	RMPCONN *rconn;
+{
+	RMPCONN *rtmp;
+
+	if (LastFree == NULL) {		/* nothing cached; make a new one */
+		if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) {
+			syslog(LOG_ERR, "NewConn: out of memory (%s)",
+			       EnetStr(rconn));
+			return(NULL);
+		}
+	} else {			/* use the cached RMPCONN */
+		rtmp = LastFree;
+		LastFree = NULL;
+	}
+
+	/*
+	 *  Copy template into `rtmp', init file descriptor to `-1' and
+	 *  set ptr to next elem NULL.
+	 */
+	bcopy((char *)rconn, (char *)rtmp, sizeof(RMPCONN));
+	rtmp->bootfd = -1;
+	rtmp->next = NULL;
+
+	return(rtmp);
+}
+
+/*
+**  FreeConn -- Free memory associated with an RMPCONN connection.
+**
+**	Parameters:
+**		rtmp - ptr to RMPCONN to be free'd.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- Memory associated with `rtmp' may be free'd (or cached).
+**		- File desc associated with `rtmp->bootfd' will be closed.
+*/
+void
+FreeConn(rtmp)
+	register RMPCONN *rtmp;
+{
+	/*
+	 *  If the file descriptor is in use, close the file.
+	 */
+	if (rtmp->bootfd >= 0) {
+		(void) close(rtmp->bootfd);
+		rtmp->bootfd = -1;
+	}
+
+	if (LastFree == NULL)		/* cache for next time */
+		rtmp = LastFree;
+	else				/* already one cached; free this one */
+		free((char *)rtmp);
+}
+
+/*
+**  FreeConns -- free linked list of RMPCONN connections.
+**
+**	Parameters:
+**		None.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- All malloc'd memory associated with the linked list of
+**		  connections will be free'd; `RmpConns' will be set to NULL.
+**		- If LastFree is != NULL, it too will be free'd & NULL'd.
+**
+**	Warnings:
+**		- This routine must be called with SIGHUP blocked.
+*/
+void
+FreeConns()
+{
+	register RMPCONN *rtmp;
+
+	while (RmpConns != NULL) {
+		rtmp = RmpConns;
+		RmpConns = RmpConns->next;
+		FreeConn(rtmp);
+	}
+
+	if (LastFree != NULL) {
+		free((char *)LastFree);
+		LastFree = NULL;
+	}
+}
+
+/*
+**  AddConn -- Add a connection to the linked list of connections.
+**
+**	Parameters:
+**		rconn - connection to be added.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- RmpConn will point to new connection.
+**
+**	Warnings:
+**		- This routine must be called with SIGHUP blocked.
+*/
+void
+AddConn(rconn)
+	register RMPCONN *rconn;
+{
+	if (RmpConns != NULL)
+		rconn->next = RmpConns;
+	RmpConns = rconn;
+}
+
+/*
+**  FindConn -- Find a connection in the linked list of connections.
+**
+**	We use the RMP (Ethernet) address as the basis for determining
+**	if this is the same connection.  According to the Remote Maint
+**	Protocol, we can only have one connection with any machine.
+**
+**	Parameters:
+**		rconn - connection to be found.
+**
+**	Returns:
+**		Matching connection from linked list or NULL if not found.
+**
+**	Side Effects:
+**		None.
+**
+**	Warnings:
+**		- This routine must be called with SIGHUP blocked.
+*/
+RMPCONN *
+FindConn(rconn)
+	register RMPCONN *rconn;
+{
+	register RMPCONN *rtmp;
+
+	for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next)
+		if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0],
+		         (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0)
+			break;
+
+	return(rtmp);
+}
+
+/*
+**  RemoveConn -- Remove a connection from the linked list of connections.
+**
+**	Parameters:
+**		rconn - connection to be removed.
+**
+**	Returns:
+**		Nothing.
+**
+**	Side Effects:
+**		- If found, an RMPCONN will cease to exist and it will
+**		  be removed from the linked list.
+**
+**	Warnings:
+**		- This routine must be called with SIGHUP blocked.
+*/
+void
+RemoveConn(rconn)
+	register RMPCONN *rconn;
+{
+	register RMPCONN *thisrconn, *lastrconn;
+
+	if (RmpConns == rconn) {		/* easy case */
+		RmpConns = RmpConns->next;
+		FreeConn(rconn);
+	} else {				/* must traverse linked list */
+		lastrconn = RmpConns;			/* set back ptr */
+		thisrconn = lastrconn->next;		/* set current ptr */
+		while (thisrconn != NULL) {
+			if (rconn == thisrconn) {		/* found it */
+				lastrconn->next = thisrconn->next;
+				FreeConn(thisrconn);
+				break;
+			}
+			lastrconn = thisrconn;
+			thisrconn = thisrconn->next;
+		}
+	}
+}
diff --git a/rcp.tproj/Makefile b/rcp.tproj/Makefile
new file mode 100644
index 0000000..a35583a
--- /dev/null
+++ b/rcp.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rcp
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = extern.h pathnames.h
+
+CFILES = rcp.c util.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\
+            rcp.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /bin
+WINDOWS_INSTALLDIR = /bin
+PDO_UNIX_INSTALLDIR = /bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rcp.tproj/Makefile.dist b/rcp.tproj/Makefile.dist
new file mode 100644
index 0000000..898f9a7
--- /dev/null
+++ b/rcp.tproj/Makefile.dist
@@ -0,0 +1,13 @@
+#	@(#)Makefile	8.1 (Berkeley) 7/19/93
+
+PROG=	rcp
+SRCS=	rcp.c krcmd.c kcmd.c util.c
+CFLAGS+=-DKERBEROS -DCRYPT
+DPADD=	${LIBKRB} ${LIBDES}
+LDADD=	-lkrb -ldes
+BINOWN=	root
+BINMODE=4555
+INSTALLFLAGS=-fschg
+.PATH:	${.CURDIR}/../../usr.bin/rlogin
+
+.include <bsd.prog.mk>
diff --git a/rcp.tproj/Makefile.postamble b/rcp.tproj/Makefile.postamble
new file mode 100644
index 0000000..54c0935
--- /dev/null
+++ b/rcp.tproj/Makefile.postamble
@@ -0,0 +1,5 @@
+VPATH += :$(SRCROOT)$(SRCPATH)/../rlogin.tproj
+INSTALL_PERMISSIONS = 4555    # If set, 'install' chmod's executable to this
+
+after_install::
+	$(CHFLAGS) schg $(DSTROOT)$(INSTALLDIR)/$(NAME)
diff --git a/rcp.tproj/Makefile.preamble b/rcp.tproj/Makefile.preamble
new file mode 100644
index 0000000..8f3d6b7
--- /dev/null
+++ b/rcp.tproj/Makefile.preamble
@@ -0,0 +1,5 @@
+RLOGIN_CFILES = krcmd.c des_rw.c
+OTHER_OFILES = $(RLOGIN_CFILES:.c=.o)
+VPATH_PREAMBLE = ../rlogin.tproj:
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/rcp.tproj/PB.project b/rcp.tproj/PB.project
new file mode 100644
index 0000000..c2b93b6
--- /dev/null
+++ b/rcp.tproj/PB.project
@@ -0,0 +1,29 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (extern.h, pathnames.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (rcp.c, util.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, Makefile.dist, rcp.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_INSTALLDIR = /bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = rcp; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_INSTALLDIR = /bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_MAINNIB = rcp; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rcp; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_INSTALLDIR = /bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_MAINNIB = rcp; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rcp.tproj/extern.h b/rcp.tproj/extern.h
new file mode 100644
index 0000000..706251f
--- /dev/null
+++ b/rcp.tproj/extern.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)extern.h	8.1 (Berkeley) 5/31/93
+ */
+
+typedef struct {
+	int cnt;
+	char *buf;
+} BUF;
+
+extern int iamremote;
+
+BUF	*allocbuf __P((BUF *, int, int));
+char	*colon __P((char *));
+void	 lostconn __P((int));
+void	 nospace __P((void));
+int	 okname __P((char *));
+void	 run_err __P((const char *, ...));
+int	 susystem __P((char *, int));
+void	 verifydir __P((char *));
diff --git a/rcp.tproj/pathnames.h b/rcp.tproj/pathnames.h
new file mode 100644
index 0000000..a93c4e6
--- /dev/null
+++ b/rcp.tproj/pathnames.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 5/31/93
+ */
+
+#include <paths.h>
+
+#define	_PATH_CP	"/bin/cp"
+#define	_PATH_RSH	"/usr/bin/rsh"
diff --git a/rcp.tproj/rcp.1 b/rcp.tproj/rcp.1
new file mode 100644
index 0000000..bff0a01
--- /dev/null
+++ b/rcp.tproj/rcp.1
@@ -0,0 +1,159 @@
+.\" Copyright (c) 1983, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)rcp.1	8.1 (Berkeley) 5/31/93
+.\"
+.Dd May 31, 1993
+.Dt RCP 1
+.Os BSD 4.3r
+.Sh NAME
+.Nm rcp
+.Nd remote file copy
+.Sh SYNOPSIS
+.Nm rcp
+.Op Fl Kpx
+.Op Fl k Ar realm
+.Ar file1 file2
+.Nm rcp
+.Op Fl Kprx
+.Op Fl k Ar realm
+.Ar file ...
+.Ar directory
+.Sh DESCRIPTION
+.Nm Rcp
+copies files between machines.  Each
+.Ar file
+or
+.Ar directory
+argument is either a remote file name of the
+form ``rname@rhost:path'', or a local file name (containing no `:' characters,
+or a `/' before any `:'s).
+.Pp
+.Bl -tag -width flag
+.It Fl K
+The
+.Fl K
+option turns off all Kerberos authentication.
+.It Fl k
+The
+.Fl k
+option requests
+.Nm rcp
+to obtain tickets
+for the remote host in realm
+.Ar realm
+instead of the remote host's realm as determined by
+.Xr krb_realmofhost  3  .
+.It Fl p
+The
+.Fl p
+option causes
+.Nm rcp
+to attempt to preserve (duplicate) in its copies the modification
+times and modes of the source files, ignoring the
+.Ar umask  .
+By default, the mode and owner of
+.Ar file2
+are preserved if it already existed; otherwise the mode of the source file
+modified by the
+.Xr umask  2
+on the destination host is used.
+.It Fl r
+If any of the source files are directories,
+.Nm rcp
+copies each subtree rooted at that name; in this case
+the destination must be a directory.
+.It Fl x
+The
+.Fl x
+option turns on
+.Tn DES
+encryption for all data passed by
+.Nm rcp .
+This may impact response time and
+.Tn CPU
+utilization, but provides
+increased security.
+.El
+.Pp
+If
+.Ar path
+is not a full path name, it is interpreted relative to
+the login directory of the specified user
+.Ar ruser
+on
+.Ar rhost  ,
+or your current user name if no other remote user name is specified.
+A
+.Ar path
+on a remote host may be quoted (using \e, ", or \(aa)
+so that the metacharacters are interpreted remotely.
+.Pp
+.Nm Rcp
+does not prompt for passwords; it performs remote execution
+via
+.Xr rsh  1  ,
+and requires the same authorization.
+.Pp
+.Nm Rcp
+handles third party copies, where neither source nor target files
+are on the current machine.
+.Sh SEE ALSO
+.Xr cp 1 ,
+.Xr ftp 1 ,
+.Xr rsh 1 ,
+.Xr rlogin 1
+.Sh HISTORY
+The
+.Nm rcp
+command appeared in
+.Bx 4.2 .
+The version of
+.Nm rcp
+described here
+has been reimplemented with Kerberos in
+.Bx 4.3 Reno .
+.Sh BUGS
+Doesn't detect all cases where the target of a copy might
+be a file in cases where only a directory should be legal.
+.Pp
+Is confused by any output generated by commands in a
+.Pa \&.login ,
+.Pa \&.profile ,
+or
+.Pa \&.cshrc
+file on the remote host.
+.Pp
+The destination user and hostname may have to be specified as
+``rhost.rname'' when the destination machine is running the
+.Bx 4.2
+version of
+.Nm rcp  .
diff --git a/rcp.tproj/rcp.c b/rcp.tproj/rcp.c
new file mode 100644
index 0000000..579f328
--- /dev/null
+++ b/rcp.tproj/rcp.c
@@ -0,0 +1,938 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1990, 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pathnames.h"
+#include "extern.h"
+
+#ifdef KERBEROS
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+
+char	dst_realm_buf[REALM_SZ];
+char	*dest_realm = NULL;
+int	use_kerberos = 1;
+CREDENTIALS 	cred;
+Key_schedule	schedule;
+extern	char	*krb_realmofhost();
+#ifdef CRYPT
+int	doencrypt = 0;
+#define	OPTIONS	"dfKk:prtx"
+#else
+#define	OPTIONS	"dfKk:prt"
+#endif
+#else
+#define	OPTIONS "dfprt"
+#endif
+
+struct passwd *pwd;
+u_short	port;
+uid_t	userid;
+int errs, rem;
+int pflag, iamremote, iamrecursive, targetshouldbedirectory;
+
+#define	CMDNEEDS	64
+char cmd[CMDNEEDS];		/* must hold "rcp -r -p -d\0" */
+
+#ifdef KERBEROS
+int	 kerberos __P((char **, char *, char *, char *));
+void	 oldw __P((const char *, ...));
+#endif
+int	 response __P((void));
+void	 rsource __P((char *, struct stat *));
+void	 sink __P((int, char *[]));
+void	 source __P((int, char *[]));
+void	 tolocal __P((int, char *[]));
+void	 toremote __P((char *, int, char *[]));
+void	 usage __P((void));
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct servent *sp;
+	int ch, fflag, tflag;
+	char *targ, *shell;
+
+	fflag = tflag = 0;
+	while ((ch = getopt(argc, argv, OPTIONS)) != EOF)
+		switch(ch) {			/* User-visible flags. */
+		case 'K':
+#ifdef KERBEROS
+			use_kerberos = 0;
+#endif
+			break;
+#ifdef	KERBEROS
+		case 'k':
+			dest_realm = dst_realm_buf;
+			(void)strncpy(dst_realm_buf, optarg, REALM_SZ);
+			break;
+#ifdef CRYPT
+		case 'x':
+			doencrypt = 1;
+			/* des_set_key(cred.session, schedule); */
+			break;
+#endif
+#endif
+		case 'p':
+			pflag = 1;
+			break;
+		case 'r':
+			iamrecursive = 1;
+			break;
+						/* Server options. */
+		case 'd':
+			targetshouldbedirectory = 1;
+			break;
+		case 'f':			/* "from" */
+			iamremote = 1;
+			fflag = 1;
+			break;
+		case 't':			/* "to" */
+			iamremote = 1;
+			tflag = 1;
+			break;
+		case '?':
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+#ifdef KERBEROS
+	if (use_kerberos) {
+#ifdef CRYPT
+		shell = doencrypt ? "ekshell" : "kshell";
+#else
+		shell = "kshell";
+#endif
+		if ((sp = getservbyname(shell, "tcp")) == NULL) {
+			use_kerberos = 0;
+			oldw("can't get entry for %s/tcp service", shell);
+			sp = getservbyname(shell = "shell", "tcp");
+		}
+	} else
+		sp = getservbyname(shell = "shell", "tcp");
+#else
+	sp = getservbyname(shell = "shell", "tcp");
+#endif
+	if (sp == NULL)
+		errx(1, "%s/tcp: unknown service", shell);
+	port = sp->s_port;
+
+	if ((pwd = getpwuid(userid = getuid())) == NULL)
+		errx(1, "unknown user %d", (int)userid);
+
+	rem = STDIN_FILENO;		/* XXX */
+
+	if (fflag) {			/* Follow "protocol", send data. */
+		(void)response();
+		(void)setuid(userid);
+		source(argc, argv);
+		exit(errs);
+	}
+
+	if (tflag) {			/* Receive data. */
+		(void)setuid(userid);
+		sink(argc, argv);
+		exit(errs);
+	}
+
+	if (argc < 2)
+		usage();
+	if (argc > 2)
+		targetshouldbedirectory = 1;
+
+	rem = -1;
+	/* Command to be executed on remote system using "rsh". */
+#ifdef	KERBEROS
+	(void)snprintf(cmd, sizeof(cmd),
+	    "rcp%s%s%s%s", iamrecursive ? " -r" : "",
+#ifdef CRYPT
+	    (doencrypt && use_kerberos ? " -x" : ""),
+#else
+	    "",
+#endif
+	    pflag ? " -p" : "", targetshouldbedirectory ? " -d" : "");
+#else
+	(void)snprintf(cmd, sizeof(cmd), "rcp%s%s%s",
+	    iamrecursive ? " -r" : "", pflag ? " -p" : "",
+	    targetshouldbedirectory ? " -d" : "");
+#endif
+
+	(void)signal(SIGPIPE, lostconn);
+
+	if (targ = colon(argv[argc - 1]))	/* Dest is remote host. */
+		toremote(targ, argc, argv);
+	else {
+		tolocal(argc, argv);		/* Dest is local host. */
+		if (targetshouldbedirectory)
+			verifydir(argv[argc - 1]);
+	}
+	exit(errs);
+}
+
+void
+toremote(targ, argc, argv)
+	char *targ, *argv[];
+	int argc;
+{
+	int i, len, tos;
+	char *bp, *host, *src, *suser, *thost, *tuser;
+
+	*targ++ = 0;
+	if (*targ == 0)
+		targ = ".";
+
+	if (thost = strchr(argv[argc - 1], '@')) {
+		/* user@host */
+		*thost++ = 0;
+		tuser = argv[argc - 1];
+		if (*tuser == '\0')
+			tuser = NULL;
+		else if (!okname(tuser))
+			exit(1);
+	} else {
+		thost = argv[argc - 1];
+		tuser = NULL;
+	}
+
+	for (i = 0; i < argc - 1; i++) {
+		src = colon(argv[i]);
+		if (src) {			/* remote to remote */
+			*src++ = 0;
+			if (*src == 0)
+				src = ".";
+			host = strchr(argv[i], '@');
+			len = strlen(_PATH_RSH) + strlen(argv[i]) +
+			    strlen(src) + (tuser ? strlen(tuser) : 0) +
+			    strlen(thost) + strlen(targ) + CMDNEEDS + 20;
+			if (!(bp = malloc(len)))
+				err(1, NULL);
+			if (host) {
+				*host++ = 0;
+				suser = argv[i];
+				if (*suser == '\0')
+					suser = pwd->pw_name;
+				else if (!okname(suser))
+					continue;
+				(void)snprintf(bp, len,
+				    "%s %s -l %s -n %s %s '%s%s%s:%s'",
+				    _PATH_RSH, host, suser, cmd, src,
+				    tuser ? tuser : "", tuser ? "@" : "",
+				    thost, targ);
+			} else
+				(void)snprintf(bp, len,
+				    "exec %s %s -n %s %s '%s%s%s:%s'",
+				    _PATH_RSH, argv[i], cmd, src,
+				    tuser ? tuser : "", tuser ? "@" : "",
+				    thost, targ);
+			(void)susystem(bp, userid);
+			(void)free(bp);
+		} else {			/* local to remote */
+			if (rem == -1) {
+				len = strlen(targ) + CMDNEEDS + 20;
+				if (!(bp = malloc(len)))
+					err(1, NULL);
+				(void)snprintf(bp, len, "%s -t %s", cmd, targ);
+				host = thost;
+#ifdef KERBEROS
+				if (use_kerberos)
+					rem = kerberos(&host, bp,
+					    pwd->pw_name,
+					    tuser ? tuser : pwd->pw_name);
+				else
+#endif
+					rem = rcmd(&host, port, pwd->pw_name,
+					    tuser ? tuser : pwd->pw_name,
+					    bp, 0);
+				if (rem < 0)
+					exit(1);
+				tos = IPTOS_THROUGHPUT;
+				if (setsockopt(rem, IPPROTO_IP, IP_TOS,
+				    &tos, sizeof(int)) < 0)
+					warn("TOS (ignored)");
+				if (response() < 0)
+					exit(1);
+				(void)free(bp);
+				(void)setuid(userid);
+			}
+			source(1, argv+i);
+		}
+	}
+}
+
+void
+tolocal(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int i, len, tos;
+	char *bp, *host, *src, *suser;
+
+	for (i = 0; i < argc - 1; i++) {
+		if (!(src = colon(argv[i]))) {		/* Local to local. */
+			len = strlen(_PATH_CP) + strlen(argv[i]) +
+			    strlen(argv[argc - 1]) + 20;
+			if (!(bp = malloc(len)))
+				err(1, NULL);
+			(void)snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
+			    iamrecursive ? " -r" : "", pflag ? " -p" : "",
+			    argv[i], argv[argc - 1]);
+			if (susystem(bp, userid))
+				++errs;
+			(void)free(bp);
+			continue;
+		}
+		*src++ = 0;
+		if (*src == 0)
+			src = ".";
+		if ((host = strchr(argv[i], '@')) == NULL) {
+			host = argv[i];
+			suser = pwd->pw_name;
+		} else {
+			*host++ = 0;
+			suser = argv[i];
+			if (*suser == '\0')
+				suser = pwd->pw_name;
+			else if (!okname(suser))
+				continue;
+		}
+		len = strlen(src) + CMDNEEDS + 20;
+		if ((bp = malloc(len)) == NULL)
+			err(1, NULL);
+		(void)snprintf(bp, len, "%s -f %s", cmd, src);
+		rem = 
+#ifdef KERBEROS
+		    use_kerberos ? 
+			kerberos(&host, bp, pwd->pw_name, suser) : 
+#endif
+			rcmd(&host, port, pwd->pw_name, suser, bp, 0);
+		(void)free(bp);
+		if (rem < 0) {
+			++errs;
+			continue;
+		}
+		(void)seteuid(userid);
+		tos = IPTOS_THROUGHPUT;
+		if (setsockopt(rem, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0)
+			warn("TOS (ignored)");
+		sink(1, argv + argc - 1);
+		(void)seteuid(0);
+		(void)close(rem);
+		rem = -1;
+	}
+}
+
+void
+source(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct stat stb;
+	static BUF buffer;
+	BUF *bp;
+	off_t i;
+	int amt, fd, haderr, indx, result;
+	char *last, *name, buf[BUFSIZ];
+
+	for (indx = 0; indx < argc; ++indx) {
+                name = argv[indx];
+		if ((fd = open(name, O_RDONLY, 0)) < 0)
+			goto syserr;
+		if (fstat(fd, &stb)) {
+syserr:			run_err("%s: %s", name, strerror(errno));
+			goto next;
+		}
+		switch (stb.st_mode & S_IFMT) {
+		case S_IFREG:
+			break;
+		case S_IFDIR:
+			if (iamrecursive) {
+				rsource(name, &stb);
+				goto next;
+			}
+			/* FALLTHROUGH */
+		default:
+			run_err("%s: not a regular file", name);
+			goto next;
+		}
+		if ((last = strrchr(name, '/')) == NULL)
+			last = name;
+		else
+			++last;
+		if (pflag) {
+			/*
+			 * Make it compatible with possible future
+			 * versions expecting microseconds.
+			 */
+			(void)snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n",
+			    stb.st_mtimespec.tv_sec, stb.st_atimespec.tv_sec);
+			(void)write(rem, buf, strlen(buf));
+			if (response() < 0)
+				goto next;
+		}
+#define	MODEMASK	(S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
+		(void)snprintf(buf, sizeof(buf), "C%04o %qd %s\n",
+		    stb.st_mode & MODEMASK, stb.st_size, last);
+		(void)write(rem, buf, strlen(buf));
+		if (response() < 0)
+			goto next;
+		if ((bp = allocbuf(&buffer, fd, BUFSIZ)) == NULL) {
+next:			(void)close(fd);
+			continue;
+		}
+
+		/* Keep writing after an error so that we stay sync'd up. */
+		for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
+			amt = bp->cnt;
+			if (i + amt > stb.st_size)
+				amt = stb.st_size - i;
+			if (!haderr) {
+				result = read(fd, bp->buf, amt);
+				if (result != amt)
+					haderr = result >= 0 ? EIO : errno;
+			}
+			if (haderr)
+				(void)write(rem, bp->buf, amt);
+			else {
+				result = write(rem, bp->buf, amt);
+				if (result != amt)
+					haderr = result >= 0 ? EIO : errno;
+			}
+		}
+		if (close(fd) && !haderr)
+			haderr = errno;
+		if (!haderr)
+			(void)write(rem, "", 1);
+		else
+			run_err("%s: %s", name, strerror(haderr));
+		(void)response();
+	}
+}
+
+void
+rsource(name, statp)
+	char *name;
+	struct stat *statp;
+{
+	DIR *dirp;
+	struct dirent *dp;
+	char *last, *vect[1], path[MAXPATHLEN];
+
+	if (!(dirp = opendir(name))) {
+		run_err("%s: %s", name, strerror(errno));
+		return;
+	}
+	last = strrchr(name, '/');
+	if (last == 0)
+		last = name;
+	else
+		last++;
+	if (pflag) {
+		(void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n",
+		    statp->st_mtimespec.tv_sec, statp->st_atimespec.tv_sec);
+		(void)write(rem, path, strlen(path));
+		if (response() < 0) {
+			closedir(dirp);
+			return;
+		}
+	}
+	(void)snprintf(path, sizeof(path),
+	    "D%04o %d %s\n", statp->st_mode & MODEMASK, 0, last);
+	(void)write(rem, path, strlen(path));
+	if (response() < 0) {
+		closedir(dirp);
+		return;
+	}
+	while (dp = readdir(dirp)) {
+		if (dp->d_ino == 0)
+			continue;
+		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
+			continue;
+		if (strlen(name) + 1 + strlen(dp->d_name) >= MAXPATHLEN - 1) {
+			run_err("%s/%s: name too long", name, dp->d_name);
+			continue;
+		}
+		(void)snprintf(path, sizeof(path), "%s/%s", name, dp->d_name);
+		vect[0] = path;
+		source(1, vect);
+	}
+	(void)closedir(dirp);
+	(void)write(rem, "E\n", 2);
+	(void)response();
+}
+
+void
+sink(argc, argv)
+	int argc;
+	char *argv[];
+{
+	static BUF buffer;
+	struct stat stb;
+	struct timeval tv[2];
+	enum { YES, NO, DISPLAYED } wrerr;
+	BUF *bp;
+	off_t i, j;
+	int amt, count, exists, first, mask, mode, ofd, omode;
+	int setimes, size, targisdir, wrerrno;
+	char ch, *cp, *np, *targ, *why, *vect[1], buf[BUFSIZ];
+
+#define	atime	tv[0]
+#define	mtime	tv[1]
+#define	SCREWUP(str)	{ why = str; goto screwup; }
+
+	setimes = targisdir = 0;
+	mask = umask(0);
+	if (!pflag)
+		(void)umask(mask);
+	if (argc != 1) {
+		run_err("ambiguous target");
+		exit(1);
+	}
+	targ = *argv;
+	if (targetshouldbedirectory)
+		verifydir(targ);
+	(void)write(rem, "", 1);
+	if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
+		targisdir = 1;
+	for (first = 1;; first = 0) {
+		cp = buf;
+		if (read(rem, cp, 1) <= 0)
+			return;
+		if (*cp++ == '\n')
+			SCREWUP("unexpected <newline>");
+		do {
+			if (read(rem, &ch, sizeof(ch)) != sizeof(ch))
+				SCREWUP("lost connection");
+			*cp++ = ch;
+		} while (cp < &buf[BUFSIZ - 1] && ch != '\n');
+		*cp = 0;
+
+		if (buf[0] == '\01' || buf[0] == '\02') {
+			if (iamremote == 0)
+				(void)write(STDERR_FILENO,
+				    buf + 1, strlen(buf + 1));
+			if (buf[0] == '\02')
+				exit(1);
+			++errs;
+			continue;
+		}
+		if (buf[0] == 'E') {
+			(void)write(rem, "", 1);
+			return;
+		}
+
+		if (ch == '\n')
+			*--cp = 0;
+
+#define getnum(t) (t) = 0; while (isdigit(*cp)) (t) = (t) * 10 + (*cp++ - '0');
+		cp = buf;
+		if (*cp == 'T') {
+			setimes++;
+			cp++;
+			getnum(mtime.tv_sec);
+			if (*cp++ != ' ')
+				SCREWUP("mtime.sec not delimited");
+			getnum(mtime.tv_usec);
+			if (*cp++ != ' ')
+				SCREWUP("mtime.usec not delimited");
+			getnum(atime.tv_sec);
+			if (*cp++ != ' ')
+				SCREWUP("atime.sec not delimited");
+			getnum(atime.tv_usec);
+			if (*cp++ != '\0')
+				SCREWUP("atime.usec not delimited");
+			(void)write(rem, "", 1);
+			continue;
+		}
+		if (*cp != 'C' && *cp != 'D') {
+			/*
+			 * Check for the case "rcp remote:foo\* local:bar".
+			 * In this case, the line "No match." can be returned
+			 * by the shell before the rcp command on the remote is
+			 * executed so the ^Aerror_message convention isn't
+			 * followed.
+			 */
+			if (first) {
+				run_err("%s", cp);
+				exit(1);
+			}
+			SCREWUP("expected control record");
+		}
+		mode = 0;
+		for (++cp; cp < buf + 5; cp++) {
+			if (*cp < '0' || *cp > '7')
+				SCREWUP("bad mode");
+			mode = (mode << 3) | (*cp - '0');
+		}
+		if (*cp++ != ' ')
+			SCREWUP("mode not delimited");
+
+		for (size = 0; isdigit(*cp);)
+			size = size * 10 + (*cp++ - '0');
+		if (*cp++ != ' ')
+			SCREWUP("size not delimited");
+		if (targisdir) {
+			static char *namebuf;
+			static int cursize;
+			size_t need;
+
+			need = strlen(targ) + strlen(cp) + 250;
+			if (need > cursize) {
+				if (!(namebuf = malloc(need)))
+					run_err("%s", strerror(errno));
+			}
+			(void)snprintf(namebuf, need, "%s%s%s", targ,
+			    *targ ? "/" : "", cp);
+			np = namebuf;
+		} else
+			np = targ;
+		exists = stat(np, &stb) == 0;
+		if (buf[0] == 'D') {
+			int mod_flag = pflag;
+			if (exists) {
+				if (!S_ISDIR(stb.st_mode)) {
+					errno = ENOTDIR;
+					goto bad;
+				}
+				if (pflag)
+					(void)chmod(np, mode);
+			} else {
+				/* Handle copying from a read-only directory */
+				mod_flag = 1;
+				if (mkdir(np, mode | S_IRWXU) < 0)
+					goto bad;
+			}
+			vect[0] = np;
+			sink(1, vect);
+			if (setimes) {
+				setimes = 0;
+				if (utimes(np, tv) < 0)
+				    run_err("%s: set times: %s",
+					np, strerror(errno));
+			}
+			if (mod_flag)
+				(void)chmod(np, mode);
+			continue;
+		}
+		omode = mode;
+		mode |= S_IWRITE;
+		if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
+bad:			run_err("%s: %s", np, strerror(errno));
+			continue;
+		}
+		(void)write(rem, "", 1);
+		if ((bp = allocbuf(&buffer, ofd, BUFSIZ)) == NULL) {
+			(void)close(ofd);
+			continue;
+		}
+		cp = bp->buf;
+		wrerr = NO;
+		for (count = i = 0; i < size; i += BUFSIZ) {
+			amt = BUFSIZ;
+			if (i + amt > size)
+				amt = size - i;
+			count += amt;
+			do {
+				j = read(rem, cp, amt);
+				if (j <= 0) {
+					run_err("%s", j ? strerror(errno) :
+					    "dropped connection");
+					exit(1);
+				}
+				amt -= j;
+				cp += j;
+			} while (amt > 0);
+			if (count == bp->cnt) {
+				/* Keep reading so we stay sync'd up. */
+				if (wrerr == NO) {
+					j = write(ofd, bp->buf, count);
+					if (j != count) {
+						wrerr = YES;
+						wrerrno = j >= 0 ? EIO : errno; 
+					}
+				}
+				count = 0;
+				cp = bp->buf;
+			}
+		}
+		if (count != 0 && wrerr == NO &&
+		    (j = write(ofd, bp->buf, count)) != count) {
+			wrerr = YES;
+			wrerrno = j >= 0 ? EIO : errno; 
+		}
+		if (ftruncate(ofd, size)) {
+			run_err("%s: truncate: %s", np, strerror(errno));
+			wrerr = DISPLAYED;
+		}
+		if (pflag) {
+			if (exists || omode != mode)
+				if (fchmod(ofd, omode))
+					run_err("%s: set mode: %s",
+					    np, strerror(errno));
+		} else {
+			if (!exists && omode != mode)
+				if (fchmod(ofd, omode & ~mask))
+					run_err("%s: set mode: %s",
+					    np, strerror(errno));
+		}
+		(void)close(ofd);
+		(void)response();
+		if (setimes && wrerr == NO) {
+			setimes = 0;
+			if (utimes(np, tv) < 0) {
+				run_err("%s: set times: %s",
+				    np, strerror(errno));
+				wrerr = DISPLAYED;
+			}
+		}
+		switch(wrerr) {
+		case YES:
+			run_err("%s: %s", np, strerror(wrerrno));
+			break;
+		case NO:
+			(void)write(rem, "", 1);
+			break;
+		case DISPLAYED:
+			break;
+		}
+	}
+screwup:
+	run_err("protocol error: %s", why);
+	exit(1);
+}
+
+#ifdef KERBEROS
+int
+kerberos(host, bp, locuser, user)
+	char **host, *bp, *locuser, *user;
+{
+	struct servent *sp;
+
+again:
+	if (use_kerberos) {
+		rem = KSUCCESS;
+		errno = 0;
+		if (dest_realm == NULL)
+			dest_realm = krb_realmofhost(*host);
+		rem = 
+#ifdef CRYPT
+		    doencrypt ? 
+			krcmd_mutual(host,
+			    port, user, bp, 0, dest_realm, &cred, schedule) :
+#endif
+			krcmd(host, port, user, bp, 0, dest_realm);
+
+		if (rem < 0) {
+			use_kerberos = 0;
+			if ((sp = getservbyname("shell", "tcp")) == NULL)
+				errx(1, "unknown service shell/tcp");
+			if (errno == ECONNREFUSED)
+			    oldw("remote host doesn't support Kerberos");
+			else if (errno == ENOENT)
+			    oldw("can't provide Kerberos authentication data");
+			port = sp->s_port;
+			goto again;
+		}
+	} else {
+#ifdef CRYPT
+		if (doencrypt)
+			errx(1,
+			   "the -x option requires Kerberos authentication");
+#endif
+		rem = rcmd(host, port, locuser, user, bp, 0);
+	}
+	return (rem);
+}
+#endif /* KERBEROS */
+
+int
+response()
+{
+	char ch, *cp, resp, rbuf[BUFSIZ];
+
+	if (read(rem, &resp, sizeof(resp)) != sizeof(resp))
+		lostconn(0);
+
+	cp = rbuf;
+	switch(resp) {
+	case 0:				/* ok */
+		return (0);
+	default:
+		*cp++ = resp;
+		/* FALLTHROUGH */
+	case 1:				/* error, followed by error msg */
+	case 2:				/* fatal error, "" */
+		do {
+			if (read(rem, &ch, sizeof(ch)) != sizeof(ch))
+				lostconn(0);
+			*cp++ = ch;
+		} while (cp < &rbuf[BUFSIZ] && ch != '\n');
+
+		if (!iamremote)
+			(void)write(STDERR_FILENO, rbuf, cp - rbuf);
+		++errs;
+		if (resp == 1)
+			return (-1);
+		exit(1);
+	}
+	/* NOTREACHED */
+}
+
+void
+usage()
+{
+#ifdef KERBEROS
+#ifdef CRYPT
+	(void)fprintf(stderr, "%s\n\t%s\n",
+	    "usage: rcp [-Kpx] [-k realm] f1 f2",
+	    "or: rcp [-Kprx] [-k realm] f1 ... fn directory");
+#else
+	(void)fprintf(stderr, "%s\n\t%s\n",
+	    "usage: rcp [-Kp] [-k realm] f1 f2",
+	    "or: rcp [-Kpr] [-k realm] f1 ... fn directory");
+#endif
+#else
+	(void)fprintf(stderr,
+	    "usage: rcp [-p] f1 f2; or: rcp [-pr] f1 ... fn directory\n");
+#endif
+	exit(1);
+}
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef KERBEROS
+void
+#if __STDC__
+oldw(const char *fmt, ...)
+#else
+oldw(fmt, va_alist)
+	char *fmt;
+        va_dcl
+#endif
+{
+	va_list ap;
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	(void)fprintf(stderr, "rcp: ");
+	(void)vfprintf(stderr, fmt, ap);
+	(void)fprintf(stderr, ", using standard rcp\n");
+	va_end(ap);
+}
+#endif
+
+void
+#if __STDC__
+run_err(const char *fmt, ...)
+#else
+run_err(fmt, va_alist)
+	char *fmt;
+        va_dcl
+#endif
+{
+	static FILE *fp;
+	va_list ap;
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+
+	++errs;
+	if (fp == NULL && !(fp = fdopen(rem, "w")))
+		return;
+	(void)fprintf(fp, "%c", 0x01);
+	(void)fprintf(fp, "rcp: ");
+	(void)vfprintf(fp, fmt, ap);
+	(void)fprintf(fp, "\n");
+	(void)fflush(fp);
+
+	if (!iamremote)
+		vwarnx(fmt, ap);
+
+	va_end(ap);
+}
diff --git a/rcp.tproj/util.c b/rcp.tproj/util.c
new file mode 100644
index 0000000..7ee6866
--- /dev/null
+++ b/rcp.tproj/util.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "extern.h"
+
+char *
+colon(cp)
+	char *cp;
+{
+	if (*cp == ':')		/* Leading colon is part of file name. */
+		return (0);
+
+	for (; *cp; ++cp) {
+		if (*cp == ':')
+			return (cp);
+		if (*cp == '/')
+			return (0);
+	}
+	return (0);
+}
+
+void
+verifydir(cp)
+	char *cp;
+{
+	struct stat stb;
+
+	if (!stat(cp, &stb)) {
+		if (S_ISDIR(stb.st_mode))
+			return;
+		errno = ENOTDIR;
+	}
+	run_err("%s: %s", cp, strerror(errno));
+	exit(1);
+}
+
+int
+okname(cp0)
+	char *cp0;
+{
+	int c;
+	char *cp;
+
+	cp = cp0;
+	do {
+		c = *cp;
+		if (c & 0200)
+			goto bad;
+		if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-')
+			goto bad;
+	} while (*++cp);
+	return (1);
+
+bad:	warnx("%s: invalid user name", cp0);
+	return (0);
+}
+
+int
+susystem(s, userid)
+	int userid;
+	char *s;
+{
+	sig_t istat, qstat;
+	int status, w;
+	pid_t pid;
+
+	pid = vfork();
+	switch (pid) {
+	case -1:
+		return (127);
+	
+	case 0:
+		(void)setuid(userid);
+		execl(_PATH_BSHELL, "sh", "-c", s, NULL);
+		_exit(127);
+	}
+	istat = signal(SIGINT, SIG_IGN);
+	qstat = signal(SIGQUIT, SIG_IGN);
+	if (waitpid(pid, &status, 0) < 0)
+		status = -1;
+	(void)signal(SIGINT, istat);
+	(void)signal(SIGQUIT, qstat);
+	return (status);
+}
+
+BUF *
+allocbuf(bp, fd, blksize)
+	BUF *bp;
+	int fd, blksize;
+{
+	struct stat stb;
+	size_t size;
+
+	if (fstat(fd, &stb) < 0) {
+		run_err("fstat: %s", strerror(errno));
+		return (0);
+	}
+	size = roundup(stb.st_blksize, blksize);
+	if (size == 0)
+		size = blksize;
+	if (bp->cnt >= size)
+		return (bp);
+	if ((bp->buf = realloc(bp->buf, size)) == NULL) {
+		bp->cnt = 0;
+		run_err("%s", strerror(errno));
+		return (0);
+	}
+	bp->cnt = size;
+	return (bp);
+}
+
+void
+lostconn(signo)
+	int signo;
+{
+	if (!iamremote)
+		warnx("lost connection");
+	exit(1);
+}
diff --git a/revnetgroup.tproj/Makefile b/revnetgroup.tproj/Makefile
new file mode 100644
index 0000000..a494108
--- /dev/null
+++ b/revnetgroup.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = revnetgroup
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = hash.h
+
+CFILES = hash.c parse_netgroup.c revnetgroup.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble revnetgroup.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/revnetgroup.tproj/Makefile.postamble b/revnetgroup.tproj/Makefile.postamble
new file mode 100644
index 0000000..509e7f5
--- /dev/null
+++ b/revnetgroup.tproj/Makefile.postamble
@@ -0,0 +1,101 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGE: langage in which the project is written (default "English")
+#  LOCAL_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/revnetgroup.tproj/Makefile.preamble b/revnetgroup.tproj/Makefile.preamble
new file mode 100644
index 0000000..83f25c7
--- /dev/null
+++ b/revnetgroup.tproj/Makefile.preamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. <<default?>>
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSION: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
diff --git a/revnetgroup.tproj/PB.project b/revnetgroup.tproj/PB.project
new file mode 100644
index 0000000..3a8d039
--- /dev/null
+++ b/revnetgroup.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (hash.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (hash.c, parse_netgroup.c, revnetgroup.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, revnetgroup.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = revnetgroup; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/revnetgroup.tproj/hash.c b/revnetgroup.tproj/hash.c
new file mode 100644
index 0000000..9aee4bd
--- /dev/null
+++ b/revnetgroup.tproj/hash.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: hash.c,v 1.1 1997/04/15 22:06:11 maja Exp $ */
+/*
+ * Copyright (c) 1995
+ *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$FreeBSD: hash.c,v 1.4 1997/02/22 14:22:01 peter Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include "hash.h"
+
+#ifndef lint
+static const char rcsid[] = "$OpenBSD: hash.c,v 1.1 1997/04/15 22:06:11 maja Exp $";
+#endif
+
+/*
+ * This hash function is stolen directly from the
+ * Berkeley DB package. It already exists inside libc, but
+ * it's declared static which prevents us from calling it
+ * from here.
+ */
+/*
+ * OZ's original sdbm hash
+ */
+u_int32_t
+hash(keyarg, len)
+	const void *keyarg;
+	register size_t len;
+{
+	register const u_char *key;
+	register size_t loop;
+	register u_int32_t h;
+
+#define HASHC   h = *key++ + 65599 * h
+
+	h = 0;
+	key = keyarg;
+	if (len > 0) {
+		loop = (len + 8 - 1) >> 3;
+
+		switch (len & (8 - 1)) {
+		case 0:
+			do {
+				HASHC;
+				/* FALLTHROUGH */
+		case 7:
+				HASHC;
+				/* FALLTHROUGH */
+		case 6:
+				HASHC;
+				/* FALLTHROUGH */
+		case 5:
+				HASHC;
+				/* FALLTHROUGH */
+		case 4:
+				HASHC;
+				/* FALLTHROUGH */
+		case 3:
+				HASHC;
+				/* FALLTHROUGH */
+		case 2:
+				HASHC;
+				/* FALLTHROUGH */
+		case 1:
+				HASHC;
+			} while (--loop);
+		}
+	}
+	return (h);
+}
+
+/*
+ * Generate a hash value for a given key (character string).
+ * We mask off all but the lower 8 bits since our table array
+ * can only hold 256 elements.
+ */
+u_int32_t hashkey(key)
+	char *key;
+{
+
+	if (key == NULL)
+		return (-1);
+	return(hash((void *)key, strlen(key)) & HASH_MASK);
+}
+
+/* Find an entry in the hash table (may be hanging off a linked list). */
+char *lookup(table, key)
+	struct group_entry *table[];
+	char *key;
+{
+	struct group_entry *cur;
+
+	cur = table[hashkey(key)];
+
+	while (cur) {
+		if (!strcmp(cur->key, key))
+			return(cur->data);
+		cur = cur->next;
+	}
+
+	return(NULL);
+}
+
+/*
+ * Store an entry in the main netgroup hash table. Here's how this
+ * works: the table can only be so big when we initialize it (TABLESIZE)
+ * but the number of netgroups in the /etc/netgroup file could easily be
+ * much larger than the table. Since our hash values are adjusted to
+ * never be greater than TABLESIZE too, this means it won't be long before
+ * we find ourselves with two keys that hash to the same value.
+ *
+ * One way to deal with this is to malloc(2) a second table and start
+ * doing indirection, but this is a pain in the butt and it's not worth
+ * going to all that trouble for a dinky little program like this. Instead,
+ * we turn each table entry into a linked list and simply link keys
+ * with the same hash value together at the same index location within
+ * the table.
+ *
+ * That's a lot of comment for such a small piece of code, isn't it.
+ */
+void store (table, key, data)
+	struct group_entry *table[];
+	char *key, *data;
+{
+	struct group_entry *new;
+	u_int32_t i;
+
+	i = hashkey(key);
+
+	new = (struct group_entry *)malloc(sizeof(struct group_entry));
+	new->key = strdup(key);
+	new->data = strdup(data);
+	new->next = table[i];
+	table[i] = new;
+
+	return;
+}
+
+/*
+ * Store a group member entry and/or update its grouplist. This is
+ * a bit more complicated than the previous function since we have to
+ * maintain not only the hash table of group members, each group member
+ * structure also has a linked list of groups hung off it. If handed
+ * a member name that we haven't encountered before, we have to do
+ * two things: add that member to the table (possibly hanging them
+ * off the end of a linked list, as above), and add a group name to
+ * the member's grouplist list. If we're handed a name that already has
+ * an entry in the table, then we just have to do one thing, which is
+ * to update its grouplist.
+ */
+void mstore (table, key, data, domain)
+	struct member_entry *table[];
+	char *key, *data, *domain;
+{
+	struct member_entry *cur, *new;
+	struct grouplist *tmp,*p;
+	u_int32_t i;
+
+	i = hashkey(key);
+	cur = table[i];
+
+	tmp = (struct grouplist *)malloc(sizeof(struct grouplist));
+	tmp->groupname = strdup(data);
+	tmp->next = NULL;
+
+	/* Check if all we have to do is insert a new groupname. */
+	while (cur) {
+		if (!strcmp(cur->key, key) && !strcmp(cur->domain,domain)) {
+		  	p = cur->groups;
+			while(p) {
+				if (!strcmp(p->groupname,data))
+					return;
+				p = p->next;
+			}
+			tmp->next = cur->groups;
+			cur->groups = tmp;
+			return;
+		}
+		cur = cur->next;
+	}
+
+	/* Didn't find a match -- add the whole mess to the table. */
+	new = (struct member_entry *)malloc(sizeof(struct member_entry));
+	new->key = strdup(key);
+	new->domain = strdup(domain);
+	new->groups = tmp;
+	new->next = table[i];
+	table[i] = new;
+
+	return;
+}
diff --git a/revnetgroup.tproj/hash.h b/revnetgroup.tproj/hash.h
new file mode 100644
index 0000000..822c9e0
--- /dev/null
+++ b/revnetgroup.tproj/hash.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: hash.h,v 1.1 1997/04/15 22:06:12 maja Exp $ */
+/*
+ * Copyright (c) 1995
+ *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$FreeBSD: hash.h,v 1.5 1997/02/22 14:22:02 peter Exp $
+ */
+
+/* Groupname entry hung off a member_entry node. */
+struct grouplist {
+	char *groupname;
+	struct grouplist *next;
+};
+
+/* Entry in the cooked member list hash table. */
+struct member_entry {
+	char *key;
+	char *domain;
+	struct grouplist *groups;
+	struct member_entry *next;
+};
+
+/* Entry in the raw netgroup table. */
+struct group_entry {
+	char *key;
+	char *data;
+	struct group_entry *next;
+};
+
+/* Table size (chosen arbitrarily). Not too big, not too small. */
+#define TABLESIZE 256
+#define HASH_MASK 0x000000FF
+
+#define LINSIZ 1024 * 10
+
+extern void store __P(( struct group_entry ** , char *, char * ));
+extern void mstore __P(( struct member_entry ** , char *, char *, char * ));
+extern char *lookup __P(( struct group_entry **, char * ));
+extern void __endnetgrent __P(( void ));
+extern void __setnetgrent __P(( char * ));
+extern int __getnetgrent __P(( char **, char **, char ** ));
diff --git a/revnetgroup.tproj/parse_netgroup.c b/revnetgroup.tproj/parse_netgroup.c
new file mode 100644
index 0000000..0d1e07a
--- /dev/null
+++ b/revnetgroup.tproj/parse_netgroup.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: parse_netgroup.c,v 1.2 1997/08/18 03:11:35 millert Exp $ */
+/*
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$FreeBSD: parse_netgroup.c,v 1.5 1997/02/22 14:22:02 peter Exp $
+ */
+
+/*
+ * This is a specially hacked-up version of getnetgrent.c used to parse
+ * data from the stored hash table of netgroup info rather than from a
+ * file. It's used mainly for the parse_netgroup() function. All the YP
+ * stuff and file support has been stripped out since it isn't needed.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "hash.h"
+
+#ifndef lint
+static const char rcsid[] = "$OpenBSD: parse_netgroup.c,v 1.2 1997/08/18 03:11:35 millert Exp $";
+#endif
+
+/*
+ * Static Variables and functions used by setnetgrent(), getnetgrent() and
+ * __endnetgrent().
+ * There are two linked lists:
+ * - linelist is just used by setnetgrent() to parse the net group file via.
+ *   parse_netgrp()
+ * - netgrp is the list of entries for the current netgroup
+ */
+struct linelist {
+	struct linelist	*l_next;	/* Chain ptr. */
+	int		l_parsed;	/* Flag for cycles */
+	char		*l_groupname;	/* Name of netgroup */
+	char		*l_line;	/* Netgroup entrie(s) to be parsed */
+};
+
+struct netgrp {
+	struct netgrp	*ng_next;	/* Chain ptr */
+	char		*ng_str[3];	/* Field pointers, see below */
+};
+#define NG_HOST		0	/* Host name */
+#define NG_USER		1	/* User name */
+#define NG_DOM		2	/* and Domain name */
+
+static struct linelist	*linehead = (struct linelist *)0;
+static struct netgrp	*nextgrp = (struct netgrp *)0;
+static struct {
+	struct netgrp	*gr;
+	char		*grname;
+} grouphead = {
+	(struct netgrp *)0,
+	(char *)0,
+};
+static int parse_netgrp();
+static struct linelist *read_for_group();
+void __setnetgrent(), __endnetgrent();
+int __getnetgrent();
+extern struct group_entry *gtable[];
+
+/*
+ * setnetgrent()
+ * Parse the netgroup file looking for the netgroup and build the list
+ * of netgrp structures. Let parse_netgrp() and read_for_group() do
+ * most of the work.
+ */
+void
+__setnetgrent(group)
+	char *group;
+{
+	/* Sanity check */
+
+	if (group == NULL || !strlen(group))
+		return;
+
+	if (grouphead.gr == (struct netgrp *)0 ||
+		strcmp(group, grouphead.grname)) {
+		__endnetgrent();
+		if (parse_netgrp(group))
+			__endnetgrent();
+		else {
+			grouphead.grname = (char *)
+				malloc(strlen(group) + 1);
+			strcpy(grouphead.grname, group);
+		}
+	}
+	nextgrp = grouphead.gr;
+}
+
+/*
+ * Get the next netgroup off the list.
+ */
+int
+__getnetgrent(hostp, userp, domp)
+	char **hostp, **userp, **domp;
+{
+	if (nextgrp) {
+		*hostp = nextgrp->ng_str[NG_HOST];
+		*userp = nextgrp->ng_str[NG_USER];
+		*domp = nextgrp->ng_str[NG_DOM];
+		nextgrp = nextgrp->ng_next;
+		return (1);
+	}
+	return (0);
+}
+
+/*
+ * __endnetgrent() - cleanup
+ */
+void
+__endnetgrent()
+{
+	register struct linelist *lp, *olp;
+	register struct netgrp *gp, *ogp;
+
+	lp = linehead;
+	while (lp) {
+		olp = lp;
+		lp = lp->l_next;
+		free(olp->l_groupname);
+		free(olp->l_line);
+		free((char *)olp);
+	}
+	linehead = (struct linelist *)0;
+	if (grouphead.grname) {
+		free(grouphead.grname);
+		grouphead.grname = (char *)0;
+	}
+	gp = grouphead.gr;
+	while (gp) {
+		ogp = gp;
+		gp = gp->ng_next;
+		if (ogp->ng_str[NG_HOST])
+			free(ogp->ng_str[NG_HOST]);
+		if (ogp->ng_str[NG_USER])
+			free(ogp->ng_str[NG_USER]);
+		if (ogp->ng_str[NG_DOM])
+			free(ogp->ng_str[NG_DOM]);
+		free((char *)ogp);
+	}
+	grouphead.gr = (struct netgrp *)0;
+}
+
+/*
+ * Parse the netgroup file setting up the linked lists.
+ */
+static int
+parse_netgrp(group)
+	char *group;
+{
+	register char *spos, *epos;
+	register int len, strpos;
+#ifdef DEBUG
+	register int fields;
+#endif
+	char *pos, *gpos;
+	struct netgrp *grp;
+	struct linelist *lp = linehead;
+
+	/*
+	 * First, see if the line has already been read in.
+	 */
+	while (lp) {
+		if (!strcmp(group, lp->l_groupname))
+			break;
+		lp = lp->l_next;
+	}
+	if (lp == (struct linelist *)0 &&
+	    (lp = read_for_group(group)) == (struct linelist *)0)
+		return (1);
+	if (lp->l_parsed) {
+#ifdef DEBUG
+		/*
+		 * This error message is largely superflous since the
+		 * code handles the error condition sucessfully, and
+		 * spewing it out from inside libc can actually hose
+		 * certain programs.
+		 */
+		fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);
+#endif
+		return (1);
+	} else
+		lp->l_parsed = 1;
+	pos = lp->l_line;
+	/* Watch for null pointer dereferences, dammit! */
+	while (pos != NULL && *pos != '\0') {
+		if (*pos == '(') {
+			grp = (struct netgrp *)malloc(sizeof (struct netgrp));
+			bzero((char *)grp, sizeof (struct netgrp));
+			grp->ng_next = grouphead.gr;
+			grouphead.gr = grp;
+			pos++;
+			gpos = strsep(&pos, ")");
+#ifdef DEBUG
+			fields = 0;
+#endif
+			for (strpos = 0; strpos < 3; strpos++) {
+				if ((spos = strsep(&gpos, ","))) {
+#ifdef DEBUG
+					fields++;
+#endif
+					while (*spos == ' ' || *spos == '\t')
+						spos++;
+					if ((epos = strpbrk(spos, " \t"))) {
+						*epos = '\0';
+						len = epos - spos;
+					} else
+						len = strlen(spos);
+					if (len > 0) {
+						grp->ng_str[strpos] =  (char *)
+							malloc(len + 1);
+						bcopy(spos, grp->ng_str[strpos],
+							len + 1);
+					}
+				} else {
+					/*
+					 * All other systems I've tested
+					 * return NULL for empty netgroup
+					 * fields. It's up to user programs
+					 * to handle the NULLs appropriately.
+					 */
+					grp->ng_str[strpos] = NULL;
+				}
+			}
+#ifdef DEBUG
+			/*
+			 * Note: on other platforms, malformed netgroup
+			 * entries are not normally flagged. While we
+			 * can catch bad entries and report them, we should
+			 * stay silent by default for compatibility's sake.
+			 */
+			if (fields < 3)
+					fprintf(stderr, "Bad entry (%s%s%s%s%s) in netgroup \"%s\"\n",
+						grp->ng_str[NG_HOST] == NULL ? "" : grp->ng_str[NG_HOST],
+						grp->ng_str[NG_USER] == NULL ? "" : ",",
+						grp->ng_str[NG_USER] == NULL ? "" : grp->ng_str[NG_USER],
+						grp->ng_str[NG_DOM] == NULL ? "" : ",",
+						grp->ng_str[NG_DOM] == NULL ? "" : grp->ng_str[NG_DOM],
+						lp->l_groupname);
+#endif
+		} else {
+			spos = strsep(&pos, ", \t");
+			if (parse_netgrp(spos))
+				continue;
+		}
+		/* Watch for null pointer dereferences, dammit! */
+		if (pos != NULL)
+			while (*pos == ' ' || *pos == ',' || *pos == '\t')
+				pos++;
+	}
+	return (0);
+}
+
+/*
+ * Read the netgroup file and save lines until the line for the netgroup
+ * is found. Return 1 if eof is encountered.
+ */
+static struct linelist *
+read_for_group(group)
+	char *group;
+{
+	register char *pos, *spos, *linep = NULL, *olinep = NULL;
+	register int len, olen;
+	int cont;
+	struct linelist *lp;
+	char line[LINSIZ + 1];
+	char *data = NULL;
+
+	data = lookup (gtable, group);
+	sprintf(line, "%s %s", group, data);
+	pos = (char *)&line;
+#ifdef CANT_HAPPEN
+	if (*pos == '#')
+		continue;
+#endif
+	while (*pos == ' ' || *pos == '\t')
+		pos++;
+	spos = pos;
+	while (*pos != ' ' && *pos != '\t' && *pos != '\n' &&
+		*pos != '\0')
+		pos++;
+	len = pos - spos;
+	while (*pos == ' ' || *pos == '\t')
+		pos++;
+	if (*pos != '\n' && *pos != '\0') {
+		lp = (struct linelist *)malloc(sizeof (*lp));
+		lp->l_parsed = 0;
+		lp->l_groupname = (char *)malloc(len + 1);
+		bcopy(spos, lp->l_groupname, len);
+		*(lp->l_groupname + len) = '\0';
+		len = strlen(pos);
+		olen = 0;
+			/*
+			 * Loop around handling line continuations.
+			 */
+			do {
+				if (*(pos + len - 1) == '\n')
+					len--;
+				if (*(pos + len - 1) == '\\') {
+					len--;
+					cont = 1;
+				} else
+					cont = 0;
+				if (len > 0) {
+					linep = (char *)malloc(olen + len + 1);
+					if (olen > 0) {
+						bcopy(olinep, linep, olen);
+						free(olinep);
+					}
+					bcopy(pos, linep + olen, len);
+					olen += len;
+					*(linep + olen) = '\0';
+					olinep = linep;
+				}
+#ifdef CANT_HAPPEN
+				if (cont) {
+					if (fgets(line, LINSIZ, netf)) {
+						pos = line;
+						len = strlen(pos);
+					} else
+						cont = 0;
+				}
+#endif
+			} while (cont);
+		lp->l_line = linep;
+		lp->l_next = linehead;
+		linehead = lp;
+#ifdef CANT_HAPPEN
+		/*
+		 * If this is the one we wanted, we are done.
+		 */
+		if (!strcmp(lp->l_groupname, group))
+#endif
+			return (lp);
+	}
+	return ((struct linelist *)0);
+}
diff --git a/revnetgroup.tproj/revnetgroup.8 b/revnetgroup.tproj/revnetgroup.8
new file mode 100644
index 0000000..aea4095
--- /dev/null
+++ b/revnetgroup.tproj/revnetgroup.8
@@ -0,0 +1,138 @@
+.\"	$OpenBSD: revnetgroup.8,v 1.1 1997/04/15 22:06:14 maja Exp $
+.\" Copyright (c) 1995
+.\"	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by Bill Paul.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	$FreeBSD: revnetgroup.8,v 1.4 1997/02/22 14:22:03 peter Exp $
+.\"
+.Dd October 24, 1995
+.Dt REVNETGROUP 8
+.Os
+.Sh NAME
+.Nm revnetgroup
+.Nd "generate reverse netgroup data"
+.Sh SYNOPSIS
+.Nm revnetgroup
+.Fl u
+.Fl h
+.Op Fl f Ar netgroup_file
+.Sh DESCRIPTION
+.Nm revnetgroup
+processes the contents of a file in
+.Xr netgroup 5
+format into what is called
+.Pa reverse netgroup
+form. That is, where the original file shows
+netgroup memberships in terms of which members reside in a particular
+group, the reverse netgroup format specifies what groups are associated
+with a particular member. This information is used to generate the
+.Nm netgroup.byuser
+and
+.Nm netgroup.byhosts
+YP maps. These reverse netgroup maps are used to help speed up
+netgroup lookups, particularly for the
+.Fn innetgr
+library function.
+.Pp
+For example, the standard
+.Nm /etc/netgroup
+file may list a netgroup and a list of its members. Here, the
+netgroup is considered the
+.Pa key
+and the member names are the
+.Pa data .
+By contrast, the reverse
+.Nm netgroup.byusers
+database lists each unique
+member as the key and the netgroups to which the members belong become
+the data. Seperate databases are created to hold information pertaining
+to users and hosts; this allows netgroup username lookups
+and netgroup hostname lookups to be performed using independent keyspaces.
+.Pp
+By constructing these reverse netgroup databases (and the corresponding
+YP maps) in advance, the
+.Xr getnetgrent 3
+library functions are spared from having to work out the dependencies
+themselves on the fly. This is important on networks with large numbers
+of users and hosts, since it can take a considerable amount of time
+to process very large netgroup databases.
+.Pp
+The
+.Nm revnetgroup
+command prints its results on the standard output. It is usually called
+only by
+.Nm /var/yp/\<domain\>/Makefile
+when rebuilding the YP netgroup maps.
+.Pp
+.Sh OPTIONS
+The
+.Nm revnetgroup
+command supports the following options:
+.Bl -tag -width flag
+.It Fl u
+Generate netgroup.byuser output; only username information in the
+original netgroup file is processed.
+.It Fl h
+Generate netgroup.byhost output; only hostname information in the
+original netgroup file is processed. (Note at least one of the
+.Fl u
+or
+.Fl h
+flags must be specified.)
+.It Op Fl f Ar netgroup_file
+The
+.Nm revnetgroup
+command uses
+.Nm /etc/netgroup
+as its default input file. The
+.Fl f
+flag allows the user to specify an alternate input file. Specifying ``-''
+as the input file causes
+.Nm revnetgroup
+to read from the standard input.
+.El
+.Sh FILES
+.Bl -tag -width Pa -compact
+.It Pa /var/yp/\<domain\>Makefile
+The Makefile that calls
+.Nm makedbm
+and
+.Nm revnetgroup
+to build the YP databases.
+.It Pa /etc/netgroup
+The default netgroup database file. This file is most often found
+only on the YP master server.
+.El
+.Sh SEE ALSO
+.Xr getnetgrent 3 ,
+.Xr yp 8 ,
+.Xr netgroup 5 ,
+.Xr makedbm 8
+.Sh AUTHOR
+Bill Paul <wpaul@ctr.columbia.edu>
diff --git a/revnetgroup.tproj/revnetgroup.c b/revnetgroup.tproj/revnetgroup.c
new file mode 100644
index 0000000..a45db99
--- /dev/null
+++ b/revnetgroup.tproj/revnetgroup.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: revnetgroup.c,v 1.1 1997/04/15 22:06:15 maja Exp $ */
+/*
+ * Copyright (c) 1995
+ *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * reverse netgroup map generator program
+ *
+ * Written by Bill Paul <wpaul@ctr.columbia.edu>
+ * Center for Telecommunications Research
+ * Columbia University, New York City
+ *
+ *	$FreeBSD: revnetgroup.c,v 1.7 1997/03/28 15:48:15 imp Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+#include "hash.h"
+
+#ifndef lint
+static const char rcsid[] = "$OpenBSD: revnetgroup.c,v 1.1 1997/04/15 22:06:15 maja Exp $";
+#endif
+
+/* Default location of netgroup file. */
+char *netgroup = "/etc/netgroup";
+
+/* Stored hash table version of 'forward' netgroup database. */
+struct group_entry *gtable[TABLESIZE];
+
+/*
+ * Stored hash table of 'reverse' netgroup member database
+ * which we will construct.
+ */
+struct member_entry *mtable[TABLESIZE];
+
+void usage(prog)
+char *prog;
+{
+	fprintf (stderr,"usage: %s -u|-h [-f netgroup file]\n",prog);
+	exit(1);
+}
+
+extern char *optarg;
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	FILE *fp;
+	char readbuf[LINSIZ];
+	struct group_entry *gcur;
+	struct member_entry *mcur;
+	char *host, *user, *domain;
+	int ch;
+	char *key = NULL, *data = NULL;
+	int hosts = -1, i;
+
+	if (argc < 2)
+		usage(argv[0]);
+
+	while ((ch = getopt(argc, argv, "uhf:")) != -1) {
+		switch(ch) {
+		case 'u':
+			if (hosts != -1) {
+				warnx("please use only one of -u or -h");
+				usage(argv[0]);
+			}
+			hosts = 0;
+			break;
+		case 'h':
+			if (hosts != -1) {
+				warnx("please use only one of -u or -h");
+				usage(argv[0]);
+			}
+			hosts = 1;
+			break;
+		case 'f':
+			netgroup = optarg;
+			break;
+		default:
+			usage(argv[0]);
+			break;
+		}
+	}
+
+	if (hosts == -1)
+		usage(argv[0]);
+
+	if (strcmp(netgroup, "-")) {
+		if ((fp = fopen(netgroup, "r")) == NULL) {
+			err(1,netgroup);
+		}
+	} else {
+		fp = stdin;
+	}
+
+	/* Stuff all the netgroup names and members into a hash table. */
+	while (fgets(readbuf, LINSIZ, fp)) {
+		if (readbuf[0] == '#')
+			continue;
+		/* handle backslash line continuations */
+		while(readbuf[strlen(readbuf) - 2] == '\\') {
+			fgets((char *)&readbuf[strlen(readbuf) - 2],
+					sizeof(readbuf) - strlen(readbuf), fp);
+		}
+		data = NULL;
+		if ((data = (char *)(strpbrk(readbuf, " \t") + 1)) < (char *)2)
+			continue;
+		key = (char *)&readbuf;
+		*(data - 1) = '\0';
+		store(gtable, key, data);
+	}
+
+	fclose(fp);
+
+	/*
+	 * Find all members of each netgroup and keep track of which
+	 * group they belong to.
+	 */
+	for (i = 0; i < TABLESIZE; i++) {
+		gcur = gtable[i];
+		while(gcur) {
+			__setnetgrent(gcur->key);
+			while(__getnetgrent(&host, &user, &domain) != NULL) {
+				if (hosts) {
+					if (!(host && !strcmp(host,"-"))) {
+						mstore(mtable,
+						       host ? host : "*",
+						       gcur->key,
+						       domain ? domain : "*");
+					}
+				} else {
+					if (!(user && !strcmp(user,"-"))) {
+						mstore(mtable,
+						       user ? user : "*",
+						       gcur->key,
+						       domain ? domain : "*");
+					}
+				}
+			}
+			gcur = gcur->next;
+		}
+	}
+
+	/* Release resources used by the netgroup parser code. */
+	__endnetgrent();
+
+	/* Spew out the results. */
+	for (i = 0; i < TABLESIZE; i++) {
+		mcur = mtable[i];
+		while(mcur) {
+			struct grouplist *tmp;
+			printf ("%s.%s\t", mcur->key, mcur->domain);
+			tmp = mcur->groups;
+			while(tmp) {
+				printf ("%s", tmp->groupname);
+				tmp = tmp->next;
+				if (tmp)
+					printf(",");
+			}
+			mcur = mcur->next;
+			printf ("\n");
+		}
+	}
+
+	/* Let the OS free all our resources. */
+	exit(0);
+}
diff --git a/rexecd.tproj/Makefile b/rexecd.tproj/Makefile
new file mode 100644
index 0000000..2b445ca
--- /dev/null
+++ b/rexecd.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rexecd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = rexecd.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble rexecd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rexecd.tproj/Makefile.postamble b/rexecd.tproj/Makefile.postamble
new file mode 100644
index 0000000..7ede358
--- /dev/null
+++ b/rexecd.tproj/Makefile.postamble
@@ -0,0 +1,111 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
diff --git a/rexecd.tproj/Makefile.preamble b/rexecd.tproj/Makefile.preamble
new file mode 100644
index 0000000..dcbd1c8
--- /dev/null
+++ b/rexecd.tproj/Makefile.preamble
@@ -0,0 +1,119 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS = 
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR = 
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+-include ../Makefile.include
diff --git a/rexecd.tproj/PB.project b/rexecd.tproj/PB.project
new file mode 100644
index 0000000..aa703bb
--- /dev/null
+++ b/rexecd.tproj/PB.project
@@ -0,0 +1,42 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (rexecd.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, rexecd.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_DOCUMENTEXTENSIONS = (); 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rexecd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rexecd.tproj/rexecd.8 b/rexecd.tproj/rexecd.8
new file mode 100644
index 0000000..3035900
--- /dev/null
+++ b/rexecd.tproj/rexecd.8
@@ -0,0 +1,149 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)rexecd.8	8.3 (Berkeley) 6/1/94
+.\"
+.Dd June 1, 1994
+.Dt REXECD 8
+.Os BSD 4.2
+.Sh NAME
+.Nm rexecd
+.Nd remote execution server
+.Sh SYNOPSIS
+.Nm rexecd
+.Sh DESCRIPTION
+.Nm Rexecd
+is the server for the 
+.Xr rexec 3
+routine.  The server provides remote execution facilities
+with authentication based on user names and
+passwords.
+.Pp
+.Nm Rexecd
+listens for service requests at the port indicated in
+the ``exec'' service specification; see
+.Xr services 5 .
+When a service request is received the following protocol
+is initiated:
+.Bl -enum
+.It
+The server reads characters from the socket up
+to a NUL
+.Pq Ql \e0
+byte.  The resultant string is
+interpreted as an
+.Tn ASCII
+number, base 10.
+.It 
+If the number received in step 1 is non-zero,
+it is interpreted as the port number of a secondary
+stream to be used for the 
+.Em stderr .
+A second connection is then created to the specified
+port on the client's machine.
+.It
+A NUL terminated user name of at most 16 characters
+is retrieved on the initial socket.
+.It
+A NUL terminated, unencrypted password of at most
+16 characters is retrieved on the initial socket.  
+.It
+A NUL terminated command to be passed to a
+shell is retrieved on the initial socket.  The length of
+the command is limited by the upper bound on the size of
+the system's argument list.  
+.It
+.Nm Rexecd
+then validates the user as is done at login time
+and, if the authentication was successful, changes
+to the user's home directory, and establishes the user
+and group protections of the user.
+If any of these steps fail the connection is
+aborted with a diagnostic message returned.
+.It
+A NUL byte is returned on the initial socket
+and the command line is passed to the normal login
+shell of the user.  The
+shell inherits the network connections established
+by
+.Nm rexecd .
+.El
+.Sh DIAGNOSTICS
+Except for the last one listed below,
+all diagnostic messages are returned on the initial socket,
+after which any network connections are closed.
+An error is indicated by a leading byte with a value of
+1 (0 is returned in step 7 above upon successful completion
+of all the steps prior to the command execution).
+.Pp
+.Bl -tag -width Ds
+.It Sy username too long
+The name is
+longer than 16 characters.
+.It Sy password too long
+The password is longer than 16 characters.
+.It Sy command too long
+The command line passed exceeds the size of the argument
+list (as configured into the system).
+.It Sy Login incorrect.
+No password file entry for the user name existed.
+.It Sy Password incorrect.
+The wrong password was supplied.
+.ne 1i
+.It Sy \&No remote directory.
+The 
+.Xr chdir
+command to the home directory failed.
+.It Sy Try again.
+A
+.Xr fork
+by the server failed.
+.It Sy <shellname>: ...
+The user's login shell could not be started.
+This message is returned
+on the connection associated with the
+.Em stderr ,
+and is not preceded by a flag byte.
+.El
+.Sh SEE ALSO
+.Xr rexec 3
+.Sh BUGS
+Indicating ``Login incorrect'' as opposed to ``Password incorrect''
+is a security breach which allows people to probe a system for users
+with null passwords.
+.Pp
+A facility to allow all data and password exchanges to be encrypted should be
+present.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/rexecd.tproj/rexecd.c b/rexecd.tproj/rexecd.c
new file mode 100644
index 0000000..ec9e009
--- /dev/null
+++ b/rexecd.tproj/rexecd.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)rexecd.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*VARARGS1*/
+int error();
+
+/*
+ * remote execute server:
+ *	username\0
+ *	password\0
+ *	command\0
+ *	data
+ */
+/*ARGSUSED*/
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	struct sockaddr_in from;
+	int fromlen;
+
+	fromlen = sizeof (from);
+	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
+		(void)fprintf(stderr,
+		    "rexecd: getpeername: %s\n", strerror(errno));
+		exit(1);
+	}
+	doit(0, &from);
+}
+
+char	username[20] = "USER=";
+char	homedir[64] = "HOME=";
+char	shell[64] = "SHELL=";
+char	path[sizeof(_PATH_DEFPATH) + sizeof("PATH=")] = "PATH=";
+char	*envinit[] =
+	    {homedir, shell, path, username, 0};
+#ifdef __APPLE__
+extern
+#endif
+char	**environ;
+
+struct	sockaddr_in asin = { AF_INET };
+
+doit(f, fromp)
+	int f;
+	struct sockaddr_in *fromp;
+{
+	char cmdbuf[NCARGS+1], *cp, *namep;
+	char user[16], pass[16];
+	struct passwd *pwd;
+	int s;
+	u_short port;
+	int pv[2], pid, ready, readfrom, cc;
+	char buf[BUFSIZ], sig;
+	int one = 1;
+
+	(void) signal(SIGINT, SIG_DFL);
+	(void) signal(SIGQUIT, SIG_DFL);
+	(void) signal(SIGTERM, SIG_DFL);
+#ifdef DEBUG
+	{ int t = open(_PATH_TTY, 2);
+	  if (t >= 0) {
+		ioctl(t, TIOCNOTTY, (char *)0);
+		(void) close(t);
+	  }
+	}
+#endif
+	dup2(f, 0);
+	dup2(f, 1);
+	dup2(f, 2);
+	(void) alarm(60);
+	port = 0;
+	for (;;) {
+		char c;
+		if (read(f, &c, 1) != 1)
+			exit(1);
+		if (c == 0)
+			break;
+		port = port * 10 + c - '0';
+	}
+	(void) alarm(0);
+	if (port != 0) {
+		s = socket(AF_INET, SOCK_STREAM, 0);
+		if (s < 0)
+			exit(1);
+		if (bind(s, (struct sockaddr *)&asin, sizeof (asin)) < 0)
+			exit(1);
+		(void) alarm(60);
+		fromp->sin_port = htons(port);
+		if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0)
+			exit(1);
+		(void) alarm(0);
+	}
+	getstr(user, sizeof(user), "username");
+	getstr(pass, sizeof(pass), "password");
+	getstr(cmdbuf, sizeof(cmdbuf), "command");
+	setpwent();
+	pwd = getpwnam(user);
+	if (pwd == NULL) {
+		error("Login incorrect.\n");
+		exit(1);
+	}
+	endpwent();
+	if (*pwd->pw_passwd != '\0') {
+		namep = crypt(pass, pwd->pw_passwd);
+		if (strcmp(namep, pwd->pw_passwd)) {
+			error("Password incorrect.\n");
+			exit(1);
+		}
+	}
+	if (chdir(pwd->pw_dir) < 0) {
+		error("No remote directory.\n");
+		exit(1);
+	}
+	(void) write(2, "\0", 1);
+	if (port) {
+		(void) pipe(pv);
+		pid = fork();
+		if (pid == -1)  {
+			error("Try again.\n");
+			exit(1);
+		}
+		if (pid) {
+			(void) close(0); (void) close(1); (void) close(2);
+			(void) close(f); (void) close(pv[1]);
+			readfrom = (1<<s) | (1<<pv[0]);
+			ioctl(pv[1], FIONBIO, (char *)&one);
+			/* should set s nbio! */
+			do {
+				ready = readfrom;
+				(void) select(16, (fd_set *)&ready,
+				    (fd_set *)NULL, (fd_set *)NULL,
+				    (struct timeval *)NULL);
+				if (ready & (1<<s)) {
+					if (read(s, &sig, 1) <= 0)
+						readfrom &= ~(1<<s);
+					else
+						killpg(pid, sig);
+				}
+				if (ready & (1<<pv[0])) {
+					cc = read(pv[0], buf, sizeof (buf));
+					if (cc <= 0) {
+						shutdown(s, 1+1);
+						readfrom &= ~(1<<pv[0]);
+					} else
+						(void) write(s, buf, cc);
+				}
+			} while (readfrom);
+			exit(0);
+		}
+		setpgrp(0, getpid());
+		(void) close(s); (void)close(pv[0]);
+		dup2(pv[1], 2);
+	}
+	if (*pwd->pw_shell == '\0')
+		pwd->pw_shell = _PATH_BSHELL;
+	if (f > 2)
+		(void) close(f);
+	(void) setgid((gid_t)pwd->pw_gid);
+	initgroups(pwd->pw_name, pwd->pw_gid);
+	(void) setuid((uid_t)pwd->pw_uid);
+	(void)strcat(path, _PATH_DEFPATH);
+	environ = envinit;
+	strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
+	strncat(shell, pwd->pw_shell, sizeof(shell)-7);
+	strncat(username, pwd->pw_name, sizeof(username)-6);
+	cp = strrchr(pwd->pw_shell, '/');
+	if (cp)
+		cp++;
+	else
+		cp = pwd->pw_shell;
+	execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
+	perror(pwd->pw_shell);
+	exit(1);
+}
+
+/*VARARGS1*/
+error(fmt, a1, a2, a3)
+	char *fmt;
+	int a1, a2, a3;
+{
+	char buf[BUFSIZ];
+
+	buf[0] = 1;
+	(void) sprintf(buf+1, fmt, a1, a2, a3);
+	(void) write(2, buf, strlen(buf));
+}
+
+getstr(buf, cnt, err)
+	char *buf;
+	int cnt;
+	char *err;
+{
+	char c;
+
+	do {
+		if (read(0, &c, 1) != 1)
+			exit(1);
+		*buf++ = c;
+		if (--cnt == 0) {
+			error("%s too long\n", err);
+			exit(1);
+		}
+	} while (c != 0);
+}
diff --git a/rlogin.tproj/Makefile b/rlogin.tproj/Makefile
new file mode 100644
index 0000000..bd0c481
--- /dev/null
+++ b/rlogin.tproj/Makefile
@@ -0,0 +1,55 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rlogin
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = krb.h
+
+CFILES = des_rw.c kcmd.c krcmd.c rlogin.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble rlogin.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -DCRYPT
+WINDOWS_PB_CFLAGS = -DCRYPT
+PDO_UNIX_PB_CFLAGS = -DCRYPT
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rlogin.tproj/Makefile.postamble b/rlogin.tproj/Makefile.postamble
new file mode 100644
index 0000000..acddb30
--- /dev/null
+++ b/rlogin.tproj/Makefile.postamble
@@ -0,0 +1 @@
+INSTALL_PERMISSIONS = 4755    # If set, 'install' chmod's executable to this
diff --git a/rlogin.tproj/Makefile.preamble b/rlogin.tproj/Makefile.preamble
new file mode 100644
index 0000000..925a5c7
--- /dev/null
+++ b/rlogin.tproj/Makefile.preamble
@@ -0,0 +1,3 @@
+CLEAN_ALL_SUBPROJECTS = YES
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/rlogin.tproj/PB.project b/rlogin.tproj/PB.project
new file mode 100644
index 0000000..2898a5d
--- /dev/null
+++ b/rlogin.tproj/PB.project
@@ -0,0 +1,42 @@
+{
+    FILESTABLE = {
+        CLASSES = (); 
+        C_FILES = (); 
+        H_FILES = (krb.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (des_rw.c, kcmd.c, krcmd.c, rlogin.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, rlogin.1); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-DCRYPT"; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = rlogin; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = "-DCRYPT"; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_MAINNIB = rlogin; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rlogin; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = "-DCRYPT"; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_MAINNIB = rlogin; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rlogin.tproj/des_rw.c b/rlogin.tproj/des_rw.c
new file mode 100644
index 0000000..4e056cf
--- /dev/null
+++ b/rlogin.tproj/des_rw.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)des_rw.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef CRYPT
+#ifdef KERBEROS
+#include <sys/param.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static unsigned char	des_inbuf[10240], storage[10240], *store_ptr;
+static bit_64		*key;
+static u_char		*key_schedule;
+
+/* XXX these should be in a kerberos include file */
+int	krb_net_read __P((int, char *, int));
+#ifdef notdef
+/* XXX too hard to make this work */
+int	des_pcbc_encrypt __P((des_cblock *, des_cblock *, long,
+	    des_key_schedule, des_cblock *, int));
+#endif
+
+/*
+ * NB: These routines will not function properly if NBIO
+ * 	is set
+ */
+
+/*
+ * des_set_key
+ *
+ * Set des encryption/decryption key for use by the des_read and
+ * des_write routines
+ *
+ * The inkey parameter is actually the DES initial vector,
+ * and the insched is the DES Key unwrapped for faster decryption
+ */
+
+void
+des_set_key(inkey, insched)
+	bit_64		*inkey;
+	u_char		*insched;
+{
+	key = inkey;
+	key_schedule = insched;
+}
+
+void
+des_clear_key()
+{
+	bzero((char *) key, sizeof(C_Block));
+	bzero((char *) key_schedule, sizeof(Key_schedule));
+}
+	
+
+int
+des_read(fd, buf, len)
+	int fd;
+	register char *buf;
+	int len;
+{
+	int nreturned = 0;
+	long net_len, rd_len;
+	int nstored = 0;
+
+	if (nstored >= len) {
+		(void) bcopy(store_ptr, buf, len);
+		store_ptr += len;
+		nstored -= len;
+		return(len);
+	} else if (nstored) {
+		(void) bcopy(store_ptr, buf, nstored);
+		nreturned += nstored;
+		buf += nstored;
+		len -= nstored;
+		nstored = 0;
+	}
+	
+	if (krb_net_read(fd, (char *)&net_len, sizeof(net_len)) !=
+	    sizeof(net_len)) {
+		/* XXX can't read enough, pipe
+		   must have closed */
+		return(0);
+	}
+	net_len = ntohl(net_len);
+	if (net_len <= 0 || net_len > sizeof(des_inbuf)) {
+		/* preposterous length; assume out-of-sync; only
+		   recourse is to close connection, so return 0 */
+		return(0);
+	}
+	/* the writer tells us how much real data we are getting, but
+	   we need to read the pad bytes (8-byte boundary) */
+	rd_len = roundup(net_len, 8);
+	if (krb_net_read(fd, (char *)des_inbuf, rd_len) != rd_len) {
+		/* pipe must have closed, return 0 */
+		return(0);
+	}
+	(void) des_pcbc_encrypt(des_inbuf,	/* inbuf */
+			    storage,		/* outbuf */
+			    net_len,		/* length */
+			    key_schedule,	/* DES key */
+			    key,		/* IV */
+			    DECRYPT);		/* direction */
+
+	if(net_len < 8)
+		store_ptr = storage + 8 - net_len;
+	else
+		store_ptr = storage;
+
+	nstored = net_len;
+	if (nstored > len) {
+		(void) bcopy(store_ptr, buf, len);
+		nreturned += len;
+		store_ptr += len;
+		nstored -= len;
+	} else {
+		(void) bcopy(store_ptr, buf, nstored);
+		nreturned += nstored;
+		nstored = 0;
+	}
+	
+	return(nreturned);
+}
+
+static	unsigned char des_outbuf[10240];	/* > longest write */
+
+int
+des_write(fd, buf, len)
+	int fd;
+	char *buf;
+	int len;
+{
+	static	int	seeded = 0;
+	static	char	garbage_buf[8];
+	long net_len, garbage;
+
+	if(len < 8) {
+		if(!seeded) {
+			seeded = 1;
+			srandom((int) time((long *)0));
+		}
+		garbage = random();
+		/* insert random garbage */
+		(void) bcopy(&garbage, garbage_buf, MIN(sizeof(long),8));
+		/* this "right-justifies" the data in the buffer */
+		(void) bcopy(buf, garbage_buf + 8 - len, len);
+	}
+	/* pcbc_encrypt outputs in 8-byte (64 bit) increments */
+
+	(void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf,
+			    des_outbuf,
+			    (len < 8) ? 8 : len,
+			    key_schedule,	/* DES key */
+			    key,		/* IV */
+			    ENCRYPT);
+
+	/* tell the other end the real amount, but send an 8-byte padded
+	   packet */
+	net_len = htonl(len);
+	(void) write(fd, &net_len, sizeof(net_len));
+	(void) write(fd, des_outbuf, roundup(len,8));
+	return(len);
+}
+#endif /* KERBEROS */
+#endif /* CRYPT */
diff --git a/rlogin.tproj/kcmd.c b/rlogin.tproj/kcmd.c
new file mode 100644
index 0000000..1482dda
--- /dev/null
+++ b/rlogin.tproj/kcmd.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(__APPLE__) || defined(KERBEROS)
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include <kerberosIV/kparse.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "krb.h"
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#define	START_PORT	5120	 /* arbitrary */
+
+int	getport __P((int *));
+
+int
+kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm,
+    cred, schedule, msg_data, laddr, faddr, authopts)
+	int *sock;
+	char **ahost;
+	u_short rport;
+	char *locuser, *remuser, *cmd;
+	int *fd2p;
+	KTEXT ticket;
+	char *service;
+	char *realm;
+	CREDENTIALS *cred;
+	Key_schedule schedule;
+	MSG_DAT *msg_data;
+	struct sockaddr_in *laddr, *faddr;
+	long authopts;
+{
+	int s, timo = 1, pid;
+	long oldmask;
+	struct sockaddr_in sin, from;
+	char c;
+#ifdef ATHENA_COMPAT
+	int lport = IPPORT_RESERVED - 1;
+#else
+	int lport = START_PORT;
+#endif
+	struct hostent *hp;
+	int rc;
+	char *host_save;
+	int status;
+
+	pid = getpid();
+	hp = gethostbyname(*ahost);
+	if (hp == NULL) {
+		/* fprintf(stderr, "%s: unknown host\n", *ahost); */
+		return (-1);
+	}
+
+	host_save = malloc(strlen(hp->h_name) + 1);
+	strcpy(host_save, hp->h_name);
+	*ahost = host_save;
+
+#ifdef KERBEROS
+	/* If realm is null, look up from table */
+	if (realm == NULL || realm[0] == '\0')
+		realm = krb_realmofhost(host_save);
+#endif /* KERBEROS */
+
+	oldmask = sigblock(sigmask(SIGURG));
+	for (;;) {
+		s = getport(&lport);
+		if (s < 0) {
+			if (errno == EAGAIN)
+				fprintf(stderr,
+					"kcmd(socket): All ports in use\n");
+			else
+				perror("kcmd: socket");
+			sigsetmask(oldmask);
+			return (-1);
+		}
+		fcntl(s, F_SETOWN, pid);
+		sin.sin_family = hp->h_addrtype;
+#if defined(ultrix) || defined(sun)
+		bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
+#else
+		bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
+#endif
+		sin.sin_port = rport;
+		if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+			break;
+		(void) close(s);
+		if (errno == EADDRINUSE) {
+			lport--;
+			continue;
+		}
+		/*
+		 * don't wait very long for Kerberos rcmd.
+		 */
+		if (errno == ECONNREFUSED && timo <= 4) {
+			/* sleep(timo); don't wait at all here */
+			timo *= 2;
+			continue;
+		}
+#if !(defined(ultrix) || defined(sun))
+		if (hp->h_addr_list[1] != NULL) {
+			int oerrno = errno;
+
+			fprintf(stderr,
+			    "kcmd: connect to address %s: ",
+			    inet_ntoa(sin.sin_addr));
+			errno = oerrno;
+			perror(NULL);
+			hp->h_addr_list++;
+			bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
+			    hp->h_length);
+			fprintf(stderr, "Trying %s...\n",
+				inet_ntoa(sin.sin_addr));
+			continue;
+		}
+#endif /* !(defined(ultrix) || defined(sun)) */
+		if (errno != ECONNREFUSED)
+			perror(hp->h_name);
+		sigsetmask(oldmask);
+		return (-1);
+	}
+	lport--;
+	if (fd2p == 0) {
+		write(s, "", 1);
+		lport = 0;
+	} else {
+		char num[8];
+		int s2 = getport(&lport), s3;
+		int len = sizeof(from);
+
+		if (s2 < 0) {
+			status = -1;
+			goto bad;
+		}
+		listen(s2, 1);
+		(void) sprintf(num, "%d", lport);
+		if (write(s, num, strlen(num) + 1) != strlen(num) + 1) {
+			perror("kcmd(write): setting up stderr");
+			(void) close(s2);
+			status = -1;
+			goto bad;
+		}
+		s3 = accept(s2, (struct sockaddr *)&from, &len);
+		(void) close(s2);
+		if (s3 < 0) {
+			perror("kcmd:accept");
+			lport = 0;
+			status = -1;
+			goto bad;
+		}
+		*fd2p = s3;
+		from.sin_port = ntohs((u_short)from.sin_port);
+		if (from.sin_family != AF_INET ||
+		    from.sin_port >= IPPORT_RESERVED) {
+			fprintf(stderr,
+			 "kcmd(socket): protocol failure in circuit setup.\n");
+			status = -1;
+			goto bad2;
+		}
+	}
+	/*
+	 * Kerberos-authenticated service.  Don't have to send locuser,
+	 * since its already in the ticket, and we'll extract it on
+	 * the other side.
+	 */
+	/* (void) write(s, locuser, strlen(locuser)+1); */
+
+	/* set up the needed stuff for mutual auth, but only if necessary */
+	if (authopts & KOPT_DO_MUTUAL) {
+		int sin_len;
+		*faddr = sin;
+
+		sin_len = sizeof(struct sockaddr_in);
+		if (getsockname(s, (struct sockaddr *)laddr, &sin_len) < 0) {
+			perror("kcmd(getsockname)");
+			status = -1;
+			goto bad2;
+		}
+	}
+#ifdef KERBEROS
+	if ((status = krb_sendauth(authopts, s, ticket, service, *ahost,
+			       realm, (unsigned long) getpid(), msg_data,
+			       cred, schedule,
+			       laddr,
+			       faddr,
+			       "KCMDV0.1")) != KSUCCESS)
+		goto bad2;
+#endif /* KERBEROS */
+
+	(void) write(s, remuser, strlen(remuser)+1);
+	(void) write(s, cmd, strlen(cmd)+1);
+
+	if ((rc = read(s, &c, 1)) != 1) {
+		if (rc == -1)
+			perror(*ahost);
+		else
+			fprintf(stderr,"kcmd: bad connection with remote host\n");
+		status = -1;
+		goto bad2;
+	}
+	if (c != '\0') {
+		while (read(s, &c, 1) == 1) {
+			(void) write(2, &c, 1);
+			if (c == '\n')
+				break;
+		}
+		status = -1;
+		goto bad2;
+	}
+	sigsetmask(oldmask);
+	*sock = s;
+	return (KSUCCESS);
+bad2:
+	if (lport)
+		(void) close(*fd2p);
+bad:
+	(void) close(s);
+	sigsetmask(oldmask);
+	return (status);
+}
+
+int
+getport(alport)
+	int *alport;
+{
+	struct sockaddr_in sin;
+	int s;
+
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = INADDR_ANY;
+	s = socket(AF_INET, SOCK_STREAM, 0);
+	if (s < 0)
+		return (-1);
+	for (;;) {
+		sin.sin_port = htons((u_short)*alport);
+		if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+			return (s);
+		if (errno != EADDRINUSE) {
+			(void) close(s);
+			return (-1);
+		}
+		(*alport)--;
+#ifdef ATHENA_COMPAT
+		if (*alport == IPPORT_RESERVED/2) {
+#else
+		if (*alport == IPPORT_RESERVED) {
+#endif
+			(void) close(s);
+			errno = EAGAIN;		/* close */
+			return (-1);
+		}
+	}
+}
+
+#endif /* !NeXT || KERBEROS */
diff --git a/rlogin.tproj/krb.h b/rlogin.tproj/krb.h
new file mode 100644
index 0000000..10b6dca
--- /dev/null
+++ b/rlogin.tproj/krb.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)krb.h	8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * XXX
+ * These should be in a kerberos include file.
+ */
+void	 des_clear_key __P(());
+int	 des_read __P((int, char *, int));
+void	 des_set_key __P((C_Block, Key_schedule));
+int	 des_write __P((int, char *, int));
+int	 krb_net_read __P((int, char *, int));
+char	*krb_realmofhost __P((char *));
+int	 krb_sendauth __P((long, int, KTEXT, char *, char *, char *,
+	    u_long, MSG_DAT *, CREDENTIALS *, Key_schedule,
+	    struct sockaddr_in *, struct sockaddr_in *, char *));
+int	 krcmd __P((char **, u_short, char *, char *, int *, char *));
+int	 krcmd_mutual __P((char **, u_short, char *, char *, int *,
+	    char *, CREDENTIALS *, Key_schedule));
diff --git a/rlogin.tproj/krcmd.c b/rlogin.tproj/krcmd.c
new file mode 100644
index 0000000..cdbba26
--- /dev/null
+++ b/rlogin.tproj/krcmd.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/*
+ *	$Source: /cvs/Darwin/Commands/NeXT/network_cmds/rlogin.tproj/krcmd.c,v $
+ *	$Header: /mit/kerberos/ucb/mit/kcmd/RCS/krcmd.c,v 5.1
+ *		89/07/25 15:38:44 kfall Exp Locker: kfall $
+ * static char *rcsid_kcmd_c =
+ * "$Header: /mit/kerberos/ucb/mit/kcmd/RCS/krcmd.c,v 5.1 89/07/25 15:38:44
+ *	kfall Exp Locker: kfall $";
+ */
+
+#ifdef KERBEROS
+#include <sys/types.h>
+#ifdef CRYPT
+#include <sys/socket.h>
+#endif
+
+#include <netinet/in.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+
+#include <stdio.h>
+
+#define	SERVICE_NAME	"rcmd"
+
+int	kcmd __P((int *, char **, u_short, char *, char *, char *, int *,
+	    KTEXT, char *, char *, CREDENTIALS *, Key_schedule, MSG_DAT *,
+	    struct sockaddr_in *, struct sockaddr_in *, long));
+
+/*
+ * krcmd: simplified version of Athena's "kcmd"
+ *	returns a socket attached to the destination, -1 or krb error on error 
+ *	if fd2p is non-NULL, another socket is filled in for it
+ */
+
+int
+krcmd(ahost, rport, remuser, cmd, fd2p, realm)
+	char	**ahost;
+	u_short	rport;
+	char	*remuser, *cmd;
+	int	*fd2p;
+	char	*realm;
+{
+	int		sock = -1, err = 0;
+	KTEXT_ST	ticket;
+	long		authopts = 0L;
+
+	err = kcmd(
+		&sock,
+		ahost,
+		rport,
+		NULL,	/* locuser not used */
+		remuser,
+		cmd,
+		fd2p,
+		&ticket,
+		SERVICE_NAME,
+		realm,
+		(CREDENTIALS *)  NULL,		/* credentials not used */
+		(bit_64 *) NULL,		/* key schedule not used */
+		(MSG_DAT *) NULL,		/* MSG_DAT not used */
+		(struct sockaddr_in *) NULL,	/* local addr not used */
+		(struct sockaddr_in *) NULL,	/* foreign addr not used */
+		authopts
+	);
+
+	if (err > KSUCCESS && err < MAX_KRB_ERRORS) {
+		fprintf(stderr, "krcmd: %s\n", krb_err_txt[err]);
+		return(-1);
+	}
+	if (err < 0)
+		return(-1);
+	return(sock);
+}
+
+#ifdef CRYPT
+int
+krcmd_mutual(ahost, rport, remuser, cmd, fd2p, realm, cred, sched)
+	char		**ahost;
+	u_short		rport;
+	char		*remuser, *cmd;
+	int		*fd2p;
+	char		*realm;
+	CREDENTIALS	*cred;
+	Key_schedule	sched;
+{
+	int		sock, err;
+	KTEXT_ST	ticket;
+	MSG_DAT		msg_dat;
+	struct sockaddr_in	laddr, faddr;
+	long authopts = KOPT_DO_MUTUAL;
+
+	err = kcmd(
+		&sock,
+		ahost,
+		rport,
+		NULL,	/* locuser not used */
+		remuser,
+		cmd,
+		fd2p,
+		&ticket,
+		SERVICE_NAME,
+		realm,
+		cred,		/* filled in */
+		sched,		/* filled in */
+		&msg_dat,	/* filled in */
+		&laddr,		/* filled in */
+		&faddr,		/* filled in */
+		authopts
+	);
+
+	if (err > KSUCCESS && err < MAX_KRB_ERRORS) {
+		fprintf(stderr, "krcmd_mutual: %s\n", krb_err_txt[err]);
+		return(-1);
+	}
+
+	if (err < 0)
+		return (-1);
+	return(sock);
+}
+#endif /* CRYPT */
+#endif /* KERBEROS */
diff --git a/rlogin.tproj/rlogin.1 b/rlogin.tproj/rlogin.1
new file mode 100644
index 0000000..979658a
--- /dev/null
+++ b/rlogin.tproj/rlogin.1
@@ -0,0 +1,188 @@
+.\" Copyright (c) 1983, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)rlogin.1	8.2 (Berkeley) 4/29/95
+.\"
+.Dd April 29, 1995
+.Dt RLOGIN 1
+.Os BSD 4.2
+.Sh NAME
+.Nm rlogin
+.Nd remote login
+.Sh SYNOPSIS
+.Nm rlogin
+.Op Fl 8EKLdx
+.Op Fl e Ar char
+.Op Fl k Ar realm
+.Op Fl l Ar username
+.Ar host
+.Nm rlogin
+.Op Fl 8EKLdx
+.Op Fl e Ar char
+.Op Fl k Ar realm
+.Ar username@host
+.Sh DESCRIPTION
+.Nm Rlogin
+starts a terminal session on a remote host
+.Ar host  .
+.Pp
+.Nm Rlogin
+first attempts to use the Kerberos authorization mechanism, described below.
+If the remote host does not supporting Kerberos the standard Berkeley
+.Pa rhosts
+authorization mechanism is used.
+The options are as follows:
+.Bl -tag -width flag
+.It Fl 8
+The
+.Fl 8
+option allows an eight-bit input data path at all times; otherwise
+parity bits are stripped except when the remote side's stop and start
+characters are other than
+^S/^Q .
+.It Fl E
+The
+.Fl E
+option stops any character from being recognized as an escape character.
+When used with the
+.Fl 8
+option, this provides a completely transparent connection.
+.It Fl K
+The
+.Fl K
+option turns off all Kerberos authentication.
+.It Fl L
+The
+.Fl L
+option allows the rlogin session to be run in ``litout'' (see
+.Xr tty 4 )
+mode.
+.It Fl d
+The
+.Fl d
+option turns on socket debugging (see
+.Xr setsockopt 2 )
+on the TCP sockets used for communication with the remote host.
+.It Fl e
+The
+.Fl e
+option allows user specification of the escape character, which is
+``~'' by default.
+This specification may be as a literal character, or as an octal
+value in the form \ennn.
+.It Fl k
+The
+.FL k
+option requests rlogin to obtain tickets for the remote host
+in realm
+.Ar realm
+instead of the remote host's realm as determined by
+.Xr krb_realmofhost  3  .
+.It Fl x
+The
+.Fl x
+option turns on
+.Tn DES
+encryption for all data passed via the
+rlogin session.
+This may impact response time and
+.Tn CPU
+utilization, but provides
+increased security.
+.El
+.Pp
+A line of the form ``<escape char>.'' disconnects from the remote host.
+Similarly, the line ``<escape char>^Z'' will suspend the
+.Nm rlogin
+session, and ``<escape char><delayed-suspend char>'' suspends the
+send portion of the rlogin, but allows output from the remote system.
+By default, the tilde (``~'') character is the escape character, and
+normally control-Y (``^Y'') is the delayed-suspend character.
+.Pp
+All echoing takes place at the remote site, so that (except for delays)
+the
+.Nm rlogin
+is transparent.
+Flow control via ^S/^Q and flushing of input and output on interrupts
+are handled properly.
+.Sh KERBEROS AUTHENTICATION
+Each user may have a private authorization list in the file
+.Pa .klogin
+in their home directory.
+Each line in this file should contain a Kerberos principal name of the
+form
+.Ar principal.instance@realm  .
+If the originating user is authenticated to one of the principals named
+in
+.Pa .klogin ,
+access is granted to the account.
+The principal
+.Ar accountname.@localrealm
+is granted access if
+there is no
+.Pa .klogin
+file.
+Otherwise a login and password will be prompted for on the remote machine
+as in
+.Xr login  1  .
+To avoid certain security problems, the
+.Pa .klogin
+file must be owned by
+the remote user.
+.Pp
+If Kerberos authentication fails, a warning message is printed and the
+standard Berkeley
+.Nm rlogin
+is used instead.
+.Sh ENVIRONMENT
+The following environment variable is utilized by
+.Nm rlogin :
+.Bl -tag -width TERM
+.It Ev TERM
+Determines the user's terminal type.
+.El
+.Sh SEE ALSO
+.Xr rsh 1 ,
+.Xr kerberos 3 ,
+.Xr krb_sendauth 3 ,
+.Xr krb_realmofhost 3
+.Sh HISTORY
+The
+.Nm rlogin
+command appeared in
+.Bx 4.2 .
+.Sh BUGS
+.Nm Rlogin
+will be replaced by
+.Xr telnet  1
+in the near future.
+.Pp
+More of the environment should be propagated.
diff --git a/rlogin.tproj/rlogin.c b/rlogin.tproj/rlogin.c
new file mode 100644
index 0000000..b819699
--- /dev/null
+++ b/rlogin.tproj/rlogin.c
@@ -0,0 +1,1011 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/*
+ * rlogin - remote login
+ */
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <termios.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef KERBEROS
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+
+#include "krb.h"
+
+CREDENTIALS cred;
+Key_schedule schedule;
+int use_kerberos = 1, doencrypt;
+char dst_realm_buf[REALM_SZ], *dest_realm = NULL;
+#endif
+
+#ifndef TIOCPKT_WINDOW
+#define	TIOCPKT_WINDOW	0x80
+#endif
+
+/* concession to Sun */
+#ifndef SIGUSR1
+#define	SIGUSR1	30
+#endif
+
+int eight, litout, rem;
+
+int noescape;
+u_char escapechar = '~';
+
+#ifdef OLDSUN
+struct winsize {
+	unsigned short ws_row, ws_col;
+	unsigned short ws_xpixel, ws_ypixel;
+};
+#else
+#define	get_window_size(fd, wp)	ioctl(fd, TIOCGWINSZ, wp)
+#endif
+struct	winsize winsize;
+
+void		catch_child __P((int));
+void		copytochild __P((int));
+__dead void	doit __P((sigset_t *));
+__dead void	done __P((int));
+void		echo __P((char));
+u_int		getescape __P((char *));
+static void	do_exit __P((int));
+void		lostpeer __P((int));
+void		mode __P((int));
+void		msg __P((char *));
+void		oob __P((int));
+int		reader __P((sigset_t *));
+void		sendwindow __P((void));
+void		setsignal __P((int));
+int		speed __P((int));
+void		sigwinch __P((int));
+void		stop __P((char));
+__dead void	usage __P((void));
+void		writer __P((void));
+void		writeroob __P((int));
+
+#ifdef	KERBEROS
+void		warning __P((const char *, ...));
+#endif
+#ifdef OLDSUN
+int		get_window_size __P((int, struct winsize *));
+#endif
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct passwd *pw;
+	struct servent *sp;
+	sigset_t smask;
+	uid_t uid;
+	int argoff, ch, dflag, one;
+	char *host, *p, *user, term[1024];
+	struct sigaction sa;
+
+	argoff = dflag = 0;
+	one = 1;
+	host = user = NULL;
+
+	if (p = strrchr(argv[0], '/'))
+		++p;
+	else
+		p = argv[0];
+
+	if (strcmp(p, "rlogin") != 0)
+		host = p;
+
+	/* handle "rlogin host flags" */
+	if (!host && argc > 2 && argv[1][0] != '-') {
+		host = argv[1];
+		argoff = 1;
+	}
+
+#ifdef KERBEROS
+#define	OPTIONS	"8EKLde:k:l:x"
+#else
+#define	OPTIONS	"8EKLde:l:"
+#endif
+	while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != EOF)
+		switch(ch) {
+		case '8':
+			eight = 1;
+			break;
+		case 'E':
+			noescape = 1;
+			break;
+		case 'K':
+#ifdef KERBEROS
+			use_kerberos = 0;
+#endif
+			break;
+		case 'L':
+			litout = 1;
+			break;
+		case 'd':
+			dflag = 1;
+			break;
+		case 'e':
+			noescape = 0;
+			escapechar = getescape(optarg);
+			break;
+#ifdef KERBEROS
+		case 'k':
+			dest_realm = dst_realm_buf;
+			(void)strncpy(dest_realm, optarg, REALM_SZ);
+			break;
+#endif
+		case 'l':
+			user = optarg;
+			break;
+#ifdef CRYPT
+#ifdef KERBEROS
+		case 'x':
+			doencrypt = 1;
+			des_set_key(cred.session, schedule);
+			break;
+#endif
+#endif
+		case '?':
+		default:
+			usage();
+		}
+	optind += argoff;
+	argc -= optind;
+	argv += optind;
+
+	/* if haven't gotten a host yet, do so */
+	if (!host && !(host = *argv++))
+		usage();
+
+	if (*argv)
+		usage();
+
+	if (!(pw = getpwuid(uid = getuid())))
+		errx(1, "unknown user id.");
+	/* Accept user1@host format, though "-l user2" overrides user1 */
+	p = strchr(host, '@');
+	if (p) {
+		*p = '\0';
+		if (!user && p > host)
+			user = host;
+		host = p + 1;
+		if (*host == '\0')
+			usage();
+	}
+	if (!user)
+		user = pw->pw_name;
+
+	sp = NULL;
+#ifdef KERBEROS
+	if (use_kerberos) {
+		sp = getservbyname((doencrypt ? "eklogin" : "klogin"), "tcp");
+		if (sp == NULL) {
+			use_kerberos = 0;
+			warning("can't get entry for %s/tcp service",
+			    doencrypt ? "eklogin" : "klogin");
+		}
+	}
+#endif
+	if (sp == NULL)
+		sp = getservbyname("login", "tcp");
+	if (sp == NULL)
+		errx(1, "login/tcp: unknown service.");
+
+	(void)snprintf(term, sizeof(term), "%s/%d",
+			((p = getenv("TERM")) ? p : "network"),
+			speed(0));
+
+	(void)get_window_size(0, &winsize);
+
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags = SA_RESTART;
+	sa.sa_handler = lostpeer;
+	(void)sigaction(SIGPIPE, &sa, (struct sigaction *) 0);
+	/* will use SIGUSR1 for window size hack, so hold it off */
+	sigemptyset(&smask);
+	sigaddset(&smask, SIGURG);
+	sigaddset(&smask, SIGUSR1);
+	(void)sigprocmask(SIG_SETMASK, &smask, &smask);
+	/*
+	 * We set SIGURG and SIGUSR1 below so that an
+	 * incoming signal will be held pending rather than being
+	 * discarded. Note that these routines will be ready to get
+	 * a signal by the time that they are unblocked below.
+	 */
+	sa.sa_handler = copytochild;
+	(void)sigaction(SIGURG, &sa, (struct sigaction *) 0);
+	sa.sa_handler = writeroob;
+	(void)sigaction(SIGUSR1, &sa, (struct sigaction *) 0);
+
+#ifdef KERBEROS
+try_connect:
+	if (use_kerberos) {
+		struct hostent *hp;
+
+		/* Fully qualify hostname (needed for krb_realmofhost). */
+		hp = gethostbyname(host);
+		if (hp != NULL && !(host = strdup(hp->h_name)))
+			errx(1, "%s", strerror(ENOMEM));
+
+		rem = KSUCCESS;
+		errno = 0;
+		if (dest_realm == NULL)
+			dest_realm = krb_realmofhost(host);
+
+#ifdef CRYPT
+		if (doencrypt)
+			rem = krcmd_mutual(&host, sp->s_port, user, term, 0,
+			    dest_realm, &cred, schedule);
+		else
+#endif /* CRYPT */
+			rem = krcmd(&host, sp->s_port, user, term, 0,
+			    dest_realm);
+		if (rem < 0) {
+			use_kerberos = 0;
+			sp = getservbyname("login", "tcp");
+			if (sp == NULL)
+				errx(1, "unknown service login/tcp.");
+			if (errno == ECONNREFUSED)
+				warning("remote host doesn't support Kerberos");
+			if (errno == ENOENT)
+				warning("can't provide Kerberos auth data");
+			goto try_connect;
+		}
+	} else {
+#ifdef CRYPT
+		if (doencrypt)
+			errx(1, "the -x flag requires Kerberos authentication.");
+#endif /* CRYPT */
+		rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);
+	}
+#else
+	rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);
+#endif /* KERBEROS */
+
+	if (rem < 0)
+		exit(1);
+
+	if (dflag &&
+	    setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0)
+		warn("setsockopt DEBUG (ignored)");
+	one = IPTOS_LOWDELAY;
+	if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one, sizeof(int)) < 0)
+		warn("setsockopt TOS (ignored)");
+
+	(void)setuid(uid);
+	doit(&smask);
+	/*NOTREACHED*/
+}
+
+#if BSD >= 198810
+int
+speed(fd)
+	int fd;
+{
+	struct termios tt;
+
+	(void)tcgetattr(fd, &tt);
+
+	return ((int) cfgetispeed(&tt));
+}
+#else
+int    speeds[] = {	/* for older systems, B0 .. EXTB */
+	0, 50, 75, 110,
+	134, 150, 200, 300,
+	600, 1200, 1800, 2400,
+	4800, 9600, 19200, 38400
+};
+
+int
+speed(fd)
+	int fd;
+{
+	struct termios tt;
+
+	(void)tcgetattr(fd, &tt);
+
+	return (speeds[(int)cfgetispeed(&tt)]);
+}
+#endif
+
+pid_t child;
+struct termios deftt;
+struct termios nott;
+
+void
+doit(smask)
+	sigset_t *smask;
+{
+	int i;
+	struct sigaction sa;
+
+	for (i = 0; i < NCCS; i++)
+		nott.c_cc[i] = _POSIX_VDISABLE;
+	tcgetattr(0, &deftt);
+	nott.c_cc[VSTART] = deftt.c_cc[VSTART];
+	nott.c_cc[VSTOP] = deftt.c_cc[VSTOP];
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags = SA_RESTART;
+	sa.sa_handler = SIG_IGN;
+	(void)sigaction(SIGINT, &sa, (struct sigaction *) 0);
+	setsignal(SIGHUP);
+	setsignal(SIGQUIT);
+	child = fork();
+	if (child == -1) {
+		warn("fork");
+		done(1);
+	}
+	if (child == 0) {
+		mode(1);
+		if (reader(smask) == 0) {
+			msg("connection closed.");
+			exit(0);
+		}
+		sleep(1);
+		msg("\007connection closed.");
+		exit(1);
+	}
+
+	/*
+	 * We may still own the socket, and may have a pending SIGURG (or might
+	 * receive one soon) that we really want to send to the reader.  When
+	 * one of these comes in, the trap copytochild simply copies such
+	 * signals to the child. We can now unblock SIGURG and SIGUSR1
+	 * that were set above.
+	 */
+	(void)sigprocmask(SIG_SETMASK, smask, (sigset_t *) 0);
+	sa.sa_handler = catch_child;
+	(void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
+	writer();
+	msg("closed connection.");
+	done(0);
+}
+
+/* trap a signal, unless it is being ignored. */
+void
+setsignal(sig)
+	int sig;
+{
+	struct sigaction sa;
+	sigset_t sigs;
+
+	sigemptyset(&sigs);
+	sigaddset(&sigs, sig);
+	sigprocmask(SIG_BLOCK, &sigs, &sigs);
+
+	sigemptyset(&sa.sa_mask);
+	sa.sa_handler = do_exit;
+	sa.sa_flags = SA_RESTART;
+	(void)sigaction(sig, &sa, &sa);
+	if (sa.sa_handler == SIG_IGN)
+		(void)sigaction(sig, &sa, (struct sigaction *) 0);
+
+	(void)sigprocmask(SIG_SETMASK, &sigs, (sigset_t *) 0);
+}
+
+__dead void
+done(status)
+	int status;
+{
+	pid_t w;
+	int wstatus;
+	struct sigaction sa;
+
+	mode(0);
+	if (child > 0) {
+		/* make sure catch_child does not snap it up */
+		sigemptyset(&sa.sa_mask);
+		sa.sa_handler = SIG_DFL;
+		sa.sa_flags = 0;
+		(void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
+		if (kill(child, SIGKILL) >= 0)
+			while ((w = wait(&wstatus)) > 0 && w != child)
+				continue;
+	}
+	exit(status);
+}
+
+int dosigwinch;
+
+/*
+ * This is called when the reader process gets the out-of-band (urgent)
+ * request to turn on the window-changing protocol.
+ */
+void
+writeroob(signo)
+	int signo;
+{
+	struct sigaction sa;
+
+	if (dosigwinch == 0) {
+		sendwindow();
+		sigemptyset(&sa.sa_mask);
+		sa.sa_handler = sigwinch;
+		sa.sa_flags = SA_RESTART;
+		(void)sigaction(SIGWINCH, &sa, (struct sigaction *) 0);
+	}
+	dosigwinch = 1;
+}
+
+void
+catch_child(signo)
+	int signo;
+{
+	int status;
+	pid_t pid;
+
+	for (;;) {
+		pid = waitpid(-1, &status, WNOHANG|WUNTRACED);
+		if (pid == 0)
+			return;
+		/* if the child (reader) dies, just quit */
+		if (pid < 0 || (pid == child && !WIFSTOPPED(status)))
+			done(WEXITSTATUS(status) | WTERMSIG(status));
+	}
+	/* NOTREACHED */
+}
+
+/*
+ * writer: write to remote: 0 -> line.
+ * ~.				terminate
+ * ~^Z				suspend rlogin process.
+ * ~<delayed-suspend char>	suspend rlogin process, but leave reader alone.
+ */
+void
+writer()
+{
+	register int bol, local, n;
+	char c;
+
+	bol = 1;			/* beginning of line */
+	local = 0;
+	for (;;) {
+		n = read(STDIN_FILENO, &c, 1);
+		if (n <= 0) {
+			if (n < 0 && errno == EINTR)
+				continue;
+			break;
+		}
+		/*
+		 * If we're at the beginning of the line and recognize a
+		 * command character, then we echo locally.  Otherwise,
+		 * characters are echo'd remotely.  If the command character
+		 * is doubled, this acts as a force and local echo is
+		 * suppressed.
+		 */
+		if (bol) {
+			bol = 0;
+			if (!noescape && c == escapechar) {
+				local = 1;
+				continue;
+			}
+		} else if (local) {
+			local = 0;
+			if (c == '.' || c == deftt.c_cc[VEOF]) {
+				echo(c);
+				break;
+			}
+			if (c == deftt.c_cc[VSUSP] || c == deftt.c_cc[VDSUSP]) {
+				bol = 1;
+				echo(c);
+				stop(c);
+				continue;
+			}
+			if (c != escapechar)
+#ifdef CRYPT
+#ifdef KERBEROS
+				if (doencrypt)
+					(void)des_write(rem,
+					    (char *)&escapechar, 1);
+				else
+#endif
+#endif
+					(void)write(rem, &escapechar, 1);
+		}
+
+#ifdef CRYPT
+#ifdef KERBEROS
+		if (doencrypt) {
+			if (des_write(rem, &c, 1) == 0) {
+				msg("line gone");
+				break;
+			}
+		} else
+#endif
+#endif
+			if (write(rem, &c, 1) == 0) {
+				msg("line gone");
+				break;
+			}
+		bol = c == deftt.c_cc[VKILL] || c == deftt.c_cc[VEOF] ||
+		    c == deftt.c_cc[VINTR] || c == deftt.c_cc[VSUSP] ||
+		    c == '\r' || c == '\n';
+	}
+}
+
+void
+#if __STDC__
+echo(register char c)
+#else
+echo(c)
+	register char c;
+#endif
+{
+	register char *p;
+	char buf[8];
+
+	p = buf;
+	c &= 0177;
+	*p++ = escapechar;
+	if (c < ' ') {
+		*p++ = '^';
+		*p++ = c + '@';
+	} else if (c == 0177) {
+		*p++ = '^';
+		*p++ = '?';
+	} else
+		*p++ = c;
+	*p++ = '\r';
+	*p++ = '\n';
+	(void)write(STDOUT_FILENO, buf, p - buf);
+}
+
+void
+#if __STDC__
+stop(char cmdc)
+#else
+stop(cmdc)
+	char cmdc;
+#endif
+{
+	struct sigaction sa;
+
+	mode(0);
+	sigemptyset(&sa.sa_mask);
+	sa.sa_handler = SIG_IGN;
+	sa.sa_flags = SA_RESTART;
+	(void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
+	(void)kill(cmdc == deftt.c_cc[VSUSP] ? 0 : getpid(), SIGTSTP);
+	sa.sa_handler = catch_child;
+	(void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
+	mode(1);
+	sigwinch(0);			/* check for size changes */
+}
+
+void
+sigwinch(signo)
+	int signo;
+{
+	struct winsize ws;
+
+	if (dosigwinch && get_window_size(0, &ws) == 0 &&
+	    memcmp(&ws, &winsize, sizeof(ws))) {
+		winsize = ws;
+		sendwindow();
+	}
+}
+
+/*
+ * Send the window size to the server via the magic escape
+ */
+void
+sendwindow()
+{
+	struct winsize *wp;
+	char obuf[4 + sizeof (struct winsize)];
+
+	wp = (struct winsize *)(obuf+4);
+	obuf[0] = 0377;
+	obuf[1] = 0377;
+	obuf[2] = 's';
+	obuf[3] = 's';
+	wp->ws_row = htons(winsize.ws_row);
+	wp->ws_col = htons(winsize.ws_col);
+	wp->ws_xpixel = htons(winsize.ws_xpixel);
+	wp->ws_ypixel = htons(winsize.ws_ypixel);
+
+#ifdef CRYPT
+#ifdef KERBEROS
+	if(doencrypt)
+		(void)des_write(rem, obuf, sizeof(obuf));
+	else
+#endif
+#endif
+		(void)write(rem, obuf, sizeof(obuf));
+}
+
+/*
+ * reader: read from remote: line -> 1
+ */
+#define	READING	1
+#define	WRITING	2
+
+jmp_buf rcvtop;
+pid_t ppid;
+int rcvcnt, rcvstate;
+char rcvbuf[8 * 1024];
+
+void
+oob(signo)
+	int signo;
+{
+	struct termios tt;
+	int atmark, n, out, rcvd;
+	char waste[BUFSIZ], mark;
+
+	out = O_RDWR;
+	rcvd = 0;
+	while (recv(rem, &mark, 1, MSG_OOB) < 0) {
+		switch (errno) {
+		case EWOULDBLOCK:
+			/*
+			 * Urgent data not here yet.  It may not be possible
+			 * to send it yet if we are blocked for output and
+			 * our input buffer is full.
+			 */
+			if (rcvcnt < sizeof(rcvbuf)) {
+				n = read(rem, rcvbuf + rcvcnt,
+				    sizeof(rcvbuf) - rcvcnt);
+				if (n <= 0)
+					return;
+				rcvd += n;
+			} else {
+				n = read(rem, waste, sizeof(waste));
+				if (n <= 0)
+					return;
+			}
+			continue;
+		default:
+			return;
+		}
+	}
+	if (mark & TIOCPKT_WINDOW) {
+		/* Let server know about window size changes */
+		(void)kill(ppid, SIGUSR1);
+	}
+	if (!eight && (mark & TIOCPKT_NOSTOP)) {
+		tcgetattr(0, &tt);
+		tt.c_iflag &= ~(IXON | IXOFF);
+		tt.c_cc[VSTOP] = _POSIX_VDISABLE;
+		tt.c_cc[VSTART] = _POSIX_VDISABLE;
+		tcsetattr(0, TCSANOW, &tt);
+	}
+	if (!eight && (mark & TIOCPKT_DOSTOP)) {
+		tcgetattr(0, &tt);
+		tt.c_iflag |= (IXON|IXOFF);
+		tt.c_cc[VSTOP] = deftt.c_cc[VSTOP];
+		tt.c_cc[VSTART] = deftt.c_cc[VSTART];
+		tcsetattr(0, TCSANOW, &tt);
+	}
+	if (mark & TIOCPKT_FLUSHWRITE) {
+		(void)ioctl(1, TIOCFLUSH, (char *)&out);
+		for (;;) {
+			if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
+				warn("ioctl SIOCATMARK (ignored)");
+				break;
+			}
+			if (atmark)
+				break;
+			n = read(rem, waste, sizeof (waste));
+			if (n <= 0)
+				break;
+		}
+		/*
+		 * Don't want any pending data to be output, so clear the recv
+		 * buffer.  If we were hanging on a write when interrupted,
+		 * don't want it to restart.  If we were reading, restart
+		 * anyway.
+		 */
+		rcvcnt = 0;
+		longjmp(rcvtop, 1);
+	}
+
+	/* oob does not do FLUSHREAD (alas!) */
+
+	/*
+	 * If we filled the receive buffer while a read was pending, longjmp
+	 * to the top to restart appropriately.  Don't abort a pending write,
+	 * however, or we won't know how much was written.
+	 */
+	if (rcvd && rcvstate == READING)
+		longjmp(rcvtop, 1);
+}
+
+/* reader: read from remote: line -> 1 */
+int
+reader(smask)
+	sigset_t *smask;
+{
+	pid_t pid;
+	int n, remaining;
+	char *bufp;
+	struct sigaction sa;
+
+#if BSD >= 43 || defined(SUNOS4)
+	pid = getpid();		/* modern systems use positives for pid */
+#else
+	pid = -getpid();	/* old broken systems use negatives */
+#endif
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags = SA_RESTART;
+	sa.sa_handler = SIG_IGN;
+	(void)sigaction(SIGTTOU, &sa, (struct sigaction *) 0);
+	sa.sa_handler = oob;
+	(void)sigaction(SIGURG, &sa, (struct sigaction *) 0);
+	ppid = getppid();
+	(void)fcntl(rem, F_SETOWN, pid);
+	(void)setjmp(rcvtop);
+	(void)sigprocmask(SIG_SETMASK, smask, (sigset_t *) 0);
+	bufp = rcvbuf;
+	for (;;) {
+		while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
+			rcvstate = WRITING;
+			n = write(STDOUT_FILENO, bufp, remaining);
+			if (n < 0) {
+				if (errno != EINTR)
+					return (-1);
+				continue;
+			}
+			bufp += n;
+		}
+		bufp = rcvbuf;
+		rcvcnt = 0;
+		rcvstate = READING;
+
+#ifdef CRYPT
+#ifdef KERBEROS
+		if (doencrypt)
+			rcvcnt = des_read(rem, rcvbuf, sizeof(rcvbuf));
+		else
+#endif
+#endif
+			rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf));
+		if (rcvcnt == 0)
+			return (0);
+		if (rcvcnt < 0) {
+			if (errno == EINTR)
+				continue;
+			warn("read");
+			return (-1);
+		}
+	}
+}
+
+void
+mode(f)
+	int f;
+{
+	struct termios tt;
+
+	switch (f) {
+	case 0:
+		tcsetattr(0, TCSADRAIN, &deftt);
+		break;
+	case 1:
+		tt = deftt;
+		tt.c_oflag &= ~(OPOST);
+		tt.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+		tt.c_iflag &= ~(ICRNL);
+		tt.c_cc[VMIN] = 1;
+		tt.c_cc[VTIME] = 0;
+		if (eight) {
+			tt.c_iflag &= ~(IXON | IXOFF | ISTRIP);
+			tt.c_cc[VSTOP] = _POSIX_VDISABLE;
+			tt.c_cc[VSTART] = _POSIX_VDISABLE;
+		}
+		/*if (litout)
+			lflags |= LLITOUT;*/
+		tcsetattr(0, TCSADRAIN, &tt);
+		break;
+
+	default:
+		return;
+	}
+}
+
+void
+lostpeer(signo)
+	int signo;
+{
+	struct sigaction sa;
+
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags = SA_RESTART;
+	sa.sa_handler = SIG_IGN;
+	(void)sigaction(SIGPIPE, &sa, (struct sigaction *) 0);
+	msg("\007connection closed.");
+	done(1);
+}
+
+/* copy SIGURGs to the child process. */
+void
+copytochild(signo)
+	int signo;
+{
+
+	(void)kill(child, SIGURG);
+}
+
+static void do_exit(int signo)
+{
+    exit(signo);
+}
+
+void
+msg(str)
+	char *str;
+{
+
+	(void)fprintf(stderr, "rlogin: %s\r\n", str);
+}
+
+#ifdef KERBEROS
+/* VARARGS */
+void
+#if __STDC__
+warning(const char *fmt, ...)
+#else
+warning(fmt, va_alist)
+	char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+	(void)fprintf(stderr, "rlogin: warning, using standard rlogin: ");
+#ifdef __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	(void)fprintf(stderr, ".\n");
+}
+#endif
+
+__dead void
+usage()
+{
+	(void)fprintf(stderr,
+	    "usage: rlogin [ -%s]%s[-e char] [ -l username ] [username@]host\n",
+#ifdef KERBEROS
+#ifdef CRYPT
+	    "8EKLx", " [-k realm] ");
+#else
+	    "8EKL", " [-k realm] ");
+#endif
+#else
+	    "8EL", " ");
+#endif
+	exit(1);
+}
+
+/*
+ * The following routine provides compatibility (such as it is) between older
+ * Suns and others.  Suns have only a `ttysize', so we convert it to a winsize.
+ */
+#ifdef OLDSUN
+int
+get_window_size(fd, wp)
+	int fd;
+	struct winsize *wp;
+{
+	struct ttysize ts;
+	int error;
+
+	if ((error = ioctl(0, TIOCGSIZE, &ts)) != 0)
+		return (error);
+	wp->ws_row = ts.ts_lines;
+	wp->ws_col = ts.ts_cols;
+	wp->ws_xpixel = 0;
+	wp->ws_ypixel = 0;
+	return (0);
+}
+#endif
+
+u_int
+getescape(p)
+	register char *p;
+{
+	long val;
+	int len;
+
+	if ((len = strlen(p)) == 1)	/* use any single char, including '\' */
+		return ((u_int)*p);
+					/* otherwise, \nnn */
+	if (*p == '\\' && len >= 2 && len <= 4) {
+		val = strtol(++p, NULL, 8);
+		for (;;) {
+			if (!*++p)
+				return ((u_int)val);
+			if (*p < '0' || *p > '8')
+				break;
+		}
+	}
+	msg("illegal option value -- e");
+	usage();
+	/* NOTREACHED */
+}
diff --git a/rlogind.tproj/Makefile b/rlogind.tproj/Makefile
new file mode 100644
index 0000000..753d291
--- /dev/null
+++ b/rlogind.tproj/Makefile
@@ -0,0 +1,55 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rlogind
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = pathnames.h
+
+CFILES = rlogind.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble rlogind.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -DCRYPT
+WINDOWS_PB_CFLAGS = -DCRYPT
+PDO_UNIX_PB_CFLAGS = -DCRYPT
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rlogind.tproj/Makefile.postamble b/rlogind.tproj/Makefile.postamble
new file mode 100644
index 0000000..046da0d
--- /dev/null
+++ b/rlogind.tproj/Makefile.postamble
@@ -0,0 +1,2 @@
+VPATH += :../rlogin.tproj
+
diff --git a/rlogind.tproj/Makefile.preamble b/rlogind.tproj/Makefile.preamble
new file mode 100644
index 0000000..97bb72e
--- /dev/null
+++ b/rlogind.tproj/Makefile.preamble
@@ -0,0 +1,3 @@
+CLEAN_ALL_SUBPROJECTS = YES
+OTHER_OFILES = des_rw.o
+-include ../Makefile.include
diff --git a/rlogind.tproj/PB.project b/rlogind.tproj/PB.project
new file mode 100644
index 0000000..20866a4
--- /dev/null
+++ b/rlogind.tproj/PB.project
@@ -0,0 +1,41 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (pathnames.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (rlogind.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, rlogind.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-DCRYPT"; 
+    NEXTSTEP_DOCUMENTEXTENSIONS = (); 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = "-DCRYPT"; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rlogind; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = "-DCRYPT"; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rlogind.tproj/pathnames.h b/rlogind.tproj/pathnames.h
new file mode 100644
index 0000000..b9a57fa
--- /dev/null
+++ b/rlogind.tproj/pathnames.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/4/93
+ */
+
+#include <paths.h>
+
+#define	_PATH_LOGIN	"/usr/bin/login"
diff --git a/rlogind.tproj/rlogind.8 b/rlogind.tproj/rlogind.8
new file mode 100644
index 0000000..9c19933
--- /dev/null
+++ b/rlogind.tproj/rlogind.8
@@ -0,0 +1,168 @@
+.\" Copyright (c) 1983, 1989, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)rlogind.8	8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt RLOGIND 8
+.Os BSD 4.2
+.Sh NAME
+.Nm rlogind
+.Nd remote login server
+.Sh SYNOPSIS
+.Nm rlogind
+.Op Fl aln
+.Sh DESCRIPTION
+.Nm Rlogind
+is the server for the 
+.Xr rlogin 1
+program.  The server provides a remote login facility
+with authentication based on privileged port numbers from trusted hosts.
+.Pp
+Options supported by
+.Nm rlogind :
+.Bl -tag -width Ds
+.It Fl a
+Ask hostname for verification.
+.It Fl l
+Prevent any authentication based on the user's
+.Dq Pa .rhosts
+file, unless the user is logging in as the superuser.
+.It Fl n
+Disable keep-alive messages.
+.El
+.Pp
+.Nm Rlogind
+listens for service requests at the port indicated in
+the ``login'' service specification; see
+.Xr services 5 .
+When a service request is received the following protocol
+is initiated:
+.Bl -enum
+.It
+The server checks the client's source port.
+If the port is not in the range 512-1023, the server
+aborts the connection.
+.It
+The server checks the client's source address
+and requests the corresponding host name (see
+.Xr gethostbyaddr 3 ,
+.Xr hosts 5
+and
+.Xr named 8 ) .
+If the hostname cannot be determined,
+the dot-notation representation of the host address is used.
+If the hostname is in the same domain as the server (according to
+the last two components of the domain name),
+or if the
+.Fl a
+option is given,
+the addresses for the hostname are requested,
+verifying that the name and address correspond.
+Normal authentication is bypassed if the address verification fails.
+.El
+.Pp
+Once the source port and address have been checked, 
+.Nm rlogind
+proceeds with the authentication process described in
+.Xr rshd 8 .
+It then allocates a pseudo terminal (see 
+.Xr pty 4 ) ,
+and manipulates file descriptors so that the slave
+half of the pseudo terminal becomes the 
+.Em stdin ,
+.Em stdout ,
+and
+.Em stderr
+for a login process.
+The login process is an instance of the
+.Xr login 1
+program, invoked with the
+.Fl f
+option if authentication has succeeded.
+If automatic authentication fails, the user is
+prompted to log in as if on a standard terminal line.
+.Pp
+The parent of the login process manipulates the master side of
+the pseudo terminal, operating as an intermediary
+between the login process and the client instance of the
+.Xr rlogin
+program.  In normal operation, the packet protocol described
+in
+.Xr pty 4
+is invoked to provide
+.Ql ^S/^Q
+type facilities and propagate
+interrupt signals to the remote programs.  The login process
+propagates the client terminal's baud rate and terminal type,
+as found in the environment variable,
+.Ql Ev TERM ;
+see
+.Xr environ 7 .
+The screen or window size of the terminal is requested from the client,
+and window size changes from the client are propagated to the pseudo terminal.
+.Pp
+Transport-level keepalive messages are enabled unless the
+.Fl n
+option is present.
+The use of keepalive messages allows sessions to be timed out
+if the client crashes or becomes unreachable.
+.Sh DIAGNOSTICS
+All initial diagnostic messages are indicated
+by a leading byte with a value of 1,
+after which any network connections are closed.
+If there are no errors before
+.Xr login
+is invoked, a null byte is returned as in indication of success.
+.Bl -tag -width Ds
+.It Sy Try again.
+A
+.Xr fork
+by the server failed.
+.El
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr ruserok 3 ,
+.Xr rshd 8
+.Sh BUGS
+The authentication procedure used here assumes the integrity
+of each client machine and the connecting medium.  This is
+insecure, but is useful in an ``open'' environment.
+.Pp
+A facility to allow all data exchanges to be encrypted should be
+present.
+.Pp
+A more extensible protocol should be used.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/rlogind.tproj/rlogind.c b/rlogind.tproj/rlogind.c
new file mode 100644
index 0000000..4cb0575
--- /dev/null
+++ b/rlogind.tproj/rlogind.c
@@ -0,0 +1,783 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1983, 1988, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1988, 1989, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)rlogind.c	8.2 (Berkeley) 4/28/95";
+#endif /* not lint */
+
+/*
+ * remote login server:
+ *	\0
+ *	remuser\0
+ *	locuser\0
+ *	terminal_type/speed\0
+ *	data
+ */
+
+#define	FD_SETSIZE	16		/* don't need many bits for select */
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#ifdef __APPLE__
+#include <sys/termios.h>
+#else
+#include <termios.h>
+#endif
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <pwd.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pathnames.h"
+
+#ifndef TIOCPKT_WINDOW
+#define TIOCPKT_WINDOW 0x80
+#endif
+
+#ifdef	KERBEROS
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#define	SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n"
+
+AUTH_DAT	*kdata;
+KTEXT		ticket;
+u_char		auth_buf[sizeof(AUTH_DAT)];
+u_char		tick_buf[sizeof(KTEXT_ST)];
+Key_schedule	schedule;
+int		doencrypt, retval, use_kerberos, vacuous;
+
+#define		ARGSTR			"alnkvx"
+#else
+#define		ARGSTR			"aln"
+#endif	/* KERBEROS */
+
+char	*env[2];
+#define	NMAX 30
+char	lusername[NMAX+1], rusername[NMAX+1];
+static	char term[64] = "TERM=";
+#define	ENVSIZE	(sizeof("TERM=")-1)	/* skip null for concatenation */
+int	keepalive = 1;
+int	check_all = 0;
+
+struct	passwd *pwd;
+
+void	doit __P((int, struct sockaddr_in *));
+int	control __P((int, char *, int));
+void	protocol __P((int, int));
+void	cleanup __P((int));
+void	fatal __P((int, char *, int));
+int	do_rlogin __P((struct sockaddr_in *));
+void	getstr __P((char *, int, char *));
+void	setup_term __P((int));
+int	do_krb_login __P((struct sockaddr_in *));
+void	usage __P((void));
+int	local_domain __P((char *));
+char	*topdomain __P((char *));
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	extern int __check_rhosts_file;
+	struct sockaddr_in from;
+	int ch, fromlen, on;
+
+	openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH);
+
+	opterr = 0;
+	while ((ch = getopt(argc, argv, ARGSTR)) != EOF)
+		switch (ch) {
+		case 'a':
+			check_all = 1;
+			break;
+		case 'l':
+			__check_rhosts_file = 0;
+			break;
+		case 'n':
+			keepalive = 0;
+			break;
+#ifdef KERBEROS
+		case 'k':
+			use_kerberos = 1;
+			break;
+		case 'v':
+			vacuous = 1;
+			break;
+#ifdef CRYPT
+		case 'x':
+			doencrypt = 1;
+			break;
+#endif
+#endif
+		case '?':
+		default:
+			usage();
+			break;
+		}
+	argc -= optind;
+	argv += optind;
+
+#ifdef	KERBEROS
+	if (use_kerberos && vacuous) {
+		usage();
+		fatal(STDERR_FILENO, "only one of -k and -v allowed", 0);
+	}
+#endif
+	fromlen = sizeof (from);
+	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
+		syslog(LOG_ERR,"Can't get peer name of remote host: %m");
+		fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
+	}
+	on = 1;
+	if (keepalive &&
+	    setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
+		syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
+	on = IPTOS_LOWDELAY;
+	if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
+		syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
+	doit(0, &from);
+}
+
+int	child;
+int	netf;
+char	line[MAXPATHLEN];
+int	confirmed;
+
+struct winsize win = { 0, 0, 0, 0 };
+
+
+void
+doit(f, fromp)
+	int f;
+	struct sockaddr_in *fromp;
+{
+	int master, pid, on = 1;
+	int authenticated = 0;
+	register struct hostent *hp;
+	char hostname[2 * MAXHOSTNAMELEN + 1];
+	char c;
+
+	alarm(60);
+	read(f, &c, 1);
+
+	if (c != 0)
+		exit(1);
+#ifdef	KERBEROS
+	if (vacuous)
+		fatal(f, "Remote host requires Kerberos authentication", 0);
+#endif
+
+	alarm(0);
+	fromp->sin_port = ntohs((u_short)fromp->sin_port);
+	hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof(struct in_addr),
+	    fromp->sin_family);
+	if (hp)
+		(void)strcpy(hostname, hp->h_name);
+	else
+		(void)strcpy(hostname, inet_ntoa(fromp->sin_addr));
+
+#ifdef	KERBEROS
+	if (use_kerberos) {
+		retval = do_krb_login(fromp);
+		if (retval == 0)
+			authenticated++;
+		else if (retval > 0)
+			fatal(f, krb_err_txt[retval], 0);
+		write(f, &c, 1);
+		confirmed = 1;		/* we sent the null! */
+	} else
+#endif
+	{
+		if (fromp->sin_family != AF_INET ||
+		    fromp->sin_port >= IPPORT_RESERVED ||
+		    fromp->sin_port < IPPORT_RESERVED/2) {
+			syslog(LOG_NOTICE, "Connection from %s on illegal port",
+				inet_ntoa(fromp->sin_addr));
+			fatal(f, "Permission denied", 0);
+		}
+#ifdef IP_OPTIONS
+		{
+		u_char optbuf[BUFSIZ/3], *cp;
+		char lbuf[BUFSIZ], *lp;
+		int optsize = sizeof(optbuf), ipproto;
+		struct protoent *ip;
+
+		if ((ip = getprotobyname("ip")) != NULL)
+			ipproto = ip->p_proto;
+		else
+			ipproto = IPPROTO_IP;
+		if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf,
+		    &optsize) == 0 && optsize != 0) {
+			lp = lbuf;
+			for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
+				sprintf(lp, " %2.2x", *cp);
+			syslog(LOG_NOTICE,
+			    "Connection received using IP options (ignored):%s",
+			    lbuf);
+			if (setsockopt(0, ipproto, IP_OPTIONS,
+			    (char *)NULL, optsize) != 0) {
+				syslog(LOG_ERR,
+				    "setsockopt IP_OPTIONS NULL: %m");
+				exit(1);
+			}
+		}
+		}
+#endif
+		if (do_rlogin(fromp) == 0)
+			authenticated++;
+	}
+	if (confirmed == 0) {
+		write(f, "", 1);
+		confirmed = 1;		/* we sent the null! */
+	}
+#ifdef	KERBEROS
+#ifdef	CRYPT
+	if (doencrypt)
+		(void) des_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE) - 1);
+#endif
+#endif
+	netf = f;
+
+	pid = forkpty(&master, line, NULL, &win);
+	if (pid < 0) {
+		if (errno == ENOENT)
+			fatal(f, "Out of ptys", 0);
+		else
+			fatal(f, "Forkpty", 1);
+	}
+	if (pid == 0) {
+		if (f > 2)	/* f should always be 0, but... */
+			(void) close(f);
+		setup_term(0);
+		if (authenticated) {
+#ifdef	KERBEROS
+			if (use_kerberos && (pwd->pw_uid == 0))
+				syslog(LOG_INFO|LOG_AUTH,
+				    "ROOT Kerberos login from %s.%s@%s on %s\n",
+				    kdata->pname, kdata->pinst, kdata->prealm,
+				    hostname);
+#endif
+
+			execle(_PATH_LOGIN, "login", "-p",
+			    "-h", hostname, "-f", "--", lusername, NULL, env);
+		} else
+			execle(_PATH_LOGIN, "login", "-p",
+			    "-h", hostname, "--", lusername, NULL, env);
+		fatal(STDERR_FILENO, _PATH_LOGIN, 1);
+		/*NOTREACHED*/
+	}
+#ifdef	CRYPT
+#ifdef	KERBEROS
+	/*
+	 * If encrypted, don't turn on NBIO or the des read/write
+	 * routines will croak.
+	 */
+
+	if (!doencrypt)
+#endif
+#endif
+		ioctl(f, FIONBIO, &on);
+	ioctl(master, FIONBIO, &on);
+	ioctl(master, TIOCPKT, &on);
+	signal(SIGCHLD, cleanup);
+	protocol(f, master);
+	signal(SIGCHLD, SIG_IGN);
+	cleanup(0);
+}
+
+char	magic[2] = { 0377, 0377 };
+char	oobdata[] = {TIOCPKT_WINDOW};
+
+/*
+ * Handle a "control" request (signaled by magic being present)
+ * in the data stream.  For now, we are only willing to handle
+ * window size changes.
+ */
+int
+control(pty, cp, n)
+	int pty;
+	char *cp;
+	int n;
+{
+	struct winsize w;
+
+	if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's')
+		return (0);
+	oobdata[0] &= ~TIOCPKT_WINDOW;	/* we know he heard */
+	memmove(&w, cp+4, sizeof(w));
+	w.ws_row = ntohs(w.ws_row);
+	w.ws_col = ntohs(w.ws_col);
+	w.ws_xpixel = ntohs(w.ws_xpixel);
+	w.ws_ypixel = ntohs(w.ws_ypixel);
+	(void)ioctl(pty, TIOCSWINSZ, &w);
+	return (4+sizeof (w));
+}
+
+/*
+ * rlogin "protocol" machine.
+ */
+void
+protocol(f, p)
+	register int f, p;
+{
+	char pibuf[1024+1], fibuf[1024], *pbp, *fbp;
+	register pcc = 0, fcc = 0;
+	int cc, nfd, n;
+	char cntl;
+
+	/*
+	 * Must ignore SIGTTOU, otherwise we'll stop
+	 * when we try and set slave pty's window shape
+	 * (our controlling tty is the master pty).
+	 */
+	(void) signal(SIGTTOU, SIG_IGN);
+	send(f, oobdata, 1, MSG_OOB);	/* indicate new rlogin */
+	if (f > p)
+		nfd = f + 1;
+	else
+		nfd = p + 1;
+	if (nfd > FD_SETSIZE) {
+		syslog(LOG_ERR, "select mask too small, increase FD_SETSIZE");
+		fatal(f, "internal error (select mask too small)", 0);
+	}
+	for (;;) {
+		fd_set ibits, obits, ebits, *omask;
+
+		FD_ZERO(&ebits);
+		FD_ZERO(&ibits);
+		FD_ZERO(&obits);
+		omask = (fd_set *)NULL;
+		if (fcc) {
+			FD_SET(p, &obits);
+			omask = &obits;
+		} else
+			FD_SET(f, &ibits);
+		if (pcc >= 0)
+			if (pcc) {
+				FD_SET(f, &obits);
+				omask = &obits;
+			} else
+				FD_SET(p, &ibits);
+		FD_SET(p, &ebits);
+		if ((n = select(nfd, &ibits, omask, &ebits, 0)) < 0) {
+			if (errno == EINTR)
+				continue;
+			fatal(f, "select", 1);
+		}
+		if (n == 0) {
+			/* shouldn't happen... */
+			sleep(5);
+			continue;
+		}
+#define	pkcontrol(c)	((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
+		if (FD_ISSET(p, &ebits)) {
+			cc = read(p, &cntl, 1);
+			if (cc == 1 && pkcontrol(cntl)) {
+				cntl |= oobdata[0];
+				send(f, &cntl, 1, MSG_OOB);
+				if (cntl & TIOCPKT_FLUSHWRITE) {
+					pcc = 0;
+					FD_CLR(p, &ibits);
+				}
+			}
+		}
+		if (FD_ISSET(f, &ibits)) {
+#ifdef	CRYPT
+#ifdef	KERBEROS
+			if (doencrypt)
+				fcc = des_read(f, fibuf, sizeof(fibuf));
+			else
+#endif
+#endif
+				fcc = read(f, fibuf, sizeof(fibuf));
+			if (fcc < 0 && errno == EWOULDBLOCK)
+				fcc = 0;
+			else {
+				register char *cp;
+				int left, n;
+
+				if (fcc <= 0)
+					break;
+				fbp = fibuf;
+
+			top:
+				for (cp = fibuf; cp < fibuf+fcc-1; cp++)
+					if (cp[0] == magic[0] &&
+					    cp[1] == magic[1]) {
+						left = fcc - (cp-fibuf);
+						n = control(p, cp, left);
+						if (n) {
+							left -= n;
+							if (left > 0)
+								bcopy(cp+n, cp, left);
+							fcc -= n;
+							goto top; /* n^2 */
+						}
+					}
+				FD_SET(p, &obits);		/* try write */
+			}
+		}
+
+		if (FD_ISSET(p, &obits) && fcc > 0) {
+			cc = write(p, fbp, fcc);
+			if (cc > 0) {
+				fcc -= cc;
+				fbp += cc;
+			}
+		}
+
+		if (FD_ISSET(p, &ibits)) {
+			pcc = read(p, pibuf, sizeof (pibuf));
+			pbp = pibuf;
+			if (pcc < 0 && errno == EWOULDBLOCK)
+				pcc = 0;
+			else if (pcc <= 0)
+				break;
+			else if (pibuf[0] == 0) {
+				pbp++, pcc--;
+#ifdef	CRYPT
+#ifdef	KERBEROS
+				if (!doencrypt)
+#endif
+#endif
+					FD_SET(f, &obits);	/* try write */
+			} else {
+				if (pkcontrol(pibuf[0])) {
+					pibuf[0] |= oobdata[0];
+					send(f, &pibuf[0], 1, MSG_OOB);
+				}
+				pcc = 0;
+			}
+		}
+		if ((FD_ISSET(f, &obits)) && pcc > 0) {
+#ifdef	CRYPT
+#ifdef	KERBEROS
+			if (doencrypt)
+				cc = des_write(f, pbp, pcc);
+			else
+#endif
+#endif
+				cc = write(f, pbp, pcc);
+			if (cc < 0 && errno == EWOULDBLOCK) {
+				/*
+				 * This happens when we try write after read
+				 * from p, but some old kernels balk at large
+				 * writes even when select returns true.
+				 */
+				if (!FD_ISSET(p, &ibits))
+					sleep(5);
+				continue;
+			}
+			if (cc > 0) {
+				pcc -= cc;
+				pbp += cc;
+			}
+		}
+	}
+}
+
+void
+cleanup(signo)
+	int signo;
+{
+	char *p;
+
+	p = line + sizeof(_PATH_DEV) - 1;
+	if (logout(p))
+		logwtmp(p, "", "");
+	(void)chmod(line, 0666);
+	(void)chown(line, 0, 0);
+	*p = 'p';
+	(void)chmod(line, 0666);
+	(void)chown(line, 0, 0);
+	shutdown(netf, 2);
+	exit(1);
+}
+
+void
+fatal(f, msg, syserr)
+	int f;
+	char *msg;
+	int syserr;
+{
+	int len;
+	char buf[BUFSIZ], *bp = buf;
+
+	/*
+	 * Prepend binary one to message if we haven't sent
+	 * the magic null as confirmation.
+	 */
+	if (!confirmed)
+		*bp++ = '\01';		/* error indicator */
+	if (syserr)
+		len = sprintf(bp, "rlogind: %s: %s.\r\n",
+		    msg, strerror(errno));
+	else
+		len = sprintf(bp, "rlogind: %s.\r\n", msg);
+	(void) write(f, buf, bp + len - buf);
+	exit(1);
+}
+
+int
+do_rlogin(dest)
+	struct sockaddr_in *dest;
+{
+	getstr(rusername, sizeof(rusername), "remuser too long");
+	getstr(lusername, sizeof(lusername), "locuser too long");
+	getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long");
+
+	pwd = getpwnam(lusername);
+	if (pwd == NULL)
+		return (-1);
+	if (pwd->pw_uid == 0)
+		return (-1);
+	/* XXX why don't we syslog() failure? */
+	return (iruserok(dest->sin_addr.s_addr, 0, rusername, lusername));
+}
+
+void
+getstr(buf, cnt, errmsg)
+	char *buf;
+	int cnt;
+	char *errmsg;
+{
+	char c;
+
+	do {
+		if (read(0, &c, 1) != 1)
+			exit(1);
+		if (--cnt < 0)
+			fatal(STDOUT_FILENO, errmsg, 0);
+		*buf++ = c;
+	} while (c != 0);
+}
+
+void
+setup_term(fd)
+	int fd;
+{
+	register char *cp = index(term+ENVSIZE, '/');
+	char *speed;
+	struct termios tt;
+
+#ifndef notyet
+	tcgetattr(fd, &tt);
+	if (cp) {
+		*cp++ = '\0';
+		speed = cp;
+		cp = index(speed, '/');
+		if (cp)
+			*cp++ = '\0';
+		cfsetspeed(&tt, atoi(speed));
+	}
+
+	tt.c_iflag = TTYDEF_IFLAG;
+	tt.c_oflag = TTYDEF_OFLAG;
+	tt.c_lflag = TTYDEF_LFLAG;
+	tcsetattr(fd, TCSAFLUSH, &tt);
+#else
+	if (cp) {
+		*cp++ = '\0';
+		speed = cp;
+		cp = index(speed, '/');
+		if (cp)
+			*cp++ = '\0';
+		tcgetattr(fd, &tt);
+		cfsetspeed(&tt, atoi(speed));
+		tcsetattr(fd, TCSAFLUSH, &tt);
+	}
+#endif
+
+	env[0] = term;
+	env[1] = 0;
+}
+
+#ifdef	KERBEROS
+#define	VERSION_SIZE	9
+
+/*
+ * Do the remote kerberos login to the named host with the
+ * given inet address
+ *
+ * Return 0 on valid authorization
+ * Return -1 on valid authentication, no authorization
+ * Return >0 for error conditions
+ */
+int
+do_krb_login(dest)
+	struct sockaddr_in *dest;
+{
+	int rc;
+	char instance[INST_SZ], version[VERSION_SIZE];
+	long authopts = 0L;	/* !mutual */
+	struct sockaddr_in faddr;
+
+	kdata = (AUTH_DAT *) auth_buf;
+	ticket = (KTEXT) tick_buf;
+
+	instance[0] = '*';
+	instance[1] = '\0';
+
+#ifdef	CRYPT
+	if (doencrypt) {
+		rc = sizeof(faddr);
+		if (getsockname(0, (struct sockaddr *)&faddr, &rc))
+			return (-1);
+		authopts = KOPT_DO_MUTUAL;
+		rc = krb_recvauth(
+			authopts, 0,
+			ticket, "rcmd",
+			instance, dest, &faddr,
+			kdata, "", schedule, version);
+		 des_set_key(kdata->session, schedule);
+
+	} else
+#endif
+		rc = krb_recvauth(
+			authopts, 0,
+			ticket, "rcmd",
+			instance, dest, (struct sockaddr_in *) 0,
+			kdata, "", (bit_64 *) 0, version);
+
+	if (rc != KSUCCESS)
+		return (rc);
+
+	getstr(lusername, sizeof(lusername), "locuser");
+	/* get the "cmd" in the rcmd protocol */
+	getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type");
+
+	pwd = getpwnam(lusername);
+	if (pwd == NULL)
+		return (-1);
+
+	/* returns nonzero for no access */
+	if (kuserok(kdata, lusername) != 0)
+		return (-1);
+	
+	return (0);
+
+}
+#endif /* KERBEROS */
+
+void
+usage()
+{
+#ifdef KERBEROS
+	syslog(LOG_ERR, "usage: rlogind [-aln] [-k | -v]");
+#else
+	syslog(LOG_ERR, "usage: rlogind [-aln]");
+#endif
+}
+
+/*
+ * Check whether host h is in our local domain,
+ * defined as sharing the last two components of the domain part,
+ * or the entire domain part if the local domain has only one component.
+ * If either name is unqualified (contains no '.'),
+ * assume that the host is local, as it will be
+ * interpreted as such.
+ */
+int
+local_domain(h)
+	char *h;
+{
+	char localhost[MAXHOSTNAMELEN];
+	char *p1, *p2;
+
+	localhost[0] = 0;
+	(void) gethostname(localhost, sizeof(localhost));
+	p1 = topdomain(localhost);
+	p2 = topdomain(h);
+	if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2))
+		return (1);
+	return (0);
+}
+
+char *
+topdomain(h)
+	char *h;
+{
+	register char *p;
+	char *maybe = NULL;
+	int dots = 0;
+
+	for (p = h + strlen(h); p >= h; p--) {
+		if (*p == '.') {
+			if (++dots == 2)
+				return (p);
+			maybe = p;
+		}
+	}
+	return (maybe);
+}
diff --git a/route.tproj/Makefile b/route.tproj/Makefile
new file mode 100644
index 0000000..d1a9e0e
--- /dev/null
+++ b/route.tproj/Makefile
@@ -0,0 +1,53 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = route
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = keywords.h
+
+CFILES = ccitt_addr.c route.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\
+            route.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /sbin
+WINDOWS_INSTALLDIR = /sbin
+PDO_UNIX_INSTALLDIR = /sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/route.tproj/Makefile.dist b/route.tproj/Makefile.dist
new file mode 100644
index 0000000..f7de878
--- /dev/null
+++ b/route.tproj/Makefile.dist
@@ -0,0 +1,25 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/5/93
+
+PROG=	route
+MAN8=	route.0
+SRCS=	route.c ccitt_addr.c
+CFLAGS+=-I.
+CLEANFILES+=keywords.h
+BINOWN=	root
+BINMODE=4555
+
+all: route ${MAN8}
+
+keywords.h: keywords
+	sed -e '/^#/d' -e '/^$$/d' ${.CURDIR}/keywords > _keywords.tmp
+	tr a-z A-Z < _keywords.tmp | paste _keywords.tmp - | \
+	    awk '{ \
+		if (NF > 1) \
+			printf "#define\tK_%s\t%d\n\t{\"%s\", K_%s},\n", \
+			    $$2, NR, $$1, $$2 }' \
+	    > ${.TARGET}
+	rm -f _keywords.tmp
+
+.include <bsd.prog.mk>
+
+route .depend lint tags: keywords.h
diff --git a/route.tproj/Makefile.postamble b/route.tproj/Makefile.postamble
new file mode 100644
index 0000000..670967c
--- /dev/null
+++ b/route.tproj/Makefile.postamble
@@ -0,0 +1 @@
+INSTALL_PERMISSIONS = 4555    # If set, 'install' chmod's executable to this
diff --git a/route.tproj/Makefile.preamble b/route.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/route.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/route.tproj/PB.project b/route.tproj/PB.project
new file mode 100644
index 0000000..f27333b
--- /dev/null
+++ b/route.tproj/PB.project
@@ -0,0 +1,43 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        CLASSES = (); 
+        FRAMEWORKS = (); 
+        H_FILES = (keywords.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (ccitt_addr.c, route.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, Makefile.dist, route.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = route; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_MAINNIB = route; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = route; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_MAINNIB = route; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/route.tproj/ccitt_addr.c b/route.tproj/ccitt_addr.c
new file mode 100644
index 0000000..9c57be3
--- /dev/null
+++ b/route.tproj/ccitt_addr.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ccitt_addr.c	8.2 (Berkeley) 4/28/95
+ */
+
+/*
+ * parse CCITT addresses
+ *
+ * Addresses must have the format: [hpr],x121address[,userdata][,protocol]
+ * items enclosed with square brackets are optional
+ * 'h' or 'p' means hi priority (packet size = 128; specific to Datapac
+ * and necessary only for X.25(76) and non-negotiating X.25(80) DTE's)
+ * 'r' means reverse charge (remote DTE pays for call).
+ * The x121address consists of an optional netid and dot, followed
+ * by a dte address.
+ *
+ * Frank Pronk
+ * The University of British Columbia
+ * Laboratory for Computational Vision
+ * Copyright (c) 1984
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <bsd/netccitt/x25.h>
+
+static char *copychar ();
+
+ccitt_addr (addr, xp)
+char *addr;
+register struct sockaddr_x25 *xp;
+{
+	register char *p, *ap, *limit;
+	int havenet = 0;
+
+	memset(xp, 0, sizeof (*xp));
+	xp->x25_family = AF_CCITT;
+	xp->x25_len = sizeof(*xp);
+	p = addr;
+
+	/*
+	 * process optional priority and reverse charging flags
+	 */
+
+	if (*p == 'p' || *p == 'r' || *p == 'h') {
+		while (*p == 'p' || *p == 'r' || *p == 'h') {
+			if (*p == 'p' || *p == 'h')
+				xp->x25_opts.op_psize = X25_PS128;
+			else if (*p == 'r')
+				xp->x25_opts.op_flags |= X25_REVERSE_CHARGE;
+			p++;
+		}
+		if (*p != ',')
+			return (0);
+		p++;
+	}
+	if (*p == '\0')
+		return (0);
+
+	/*
+	 * [network id:]X.121 address
+	 */
+
+	ap = xp->x25_addr;
+	limit = ap + sizeof (xp->x25_addr) - 1;
+	while (*p) {
+		if (*p == ',')
+			break;
+		if (*p == '.' || *p == ':') {
+			if (havenet)
+				return (0);
+			havenet++;
+			xp->x25_net = atoi (xp->x25_addr);
+			p++;
+			ap = xp->x25_addr;
+			*ap = '\0';
+		}
+		if (*p < '0' || *p > '9')
+			return (0);
+		if (ap >= limit)
+			return (0);
+		*ap++ = *p++;
+	}
+	if (*p == '\0')
+		return (1);
+
+	/*
+	 * optional user data, bytes 4 to 16
+	 */
+
+	p++;
+	ap = xp->x25_udata + 4;		/* first four bytes are protocol id */
+	limit = ap + sizeof (xp->x25_udata) - 4;
+	xp->x25_udlen = 4;
+	while (*p) {
+		if (*p == ',')
+			break;
+		if (ap >= limit)
+			return (0);
+		p = copychar (p, ap++);
+		xp->x25_udlen++;
+	}
+	if (xp->x25_udlen == 4)
+		xp->x25_udlen = 0;
+	if (*p == '\0')
+		return (1);
+
+	p++;
+	ap = xp->x25_udata;		/* protocol id */
+	limit = ap + (xp->x25_udlen ? 4 : sizeof(xp->x25_udata));
+	while (*p) {
+		if (*p == ',')
+			return (0);
+		if (ap >= limit)
+			return (0);
+		p = copychar (p, ap++);
+	}
+	if (xp->x25_udlen == 0)
+		xp->x25_udlen = ap - xp->x25_udata;
+	return (1);
+}
+
+static char *
+copychar (from, to)
+register char *from, *to;
+{
+	register int n;
+
+	if (*from != '\\' || from[1] < '0' || from[1] > '7') {
+		*to = *from++;
+		return (from);
+	}
+	n = *++from - '0';
+	from++;
+	if (*from >= '0' && *from <= '7') {
+		register int n1;
+
+		n = n*8 + *from++ - '0';
+		if (*from >= '0' && *from <= '7' && (n1 = n*8 + *from-'0') < 256) {
+			n = n1;
+			from++;
+		}
+	}
+	*to = n;
+	return (from);
+}
diff --git a/route.tproj/keywords.h b/route.tproj/keywords.h
new file mode 100644
index 0000000..bb5eebd
--- /dev/null
+++ b/route.tproj/keywords.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#define	K_ADD	1
+	{"add", K_ADD},
+#define	K_BLACKHOLE	2
+	{"blackhole", K_BLACKHOLE},
+#define	K_CHANGE	3
+	{"change", K_CHANGE},
+#define	K_CLONING	4
+	{"cloning", K_CLONING},
+#define	K_DELETE	5
+	{"delete", K_DELETE},
+#define	K_DST	6
+	{"dst", K_DST},
+#define	K_EXPIRE	7
+	{"expire", K_EXPIRE},
+#define	K_FLUSH	8
+	{"flush", K_FLUSH},
+#define	K_GATEWAY	9
+	{"gateway", K_GATEWAY},
+#define	K_GENMASK	10
+	{"genmask", K_GENMASK},
+#define	K_GET	11
+	{"get", K_GET},
+#define	K_HOST	12
+	{"host", K_HOST},
+#define	K_HOPCOUNT	13
+	{"hopcount", K_HOPCOUNT},
+#define	K_IFACE	14
+	{"iface", K_IFACE},
+#define	K_INTERFACE	15
+	{"interface", K_INTERFACE},
+#define	K_IFA	16
+	{"ifa", K_IFA},
+#define	K_IFP	17
+	{"ifp", K_IFP},
+#define	K_INET	18
+	{"inet", K_INET},
+#define	K_ISO	19
+	{"iso", K_ISO},
+#define	K_LINK	20
+	{"link", K_LINK},
+#define	K_LOCK	21
+	{"lock", K_LOCK},
+#define	K_LOCKREST	22
+	{"lockrest", K_LOCKREST},
+#define	K_MASK	23
+	{"mask", K_MASK},
+#define	K_MONITOR	24
+	{"monitor", K_MONITOR},
+#define	K_MTU	25
+	{"mtu", K_MTU},
+#define	K_NET	26
+	{"net", K_NET},
+#define	K_NETMASK	27
+	{"netmask", K_NETMASK},
+#define	K_NOSTATIC	28
+	{"nostatic", K_NOSTATIC},
+#define	K_OSI	29
+	{"osi", K_OSI},
+#define	K_PROTO1	30
+	{"proto1", K_PROTO1},
+#define	K_PROTO2	31
+	{"proto2", K_PROTO2},
+#define	K_RECVPIPE	32
+	{"recvpipe", K_RECVPIPE},
+#define	K_REJECT	33
+	{"reject", K_REJECT},
+#define	K_RTT	34
+	{"rtt", K_RTT},
+#define	K_RTTVAR	35
+	{"rttvar", K_RTTVAR},
+#define	K_SA	36
+	{"sa", K_SA},
+#define	K_SENDPIPE	37
+	{"sendpipe", K_SENDPIPE},
+#define	K_SSTHRESH	38
+	{"ssthresh", K_SSTHRESH},
+#define	K_STATIC	39
+	{"static", K_STATIC},
+#define	K_X25	40
+	{"x25", K_X25},
+#define	K_XNS	41
+	{"xns", K_XNS},
+#define	K_XRESOLVE	42
+	{"xresolve", K_XRESOLVE},
+#define K_LLINFO	43
+	{"llinfo", K_LLINFO},
diff --git a/route.tproj/route.8 b/route.tproj/route.8
new file mode 100644
index 0000000..62b9cfe
--- /dev/null
+++ b/route.tproj/route.8
@@ -0,0 +1,325 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)route.8	8.4 (Berkeley) 6/1/94
+.\"
+.Dd June 1, 1994
+.Dt ROUTE 8
+.Os BSD 4.4
+.Sh NAME
+.Nm route
+.Nd manually manipulate the routing tables.
+.Sh SYNOPSIS
+.Nm route
+.Op Fl nqv
+.Ar command
+.Oo
+.Op Ar modifiers
+.Ar args
+.Oc
+.Sh DESCRIPTION
+.Nm Route
+is a utility used to manually manipulate the network
+routing tables.  It normally is not needed, as a
+system routing table management daemon such as
+.Xr routed 8 ,
+should tend to this task.
+.Pp
+The
+.Nm route :
+utility supports a limited number of general options,
+but a rich command language, enabling the user to specify
+any arbitrary request that could be delivered via the
+programmatic interface discussed in 
+.Xr route 4 .
+.Pp
+.Bl -tag -width Ds
+.It Fl n
+Bypasses attempts to print host and network names symbolically
+when reporting actions.  (The process of translating between symbolic
+names and numerical equivalents can be quite time consuming, and
+may require correct operation of the network; thus it may be expedient
+to forgo this, especially when attempting to repair networking operations),
+.It Fl v
+(verbose) Print additional details.
+.It Fl q
+Suppress all output.
+.El
+.Pp
+The
+.Nm route :
+utility provides six commands:
+.Pp
+.Bl -tag -width Fl -compact
+.It Cm add
+Add a route.
+.It Cm flush
+Remove all routes.
+.It Cm delete
+Delete a specific route.
+.It Cm change
+Change aspects of a route (such as its gateway).
+.It Cm get
+Lookup and display the route for a destination.
+.It Cm monitor
+Continuously report any changes to the routing information base,
+routing lookup misses, or suspected network partitionings.
+.El
+.Pp
+The monitor command has the syntax
+.Pp
+.Bd -filled -offset indent -compact
+.Nm route Op Fl n
+.Cm monitor
+.Ed
+.Pp
+The flush command has the syntax
+.Pp
+.Bd -filled -offset indent -compact
+.Nm route Op Fl n
+.Cm flush
+.Op Ar family
+.Ed
+.Pp
+If the 
+.Cm flush
+command is specified, 
+.Nm route
+will ``flush'' the routing tables of all gateway entries.
+When the address family may is specified by any of the
+.Fl osi ,
+.Fl xns ,
+or
+.Fl inet
+modifiers, only routes having destinations with addresses in the
+delineated family will be deleted.
+.Pp
+The other commands have the following syntax:
+.Pp
+.Bd -filled -offset indent -compact
+.Nm route Op Fl n
+.Ar command
+.Op Fl net No \&| Fl host
+.Ar destination gateway
+.Ed
+.Pp
+where
+.Ar destination
+is the destination host or network,
+.Ar gateway
+is the next-hop intermediary via which packets should be routed.
+Routes to a particular host may be distinguished from those to
+a network by interpreting the Internet address specified as the
+.Ar destination argument.
+The optional modifiers
+.Fl net
+and
+.Fl host
+force the destination to be interpreted as a network or a host, respectively.
+Otherwise, if the 
+.Ar destination
+has a ``local address part'' of
+INADDR_ANY ,
+or if the
+.Ar destination
+is the symbolic name of a network, then the route is
+assumed to be to a network; otherwise, it is presumed to be a
+route to a host.
+.Pp
+For example,
+.Li 128.32
+is interpreted as
+.Fl host Li 128.0.0.32 ;
+.Li 128.32.130
+is interpreted as
+.Fl host Li 128.32.0.130 ;
+.Fl net Li 128.32
+is interpreted as
+.Li 128.32.0.0;
+and 
+.Fl net Li 128.32.130
+is interpreted as
+.Li 128.32.130.0 .
+.Pp
+If the destination is directly reachable
+via an interface requiring
+no intermediary system to act as a gateway, the 
+.Fl interface
+modifier should be specified;
+the gateway given is the address of this host on the common network,
+indicating the interface to be used for transmission.
+.Pp
+The optional modifiers
+.Fl xns ,
+.Fl osi ,
+and
+.Fl link 
+specify that all subsequent addresses are in the
+.Tn XNS
+.Tn OSI
+address families,
+or are specified as link-level addresses,
+and the names must be numeric specifications rather than
+symbolic names.
+.Pp
+The optional
+.Fl netmask
+qualifier is intended
+to achieve the effect of an
+.Tn OSI
+.Tn ESIS
+redirect with the netmask option,
+or to manually add subnet routes with
+netmasks different from that of the implied network interface
+(as would otherwise be communicated using the OSPF or ISIS routing protocols).
+One specifies an additional ensuing address parameter
+(to be interpreted as a network mask).
+The implicit network mask generated in the AF_INET case
+can be overridden by making sure this option follows the destination parameter.
+.Pp
+Routes have associated flags which influence operation of the protocols
+when sending to destinations matched by the routes.
+These flags may be set (or sometimes cleared)
+by indicating the following corresponding modifiers:
+.Bd -literal
+-cloning   RTF_CLONING    - generates a new route on use
+-xresolve  RTF_XRESOLVE   - emit mesg on use (for external lookup)
+-iface    ~RTF_GATEWAY    - destination is directly reachable
+-static    RTF_STATIC     - manually added route
+-nostatic ~RTF_STATIC     - pretend route added by kernel or daemon
+-reject    RTF_REJECT     - emit an ICMP unreachable when matched
+-blackhole RTF_BLACKHOLE  - silently discard pkts (during updates)
+-proto1    RTF_PROTO1     - set protocol specific routing flag #1
+-proto2    RTF_PROTO2     - set protocol specific routing flag #2
+-llinfo    RTF_LLINFO     - validly translates proto addr to link addr
+.Ed
+.Pp
+The optional modifiers
+.Fl rtt ,
+.Fl rttvar ,
+.Fl sendpipe ,
+.Fl recvpipe ,
+.Fl mtu ,
+.Fl hopcount ,
+.Fl expire ,
+and
+.Fl ssthresh
+provide initial values to quantities maintained in the routing entry
+by transport level protocols, such as TCP or TP4.
+These may be individually locked by preceding each such modifier to
+be locked by
+the
+.Fl lock
+meta-modifier, or one can 
+specify that all ensuing metrics may be locked by the
+.Fl lockrest
+meta-modifier.
+.Pp
+In a
+.Cm change
+or
+.Cm add
+command where the destination and gateway are not sufficient to specify
+the route (as in the
+.Tn ISO
+case where several interfaces may have the
+same address), the
+.Fl ifp
+or
+.Fl ifa
+modifiers may be used to determine the interface or interface address.
+.Pp
+All symbolic names specified for a
+.Ar destination
+or 
+.Ar gateway
+are looked up first as a host name using
+.Xr gethostbyname 3 .
+If this lookup fails,
+.Xr getnetbyname 3
+is then used to interpret the name as that of a network.
+.Pp
+.Nm Route
+uses a routing socket and the new message types
+RTM_ADD,
+RTM_DELETE,
+RTM_GET,
+and
+RTM_CHANGE.
+As such, only the super-user may modify
+the routing tables.
+.ne 1i
+.Sh DIAGNOSTICS
+.Bl -tag -width Ds
+.It Sy "add [host \&| network ] %s: gateway %s flags %x"
+The specified route is being added to the tables.  The
+values printed are from the routing table entry supplied
+in the 
+.Xr ioctl 2
+call.
+If the gateway address used was not the primary address of the gateway
+(the first one returned by
+.Xr gethostbyname 3 ) ,
+the gateway address is printed numerically as well as symbolically.
+.It Sy "delete [ host &| network ] %s: gateway %s flags %x" 
+As above, but when deleting an entry.
+.It Sy "%s %s done"
+When the 
+.Cm flush
+command is specified, each routing table entry deleted
+is indicated with a message of this form.
+.It Sy "Network is unreachable"
+An attempt to add a route failed because the gateway listed was not
+on a directly-connected network.
+The next-hop gateway must be given.
+.It Sy "not in table"
+A delete operation was attempted for an entry which
+wasn't present in the tables.
+.It Sy "routing table overflow"
+An add operation was attempted, but the system was
+low on resources and was unable to allocate memory
+to create the new entry.
+.El
+.Sh SEE ALSO
+.Xr netintro 4 ,
+.Xr route 4 ,
+.Xr esis 4 ,
+.Xr routed 8 ,
+.Xr XNSrouted 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
+.Sh BUGS
+The first paragraph may have slightly exaggerated
+.Xr routed Ns 's
+abilities.
diff --git a/route.tproj/route.c b/route.tproj/route.c
new file mode 100644
index 0000000..9c53a27
--- /dev/null
+++ b/route.tproj/route.c
@@ -0,0 +1,1523 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1989, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1983, 1989, 1991, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)route.c	8.3 (Berkeley) 3/19/94";
+#endif
+static const char rcsid[] =
+	"$Id: route.c,v 1.1.1.2 2000/01/11 01:49:18 wsanchez Exp $";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+#include <netinet/in.h>
+#ifdef AT
+#include <netatalk/at.h>
+#endif
+#ifdef NS
+#include <netns/ns.h>
+#endif
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+struct keytab {
+	char	*kt_cp;
+	int	kt_i;
+} keywords[] = {
+#include "keywords.h"
+	{0, 0}
+};
+
+struct	ortentry route;
+union	sockunion {
+	struct	sockaddr sa;
+	struct	sockaddr_in sin;
+#ifdef AT
+	struct	sockaddr_at sat;
+#endif
+#ifdef NS
+	struct	sockaddr_ns sns;
+#endif
+	struct	sockaddr_dl sdl;
+} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
+
+typedef union sockunion *sup;
+int	pid, rtm_addrs, uid;
+int	s;
+int	forcehost, forcenet, doflush, nflag, af, qflag, tflag, keyword();
+int	iflag, verbose, aflen = sizeof (struct sockaddr_in);
+int	locking, lockrest, debugonly;
+struct	rt_metrics rt_metrics;
+u_long  rtm_inits;
+struct	in_addr inet_makeaddr();
+#ifdef AT
+int	atalk_aton __P((const char *, struct at_addr *));
+char	*atalk_ntoa __P((struct at_addr));
+#endif
+char	*routename(), *netname();
+void	flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();
+void	print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
+int	getaddr(), rtmsg(), x25_makemask();
+extern	char *inet_ntoa(), *iso_ntoa(), *link_ntoa();
+
+void usage __P((const char *));
+
+void
+usage(cp)
+	const char *cp;
+{
+	if (cp)
+		warnx("bad keyword: %s", cp);
+	(void) fprintf(stderr,
+	    "usage: route [-dnqtv] command [[modifiers] args]\n");
+	exit(EX_USAGE);
+	/* NOTREACHED */
+}
+
+#define ROUNDUP(a) \
+	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	int ch;
+
+	if (argc < 2)
+		usage((char *)NULL);
+
+	while ((ch = getopt(argc, argv, "nqdtv")) != -1)
+		switch(ch) {
+		case 'n':
+			nflag = 1;
+			break;
+		case 'q':
+			qflag = 1;
+			break;
+		case 'v':
+			verbose = 1;
+			break;
+		case 't':
+			tflag = 1;
+			break;
+		case 'd':
+			debugonly = 1;
+			break;
+		case '?':
+		default:
+			usage((char *)NULL);
+		}
+	argc -= optind;
+	argv += optind;
+
+	pid = getpid();
+	uid = getuid();
+	if (tflag)
+		s = open("/dev/null", O_WRONLY, 0);
+	else
+		s = socket(PF_ROUTE, SOCK_RAW, 0);
+	if (s < 0)
+		err(EX_OSERR, "socket");
+	setuid(uid);
+	if (*argv)
+		switch (keyword(*argv)) {
+		case K_GET:
+			uid = 0;
+			/* FALLTHROUGH */
+
+		case K_CHANGE:
+		case K_ADD:
+		case K_DELETE:
+			newroute(argc, argv);
+			exit(0);
+			/* NOTREACHED */
+
+		case K_MONITOR:
+			monitor();
+			/* NOTREACHED */
+
+		case K_FLUSH:
+			flushroutes(argc, argv);
+			exit(0);
+			/* NOTREACHED */
+		}
+	usage(*argv);
+	/* NOTREACHED */
+}
+
+/*
+ * Purge all entries in the routing tables not
+ * associated with network interfaces.
+ */
+void
+flushroutes(argc, argv)
+	int argc;
+	char *argv[];
+{
+	size_t needed;
+	int mib[6], rlen, seqno;
+	char *buf, *next, *lim;
+	register struct rt_msghdr *rtm;
+
+	if (uid) {
+		errx(EX_NOPERM, "must be root to alter routing table");
+	}
+	shutdown(s, 0); /* Don't want to read back our messages */
+	if (argc > 1) {
+		argv++;
+		if (argc == 2 && **argv == '-')
+		    switch (keyword(*argv + 1)) {
+			case K_INET:
+				af = AF_INET;
+				break;
+
+#ifdef
+			case K_ATALK:
+				af = AF_APPLETALK;
+				break;
+#endif
+#ifdef NS
+			case K_XNS:
+				af = AF_NS;
+				break;
+#endif
+			case K_LINK:
+				af = AF_LINK;
+				break;
+			default:
+				goto bad;
+		} else
+bad:			usage(*argv);
+	}
+	mib[0] = CTL_NET;
+	mib[1] = PF_ROUTE;
+	mib[2] = 0;		/* protocol */
+	mib[3] = 0;		/* wildcard address family */
+	mib[4] = NET_RT_DUMP;
+	mib[5] = 0;		/* no flags */
+	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+		err(EX_OSERR, "route-sysctl-estimate");
+	if ((buf = malloc(needed)) == NULL)
+		errx(EX_OSERR, "malloc failed");
+	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+		err(EX_OSERR, "route-sysctl-get");
+	lim = buf + needed;
+	if (verbose)
+		(void) printf("Examining routing table from sysctl\n");
+	seqno = 0;		/* ??? */
+	for (next = buf; next < lim; next += rtm->rtm_msglen) {
+		rtm = (struct rt_msghdr *)next;
+		if (verbose)
+			print_rtmsg(rtm, rtm->rtm_msglen);
+		if ((rtm->rtm_flags & RTF_GATEWAY) == 0)
+			continue;
+		if (af) {
+			struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
+
+			if (sa->sa_family != af)
+				continue;
+		}
+		if (debugonly)
+			continue;
+		rtm->rtm_type = RTM_DELETE;
+		rtm->rtm_seq = seqno;
+		rlen = write(s, next, rtm->rtm_msglen);
+		if (rlen < (int)rtm->rtm_msglen) {
+			warn("write to routing socket");
+			(void) printf("got only %d for rlen\n", rlen);
+			break;
+		}
+		seqno++;
+		if (qflag)
+			continue;
+		if (verbose)
+			print_rtmsg(rtm, rlen);
+		else {
+			struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
+			(void) printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ?
+			    routename(sa) : netname(sa));
+			sa = (struct sockaddr *)(sa->sa_len + (char *)sa);
+			(void) printf("%-20.20s ", routename(sa));
+			(void) printf("done\n");
+		}
+	}
+}
+
+char *
+routename(sa)
+	struct sockaddr *sa;
+{
+	register char *cp;
+	static char line[MAXHOSTNAMELEN + 1];
+	struct hostent *hp;
+	static char domain[MAXHOSTNAMELEN + 1];
+	static int first = 1;
+#ifdef NS
+	char *ns_print();
+#endif
+
+	if (first) {
+		first = 0;
+		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
+		    (cp = index(domain, '.'))) {
+			domain[MAXHOSTNAMELEN] = '\0';
+			(void) strcpy(domain, cp + 1);
+		} else
+			domain[0] = 0;
+	}
+
+	if (sa->sa_len == 0)
+		strcpy(line, "default");
+	else switch (sa->sa_family) {
+
+	case AF_INET:
+	    {	struct in_addr in;
+		in = ((struct sockaddr_in *)sa)->sin_addr;
+
+		cp = 0;
+		if (in.s_addr == INADDR_ANY || sa->sa_len < 4)
+			cp = "default";
+		if (cp == 0 && !nflag) {
+			hp = gethostbyaddr((char *)&in, sizeof (struct in_addr),
+				AF_INET);
+			if (hp) {
+				if ((cp = index(hp->h_name, '.')) &&
+				    !strcmp(cp + 1, domain))
+					*cp = 0;
+				cp = hp->h_name;
+			}
+		}
+		if (cp) {
+			strncpy(line, cp, sizeof(line) - 1);
+			line[sizeof(line) - 1] = '\0';
+		} else {
+			/* XXX - why not inet_ntoa()? */
+#define C(x)	(unsigned)((x) & 0xff)
+			in.s_addr = ntohl(in.s_addr);
+			(void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
+			   C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
+		}
+		break;
+	    }
+#ifdef AT
+	case AF_APPLETALK:
+		(void) snprintf(line, sizeof(line), "atalk %s",
+			atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr));
+		break;
+#endif
+#ifdef NS
+	case AF_NS:
+		return (ns_print((struct sockaddr_ns *)sa));
+#endif
+
+	case AF_LINK:
+		return (link_ntoa((struct sockaddr_dl *)sa));
+
+	default:
+	    {	u_short *s = (u_short *)sa;
+		u_short *slim = s + ((sa->sa_len + 1) >> 1);
+		char *cp = line + sprintf(line, "(%d)", sa->sa_family);
+		char *cpe = line + sizeof(line);
+
+		while (++s < slim && cp < cpe) /* start with sa->sa_data */
+			cp += snprintf(cp, cpe - cp, " %x", *s);
+		break;
+	    }
+	}
+	return (line);
+}
+
+/*
+ * Return the name of the network whose address is given.
+ * The address is assumed to be that of a net or subnet, not a host.
+ */
+char *
+netname(sa)
+	struct sockaddr *sa;
+{
+	char *cp = 0;
+	static char line[MAXHOSTNAMELEN + 1];
+	struct netent *np = 0;
+	u_long net, mask;
+	register u_long i;
+	int subnetshift;
+#ifdef NS
+	char *ns_print();
+#endif
+
+	switch (sa->sa_family) {
+
+	case AF_INET:
+	    {	struct in_addr in;
+		in = ((struct sockaddr_in *)sa)->sin_addr;
+
+		i = in.s_addr = ntohl(in.s_addr);
+		if (in.s_addr == 0)
+			cp = "default";
+		else if (!nflag) {
+			if (IN_CLASSA(i)) {
+				mask = IN_CLASSA_NET;
+				subnetshift = 8;
+			} else if (IN_CLASSB(i)) {
+				mask = IN_CLASSB_NET;
+				subnetshift = 8;
+			} else {
+				mask = IN_CLASSC_NET;
+				subnetshift = 4;
+			}
+			/*
+			 * If there are more bits than the standard mask
+			 * would suggest, subnets must be in use.
+			 * Guess at the subnet mask, assuming reasonable
+			 * width subnet fields.
+			 */
+			while (in.s_addr &~ mask)
+				mask = (long)mask >> subnetshift;
+			net = in.s_addr & mask;
+			while ((mask & 1) == 0)
+				mask >>= 1, net >>= 1;
+			np = getnetbyaddr(net, AF_INET);
+			if (np)
+				cp = np->n_name;
+		}
+		if (cp)
+			strncpy(line, cp, sizeof(line));
+		else if ((in.s_addr & 0xffffff) == 0)
+			(void) sprintf(line, "%u", C(in.s_addr >> 24));
+		else if ((in.s_addr & 0xffff) == 0)
+			(void) sprintf(line, "%u.%u", C(in.s_addr >> 24),
+			    C(in.s_addr >> 16));
+		else if ((in.s_addr & 0xff) == 0)
+			(void) sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
+			    C(in.s_addr >> 16), C(in.s_addr >> 8));
+		else
+			(void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
+			    C(in.s_addr >> 16), C(in.s_addr >> 8),
+			    C(in.s_addr));
+		break;
+	    }
+#ifdef AT
+	case AF_APPLETALK:
+		(void) snprintf(line, sizeof(line), "atalk %s",
+			atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr));
+		break;
+#endif
+#ifdef NS
+	case AF_NS:
+		return (ns_print((struct sockaddr_ns *)sa));
+		break;
+#endif
+
+	case AF_LINK:
+		return (link_ntoa((struct sockaddr_dl *)sa));
+
+
+	default:
+	    {	u_short *s = (u_short *)sa->sa_data;
+		u_short *slim = s + ((sa->sa_len + 1)>>1);
+		char *cp = line + sprintf(line, "af %d:", sa->sa_family);
+		char *cpe = line + sizeof(line);
+
+		while (s < slim && cp < cpe)
+			cp += snprintf(cp, cpe - cp, " %x", *s++);
+		break;
+	    }
+	}
+	return (line);
+}
+
+void
+set_metric(value, key)
+	char *value;
+	int key;
+{
+	int flag = 0;
+	u_long noval, *valp = &noval;
+
+	switch (key) {
+#define caseof(x, y, z)	case x: valp = &rt_metrics.z; flag = y; break
+	caseof(K_MTU, RTV_MTU, rmx_mtu);
+	caseof(K_HOPCOUNT, RTV_HOPCOUNT, rmx_hopcount);
+	caseof(K_EXPIRE, RTV_EXPIRE, rmx_expire);
+	caseof(K_RECVPIPE, RTV_RPIPE, rmx_recvpipe);
+	caseof(K_SENDPIPE, RTV_SPIPE, rmx_sendpipe);
+	caseof(K_SSTHRESH, RTV_SSTHRESH, rmx_ssthresh);
+	caseof(K_RTT, RTV_RTT, rmx_rtt);
+	caseof(K_RTTVAR, RTV_RTTVAR, rmx_rttvar);
+	}
+	rtm_inits |= flag;
+	if (lockrest || locking)
+		rt_metrics.rmx_locks |= flag;
+	if (locking)
+		locking = 0;
+	*valp = atoi(value);
+}
+
+void
+newroute(argc, argv)
+	int argc;
+	register char **argv;
+{
+	char *cmd, *dest = "", *gateway = "", *err;
+	int ishost = 0, ret, attempts, oerrno, flags = RTF_STATIC;
+	int key;
+	struct hostent *hp = 0;
+
+	if (uid) {
+		errx(EX_NOPERM, "must be root to alter routing table");
+	}
+	cmd = argv[0];
+	if (*cmd != 'g')
+		shutdown(s, 0); /* Don't want to read back our messages */
+	while (--argc > 0) {
+		if (**(++argv)== '-') {
+			switch (key = keyword(1 + *argv)) {
+			case K_LINK:
+				af = AF_LINK;
+				aflen = sizeof(struct sockaddr_dl);
+				break;
+			case K_INET:
+				af = AF_INET;
+				aflen = sizeof(struct sockaddr_in);
+				break;
+#ifdef AT
+			case K_ATALK:
+				af = AF_APPLETALK;
+				aflen = sizeof(struct sockaddr_at);
+				break;
+#endif
+			case K_SA:
+				af = PF_ROUTE;
+				aflen = sizeof(union sockunion);
+				break;
+#ifdef NS
+			case K_XNS:
+				af = AF_NS;
+				aflen = sizeof(struct sockaddr_ns);
+				break;
+#endif
+			case K_IFACE:
+			case K_INTERFACE:
+				iflag++;
+				break;
+			case K_NOSTATIC:
+				flags &= ~RTF_STATIC;
+				break;
+
+			case K_LLINFO:
+				flags |= RTF_LLINFO;
+				break;
+
+			case K_LOCK:
+				locking = 1;
+				break;
+			case K_LOCKREST:
+				lockrest = 1;
+				break;
+			case K_HOST:
+				forcehost++;
+				break;
+			case K_REJECT:
+				flags |= RTF_REJECT;
+				break;
+			case K_BLACKHOLE:
+				flags |= RTF_BLACKHOLE;
+				break;
+			case K_PROTO1:
+				flags |= RTF_PROTO1;
+				break;
+			case K_PROTO2:
+				flags |= RTF_PROTO2;
+				break;
+			case K_CLONING:
+				flags |= RTF_CLONING;
+				break;
+			case K_XRESOLVE:
+				flags |= RTF_XRESOLVE;
+				break;
+			case K_STATIC:
+				flags |= RTF_STATIC;
+				break;
+			case K_IFA:
+				argc--;
+				(void) getaddr(RTA_IFA, *++argv, 0);
+				break;
+			case K_IFP:
+				argc--;
+				(void) getaddr(RTA_IFP, *++argv, 0);
+				break;
+			case K_GENMASK:
+				argc--;
+				(void) getaddr(RTA_GENMASK, *++argv, 0);
+				break;
+			case K_GATEWAY:
+				argc--;
+				(void) getaddr(RTA_GATEWAY, *++argv, 0);
+				break;
+			case K_DST:
+				argc--;
+				ishost = getaddr(RTA_DST, *++argv, &hp);
+				dest = *argv;
+				break;
+			case K_NETMASK:
+				argc--;
+				(void) getaddr(RTA_NETMASK, *++argv, 0);
+				/* FALLTHROUGH */
+			case K_NET:
+				forcenet++;
+				break;
+			case K_MTU:
+			case K_HOPCOUNT:
+			case K_EXPIRE:
+			case K_RECVPIPE:
+			case K_SENDPIPE:
+			case K_SSTHRESH:
+			case K_RTT:
+			case K_RTTVAR:
+				argc--;
+				set_metric(*++argv, key);
+				break;
+			default:
+				usage(1+*argv);
+			}
+		} else {
+			if ((rtm_addrs & RTA_DST) == 0) {
+				dest = *argv;
+				ishost = getaddr(RTA_DST, *argv, &hp);
+			} else if ((rtm_addrs & RTA_GATEWAY) == 0) {
+				gateway = *argv;
+				(void) getaddr(RTA_GATEWAY, *argv, &hp);
+			} else {
+				(void) getaddr(RTA_NETMASK, *argv, 0);
+			}
+		}
+	}
+	if (forcehost)
+		ishost = 1;
+	if (forcenet)
+		ishost = 0;
+	flags |= RTF_UP;
+	if (ishost)
+		flags |= RTF_HOST;
+	if (iflag == 0)
+		flags |= RTF_GATEWAY;
+	for (attempts = 1; ; attempts++) {
+		errno = 0;
+		if ((ret = rtmsg(*cmd, flags)) == 0)
+			break;
+		if (errno != ENETUNREACH && errno != ESRCH)
+			break;
+		if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) {
+			hp->h_addr_list++;
+			bcopy(hp->h_addr_list[0], &so_gate.sin.sin_addr,
+			    MIN(hp->h_length, sizeof(so_gate.sin.sin_addr)));
+		} else
+			break;
+	}
+	if (*cmd == 'g')
+		exit(0);
+	oerrno = errno;
+	(void) printf("%s %s %s", cmd, ishost? "host" : "net", dest);
+	if (*gateway) {
+		(void) printf(": gateway %s", gateway);
+		if (attempts > 1 && ret == 0 && af == AF_INET)
+		    (void) printf(" (%s)",
+			inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr));
+	}
+	if (ret == 0)
+		(void) printf("\n");
+	else {
+		switch (oerrno) {
+		case ESRCH:
+			err = "not in table";
+			break;
+		case EBUSY:
+			err = "entry in use";
+			break;
+		case ENOBUFS:
+			err = "routing table overflow";
+			break;
+		default:
+			err = strerror(oerrno);
+			break;
+		}
+		(void) printf(": %s\n", err);
+	}
+}
+
+void
+inet_makenetandmask(net, sin, bits)
+	u_long net, bits;
+	register struct sockaddr_in *sin;
+{
+	u_long addr, mask = 0;
+	register char *cp;
+
+	rtm_addrs |= RTA_NETMASK;
+	if (net == 0)
+		mask = addr = 0;
+	else if (bits) {
+		addr = net;
+		mask = 0xffffffff << (32 - bits);
+	} else if (net < 128) {
+		addr = net << IN_CLASSA_NSHIFT;
+		mask = IN_CLASSA_NET;
+	} else if (net < 65536) {
+		addr = net << IN_CLASSB_NSHIFT;
+		mask = IN_CLASSB_NET;
+	} else if (net < 16777216L) {
+		addr = net << IN_CLASSC_NSHIFT;
+		mask = IN_CLASSC_NET;
+	} else {
+		addr = net;
+		if ((addr & IN_CLASSA_HOST) == 0)
+			mask =  IN_CLASSA_NET;
+		else if ((addr & IN_CLASSB_HOST) == 0)
+			mask =  IN_CLASSB_NET;
+		else if ((addr & IN_CLASSC_HOST) == 0)
+			mask =  IN_CLASSC_NET;
+		else
+			mask = -1;
+	}
+	sin->sin_addr.s_addr = htonl(addr);
+	sin = &so_mask.sin;
+	sin->sin_addr.s_addr = htonl(mask);
+	sin->sin_len = 0;
+	sin->sin_family = 0;
+	cp = (char *)(&sin->sin_addr + 1);
+	while (*--cp == 0 && cp > (char *)sin)
+		;
+	sin->sin_len = 1 + cp - (char *)sin;
+}
+
+/*
+ * Interpret an argument as a network address of some kind,
+ * returning 1 if a host address, 0 if a network address.
+ */
+int
+getaddr(which, s, hpp)
+	int which;
+	char *s;
+	struct hostent **hpp;
+{
+	register sup su;
+#ifdef NS
+	struct ns_addr ns_addr();
+#endif
+	struct hostent *hp;
+	struct netent *np;
+	u_long val;
+	char *q,qs;
+
+	if (af == 0) {
+		af = AF_INET;
+		aflen = sizeof(struct sockaddr_in);
+	}
+	rtm_addrs |= which;
+	switch (which) {
+	case RTA_DST:
+		su = &so_dst;
+		break;
+	case RTA_GATEWAY:
+		su = &so_gate;
+		if (iflag) {
+			#define MAX_IFACES	400
+			int			sock;
+			struct ifreq		iflist[MAX_IFACES];
+			struct ifconf		ifconf;
+			struct ifreq		*ifr, *ifr_end;
+			struct sockaddr_dl	*dl, *sdl = NULL;
+
+			/* Get socket */
+			if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
+				err(1, "socket");
+
+			/* Get interface list */
+			ifconf.ifc_req = iflist;
+			ifconf.ifc_len = sizeof(iflist);
+			if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0)
+				err(1, "ioctl(SIOCGIFCONF)");
+			close(sock);
+
+			/* Look for this interface in the list */
+			for (ifr = ifconf.ifc_req,
+			    ifr_end = (struct ifreq *)
+				(ifconf.ifc_buf + ifconf.ifc_len);
+			    ifr < ifr_end;
+			    ifr = (struct ifreq *) ((char *) &ifr->ifr_addr
+						    + ifr->ifr_addr.sa_len)) {
+				dl = (struct sockaddr_dl *)&ifr->ifr_addr;
+				if (ifr->ifr_addr.sa_family == AF_LINK
+				    && (ifr->ifr_flags & IFF_POINTOPOINT)
+				    && !strncmp(s, dl->sdl_data, dl->sdl_nlen)
+				    && s[dl->sdl_nlen] == 0) {
+					sdl = dl;
+					break;
+				}
+			}
+
+			/* If we found it, then use it */
+			if (sdl) {
+				su->sdl = *sdl;
+				return(1);
+			}
+		}
+		break;
+	case RTA_NETMASK:
+		su = &so_mask;
+		break;
+	case RTA_GENMASK:
+		su = &so_genmask;
+		break;
+	case RTA_IFP:
+		su = &so_ifp;
+		break;
+	case RTA_IFA:
+		su = &so_ifa;
+		break;
+	default:
+		usage("internal error");
+		/*NOTREACHED*/
+	}
+	su->sa.sa_len = aflen;
+	su->sa.sa_family = af; /* cases that don't want it have left already */
+	if (strcmp(s, "default") == 0) {
+		/*
+		 * Default is net 0.0.0.0/0 
+		 */
+		switch (which) {
+		case RTA_DST:
+			forcenet++;
+			/* bzero(su, sizeof(*su)); *//* for readability */
+			(void) getaddr(RTA_NETMASK, s, 0);
+			break;
+#if 0
+		case RTA_NETMASK:
+		case RTA_GENMASK:
+			/* bzero(su, sizeof(*su)); *//* for readability */
+#endif
+		}
+		return (0);
+	}
+	switch (af) {
+#ifdef NS
+	case AF_NS:
+		if (which == RTA_DST) {
+			extern short ns_bh[3];
+			struct sockaddr_ns *sms = &(so_mask.sns);
+			bzero((char *)sms, sizeof(*sms));
+			sms->sns_family = 0;
+			sms->sns_len = 6;
+			sms->sns_addr.x_net = *(union ns_net *)ns_bh;
+			rtm_addrs |= RTA_NETMASK;
+		}
+		su->sns.sns_addr = ns_addr(s);
+		return (!ns_nullhost(su->sns.sns_addr));
+#endif
+
+#ifdef AT
+	case AF_APPLETALK:
+		if (!atalk_aton(s, &su->sat.sat_addr))
+			errx(EX_NOHOST, "bad address: %s", s);
+		rtm_addrs |= RTA_NETMASK;
+		return(forcehost || su->sat.sat_addr.s_node != 0);
+#endif
+	case AF_LINK:
+		link_addr(s, &su->sdl);
+		return (1);
+
+
+	case PF_ROUTE:
+		su->sa.sa_len = sizeof(*su);
+		sockaddr(s, &su->sa);
+		return (1);
+
+	case AF_INET:
+	default:
+		break;
+	}
+
+	if (hpp == NULL)
+		hpp = &hp;
+	*hpp = NULL;
+
+	q = strchr(s,'/');
+	if (q && which == RTA_DST) {
+		qs = *q;
+		*q = '\0';
+		if (((val = inet_addr(s)) != INADDR_NONE)) {
+			inet_makenetandmask(
+				htonl(val), &su->sin, strtoul(q+1, 0, 0));
+			return (0);
+		}
+		*q =qs;
+	}
+	if (((val = inet_addr(s)) != INADDR_NONE) &&
+	    (which != RTA_DST || forcenet == 0)) {
+		su->sin.sin_addr.s_addr = val;
+		if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
+			return (1);
+		else {
+			val = ntohl(val);
+			goto netdone;
+		}
+	}
+	if ((val = inet_network(s)) != INADDR_NONE ||
+	    (forcehost == 0 && (np = getnetbyname(s)) != NULL &&
+		    (val = np->n_net) != 0)) {
+netdone:
+		if (which == RTA_DST)
+			inet_makenetandmask(val, &su->sin, 0);
+		return (0);
+	}
+	hp = gethostbyname(s);
+	if (hp) {
+		*hpp = hp;
+		su->sin.sin_family = hp->h_addrtype;
+		bcopy(hp->h_addr, (char *)&su->sin.sin_addr, 
+		    MIN(hp->h_length, sizeof(su->sin.sin_addr)));
+		return (1);
+	}
+	errx(EX_NOHOST, "bad address: %s", s);
+}
+
+
+#ifdef NS
+short ns_nullh[] = {0,0,0};
+short ns_bh[] = {-1,-1,-1};
+
+char *
+ns_print(sns)
+	struct sockaddr_ns *sns;
+{
+	struct ns_addr work;
+	union { union ns_net net_e; u_long long_e; } net;
+	u_short port;
+	static char mybuf[50+MAXHOSTNAMELEN], cport[10], chost[25];
+	char *host = "";
+	register char *p;
+	register u_char *q;
+
+	work = sns->sns_addr;
+	port = ntohs(work.x_port);
+	work.x_port = 0;
+	net.net_e  = work.x_net;
+	if (ns_nullhost(work) && net.long_e == 0) {
+		if (!port)
+			return ("*.*");
+		(void) sprintf(mybuf, "*.%XH", port);
+		return (mybuf);
+	}
+
+	if (bcmp((char *)ns_bh, (char *)work.x_host.c_host, 6) == 0)
+		host = "any";
+	else if (bcmp((char *)ns_nullh, (char *)work.x_host.c_host, 6) == 0)
+		host = "*";
+	else {
+		q = work.x_host.c_host;
+		(void) sprintf(chost, "%02X%02X%02X%02X%02X%02XH",
+			q[0], q[1], q[2], q[3], q[4], q[5]);
+		for (p = chost; *p == '0' && p < chost + 12; p++)
+			/* void */;
+		host = p;
+	}
+	if (port)
+		(void) sprintf(cport, ".%XH", htons(port));
+	else
+		*cport = 0;
+
+	(void) snprintf(mybuf, sizeof(mybuf), "%lxH.%s%s", 
+                    (unsigned long)ntohl(net.long_e),
+		       host, cport);
+	return (mybuf);
+}
+#endif
+
+void
+interfaces()
+{
+	size_t needed;
+	int mib[6];
+	char *buf, *lim, *next;
+	register struct rt_msghdr *rtm;
+
+	mib[0] = CTL_NET;
+	mib[1] = PF_ROUTE;
+	mib[2] = 0;		/* protocol */
+	mib[3] = 0;		/* wildcard address family */
+	mib[4] = NET_RT_IFLIST;
+	mib[5] = 0;		/* no flags */
+	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+		err(EX_OSERR, "route-sysctl-estimate");
+	if ((buf = malloc(needed)) == NULL)
+		errx(EX_OSERR, "malloc failed");
+	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+		err(EX_OSERR, "actual retrieval of interface table");
+	lim = buf + needed;
+	for (next = buf; next < lim; next += rtm->rtm_msglen) {
+		rtm = (struct rt_msghdr *)next;
+		print_rtmsg(rtm, rtm->rtm_msglen);
+	}
+}
+
+void
+monitor()
+{
+	int n;
+	char msg[2048];
+
+	verbose = 1;
+	if (debugonly) {
+		interfaces();
+		exit(0);
+	}
+	for(;;) {
+		n = read(s, msg, 2048);
+		(void) printf("got message of size %d\n", n);
+		print_rtmsg((struct rt_msghdr *)msg, n);
+	}
+}
+
+struct {
+	struct	rt_msghdr m_rtm;
+	char	m_space[512];
+} m_rtmsg;
+
+int
+rtmsg(cmd, flags)
+	int cmd, flags;
+{
+	static int seq;
+	int rlen;
+	register char *cp = m_rtmsg.m_space;
+	register int l;
+
+#define NEXTADDR(w, u) \
+	if (rtm_addrs & (w)) {\
+	    l = ROUNDUP(u.sa.sa_len); bcopy((char *)&(u), cp, l); cp += l;\
+	    if (verbose) sodump(&(u),"u");\
+	}
+
+	errno = 0;
+	bzero((char *)&m_rtmsg, sizeof(m_rtmsg));
+	if (cmd == 'a')
+		cmd = RTM_ADD;
+	else if (cmd == 'c')
+		cmd = RTM_CHANGE;
+	else if (cmd == 'g') {
+		cmd = RTM_GET;
+		if (so_ifp.sa.sa_family == 0) {
+			so_ifp.sa.sa_family = AF_LINK;
+			so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);
+			rtm_addrs |= RTA_IFP;
+		}
+	} else
+		cmd = RTM_DELETE;
+#define rtm m_rtmsg.m_rtm
+	rtm.rtm_type = cmd;
+	rtm.rtm_flags = flags;
+	rtm.rtm_version = RTM_VERSION;
+	rtm.rtm_seq = ++seq;
+	rtm.rtm_addrs = rtm_addrs;
+	rtm.rtm_rmx = rt_metrics;
+	rtm.rtm_inits = rtm_inits;
+
+	if (rtm_addrs & RTA_NETMASK)
+		mask_addr();
+	NEXTADDR(RTA_DST, so_dst);
+	NEXTADDR(RTA_GATEWAY, so_gate);
+	NEXTADDR(RTA_NETMASK, so_mask);
+	NEXTADDR(RTA_GENMASK, so_genmask);
+	NEXTADDR(RTA_IFP, so_ifp);
+	NEXTADDR(RTA_IFA, so_ifa);
+	rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
+	if (verbose)
+		print_rtmsg(&rtm, l);
+	if (debugonly)
+		return (0);
+	if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {
+		warn("writing to routing socket");
+		return (-1);
+	}
+	if (cmd == RTM_GET) {
+		do {
+			l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
+		} while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
+		if (l < 0)
+			warn("read from routing socket");
+		else
+			print_getmsg(&rtm, l);
+	}
+#undef rtm
+	return (0);
+}
+
+void
+mask_addr()
+{
+	int olen = so_mask.sa.sa_len;
+	register char *cp1 = olen + (char *)&so_mask, *cp2;
+
+	for (so_mask.sa.sa_len = 0; cp1 > (char *)&so_mask; )
+		if (*--cp1 != 0) {
+			so_mask.sa.sa_len = 1 + cp1 - (char *)&so_mask;
+			break;
+		}
+	if ((rtm_addrs & RTA_DST) == 0)
+		return;
+	switch (so_dst.sa.sa_family) {
+#ifdef NS
+	case AF_NS:
+#endif
+	case AF_INET:
+	case AF_APPLETALK:
+	case 0:
+		return;
+	}
+	cp1 = so_mask.sa.sa_len + 1 + (char *)&so_dst;
+	cp2 = so_dst.sa.sa_len + 1 + (char *)&so_dst;
+	while (cp2 > cp1)
+		*--cp2 = 0;
+	cp2 = so_mask.sa.sa_len + 1 + (char *)&so_mask;
+	while (cp1 > so_dst.sa.sa_data)
+		*--cp1 &= *--cp2;
+}
+
+char *msgtypes[] = {
+	"",
+	"RTM_ADD: Add Route",
+	"RTM_DELETE: Delete Route",
+	"RTM_CHANGE: Change Metrics or flags",
+	"RTM_GET: Report Metrics",
+	"RTM_LOSING: Kernel Suspects Partitioning",
+	"RTM_REDIRECT: Told to use different route",
+	"RTM_MISS: Lookup failed on this address",
+	"RTM_LOCK: fix specified metrics",
+	"RTM_OLDADD: caused by SIOCADDRT",
+	"RTM_OLDDEL: caused by SIOCDELRT",
+	"RTM_RESOLVE: Route created by cloning",
+	"RTM_NEWADDR: address being added to iface",
+	"RTM_DELADDR: address being removed from iface",
+	"RTM_IFINFO: iface status change",
+	"RTM_NEWMADDR: new multicast group membership on iface",
+	"RTM_DELMADDR: multicast group membership removed from iface",
+	0,
+};
+
+char metricnames[] =
+"\011pksent\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount"
+"\1mtu";
+char routeflags[] =
+"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT"
+"\011CLONING\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE\016b016"
+"\017PROTO2\020PROTO1\021PRCLONING\022WASCLONED\023PROTO3\024CHAINDELETE"
+"\025PINNED\026LOCAL\027BROADCAST\030MULTICAST";
+char ifnetflags[] =
+"\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6b6\7RUNNING\010NOARP"
+"\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1"
+"\017LINK2\020MULTICAST";
+char addrnames[] =
+"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
+
+void
+print_rtmsg(rtm, msglen)
+	register struct rt_msghdr *rtm;
+	int msglen;
+{
+	struct if_msghdr *ifm;
+	struct ifa_msghdr *ifam;
+#ifdef RTM_NEWMADDR
+	struct ifma_msghdr *ifmam;
+#endif
+
+	if (verbose == 0)
+		return;
+	if (rtm->rtm_version != RTM_VERSION) {
+		(void) printf("routing message version %d not understood\n",
+		    rtm->rtm_version);
+		return;
+	}
+	(void)printf("%s: len %d, ", msgtypes[rtm->rtm_type], rtm->rtm_msglen);
+	switch (rtm->rtm_type) {
+	case RTM_IFINFO:
+		ifm = (struct if_msghdr *)rtm;
+		(void) printf("if# %d, flags:", ifm->ifm_index);
+		bprintf(stdout, ifm->ifm_flags, ifnetflags);
+		pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs);
+		break;
+	case RTM_NEWADDR:
+	case RTM_DELADDR:
+		ifam = (struct ifa_msghdr *)rtm;
+		(void) printf("metric %d, flags:", ifam->ifam_metric);
+		bprintf(stdout, ifam->ifam_flags, routeflags);
+		pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs);
+		break;
+#ifdef RTM_NEWMADDR
+	case RTM_NEWMADDR:
+	case RTM_DELMADDR:
+		ifmam = (struct ifma_msghdr *)rtm;
+		pmsg_addrs((char *)(ifmam + 1), ifmam->ifmam_addrs);
+		break;
+#endif
+	default:
+		(void) printf("pid: %ld, seq %d, errno %d, flags:",
+			(long)rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno);
+		bprintf(stdout, rtm->rtm_flags, routeflags);
+		pmsg_common(rtm);
+	}
+}
+
+void
+print_getmsg(rtm, msglen)
+	register struct rt_msghdr *rtm;
+	int msglen;
+{
+	struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL;
+	struct sockaddr_dl *ifp = NULL;
+	register struct sockaddr *sa;
+	register char *cp;
+	register int i;
+
+	(void) printf("   route to: %s\n", routename(&so_dst));
+	if (rtm->rtm_version != RTM_VERSION) {
+		warnx("routing message version %d not understood",
+		     rtm->rtm_version);
+		return;
+	}
+	if (rtm->rtm_msglen > msglen) {
+		warnx("message length mismatch, in packet %d, returned %d",
+		      rtm->rtm_msglen, msglen);
+	}
+	if (rtm->rtm_errno)  {
+		errno = rtm->rtm_errno;
+		warn("message indicates error %d", errno);
+		return;
+	}
+	cp = ((char *)(rtm + 1));
+	if (rtm->rtm_addrs)
+		for (i = 1; i; i <<= 1)
+			if (i & rtm->rtm_addrs) {
+				sa = (struct sockaddr *)cp;
+				switch (i) {
+				case RTA_DST:
+					dst = sa;
+					break;
+				case RTA_GATEWAY:
+					gate = sa;
+					break;
+				case RTA_NETMASK:
+					mask = sa;
+					break;
+				case RTA_IFP:
+					if (sa->sa_family == AF_LINK &&
+					   ((struct sockaddr_dl *)sa)->sdl_nlen)
+						ifp = (struct sockaddr_dl *)sa;
+					break;
+				}
+				ADVANCE(cp, sa);
+			}
+	if (dst && mask)
+		mask->sa_family = dst->sa_family;	/* XXX */
+	if (dst)
+		(void)printf("destination: %s\n", routename(dst));
+	if (mask) {
+		int savenflag = nflag;
+
+		nflag = 1;
+		(void)printf("       mask: %s\n", routename(mask));
+		nflag = savenflag;
+	}
+	if (gate && rtm->rtm_flags & RTF_GATEWAY)
+		(void)printf("    gateway: %s\n", routename(gate));
+	if (ifp)
+		(void)printf("  interface: %.*s\n",
+		    ifp->sdl_nlen, ifp->sdl_data);
+	(void)printf("      flags: ");
+	bprintf(stdout, rtm->rtm_flags, routeflags);
+
+#define lock(f)	((rtm->rtm_rmx.rmx_locks & __CONCAT(RTV_,f)) ? 'L' : ' ')
+#define msec(u)	(((u) + 500) / 1000)		/* usec to msec */
+
+	(void) printf("\n%s\n", "\
+ recvpipe  sendpipe  ssthresh  rtt,msec    rttvar  hopcount      mtu     expire");
+	printf("%8ld%c ", rtm->rtm_rmx.rmx_recvpipe, lock(RPIPE));
+	printf("%8ld%c ", rtm->rtm_rmx.rmx_sendpipe, lock(SPIPE));
+	printf("%8ld%c ", rtm->rtm_rmx.rmx_ssthresh, lock(SSTHRESH));
+	printf("%8ld%c ", msec(rtm->rtm_rmx.rmx_rtt), lock(RTT));
+	printf("%8ld%c ", msec(rtm->rtm_rmx.rmx_rttvar), lock(RTTVAR));
+	printf("%8ld%c ", rtm->rtm_rmx.rmx_hopcount, lock(HOPCOUNT));
+	printf("%8ld%c ", rtm->rtm_rmx.rmx_mtu, lock(MTU));
+	if (rtm->rtm_rmx.rmx_expire)
+		rtm->rtm_rmx.rmx_expire -= time(0);
+	printf("%8ld%c\n", rtm->rtm_rmx.rmx_expire, lock(EXPIRE));
+#undef lock
+#undef msec
+#define	RTA_IGN	(RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD)
+	if (verbose)
+		pmsg_common(rtm);
+	else if (rtm->rtm_addrs &~ RTA_IGN) {
+		(void) printf("sockaddrs: ");
+		bprintf(stdout, rtm->rtm_addrs, addrnames);
+		putchar('\n');
+	}
+#undef	RTA_IGN
+}
+
+void
+pmsg_common(rtm)
+	register struct rt_msghdr *rtm;
+{
+	(void) printf("\nlocks: ");
+	bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames);
+	(void) printf(" inits: ");
+	bprintf(stdout, rtm->rtm_inits, metricnames);
+	pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs);
+}
+
+void
+pmsg_addrs(cp, addrs)
+	char	*cp;
+	int	addrs;
+{
+	register struct sockaddr *sa;
+	int i;
+
+	if (addrs == 0)
+		return;
+	(void) printf("\nsockaddrs: ");
+	bprintf(stdout, addrs, addrnames);
+	(void) putchar('\n');
+	for (i = 1; i; i <<= 1)
+		if (i & addrs) {
+			sa = (struct sockaddr *)cp;
+			(void) printf(" %s", routename(sa));
+			ADVANCE(cp, sa);
+		}
+	(void) putchar('\n');
+	(void) fflush(stdout);
+}
+
+void
+bprintf(fp, b, s)
+	register FILE *fp;
+	register int b;
+	register u_char *s;
+{
+	register int i;
+	int gotsome = 0;
+
+	if (b == 0)
+		return;
+	while ((i = *s++) != 0) {
+		if (b & (1 << (i-1))) {
+			if (gotsome == 0)
+				i = '<';
+			else
+				i = ',';
+			(void) putc(i, fp);
+			gotsome = 1;
+			for (; (i = *s) > 32; s++)
+				(void) putc(i, fp);
+		} else
+			while (*s > 32)
+				s++;
+	}
+	if (gotsome)
+		(void) putc('>', fp);
+}
+
+int
+keyword(cp)
+	char *cp;
+{
+	register struct keytab *kt = keywords;
+
+	while (kt->kt_cp && strcmp(kt->kt_cp, cp))
+		kt++;
+	return kt->kt_i;
+}
+
+void
+sodump(su, which)
+	register sup su;
+	char *which;
+{
+	switch (su->sa.sa_family) {
+	case AF_LINK:
+		(void) printf("%s: link %s; ",
+		    which, link_ntoa(&su->sdl));
+		break;
+	case AF_INET:
+		(void) printf("%s: inet %s; ",
+		    which, inet_ntoa(su->sin.sin_addr));
+		break;
+#ifdef AT
+	case AF_APPLETALK:
+		(void) printf("%s: atalk %s; ",
+		    which, atalk_ntoa(su->sat.sat_addr));
+		break;
+#endif
+#ifdef NS
+	case AF_NS:
+		(void) printf("%s: xns %s; ",
+		    which, ns_ntoa(su->sns.sns_addr));
+		break;
+#endif
+	}
+	(void) fflush(stdout);
+}
+
+/* States*/
+#define VIRGIN	0
+#define GOTONE	1
+#define GOTTWO	2
+/* Inputs */
+#define	DIGIT	(4*0)
+#define	END	(4*1)
+#define DELIM	(4*2)
+
+void
+sockaddr(addr, sa)
+	register char *addr;
+	register struct sockaddr *sa;
+{
+	register char *cp = (char *)sa;
+	int size = sa->sa_len;
+	char *cplim = cp + size;
+	register int byte = 0, state = VIRGIN, new = 0 /* foil gcc */;
+
+	bzero(cp, size);
+	cp++;
+	do {
+		if ((*addr >= '0') && (*addr <= '9')) {
+			new = *addr - '0';
+		} else if ((*addr >= 'a') && (*addr <= 'f')) {
+			new = *addr - 'a' + 10;
+		} else if ((*addr >= 'A') && (*addr <= 'F')) {
+			new = *addr - 'A' + 10;
+		} else if (*addr == 0)
+			state |= END;
+		else
+			state |= DELIM;
+		addr++;
+		switch (state /* | INPUT */) {
+		case GOTTWO | DIGIT:
+			*cp++ = byte; /*FALLTHROUGH*/
+		case VIRGIN | DIGIT:
+			state = GOTONE; byte = new; continue;
+		case GOTONE | DIGIT:
+			state = GOTTWO; byte = new + (byte << 4); continue;
+		default: /* | DELIM */
+			state = VIRGIN; *cp++ = byte; byte = 0; continue;
+		case GOTONE | END:
+		case GOTTWO | END:
+			*cp++ = byte; /* FALLTHROUGH */
+		case VIRGIN | END:
+			break;
+		}
+		break;
+	} while (cp < cplim);
+	sa->sa_len = cp - (char *)sa;
+}
+
+#ifdef AT
+int
+atalk_aton(const char *text, struct at_addr *addr)
+{
+	u_int net, node;
+
+	if (sscanf(text, "%u.%u", &net, &node) != 2
+	    || net > 0xffff || node > 0xff)
+		return(0);
+	addr->s_net = htons(net);
+	addr->s_node = node;
+	return(1);
+}
+
+char *
+atalk_ntoa(struct at_addr at)
+{
+	static char buf[20];
+
+	(void) snprintf(buf, sizeof(buf), "%u.%u", ntohs(at.s_net), at.s_node);
+	return(buf);
+}
+#endif
diff --git a/routed.tproj/Makefile b/routed.tproj/Makefile
new file mode 100644
index 0000000..78e1951
--- /dev/null
+++ b/routed.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = routed
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = af.h defs.h interface.h pathnames.h table.h trace.h
+
+CFILES = af.c defs.c if.c inet.c input.c main.c output.c startup.c\
+         tables.c timer.c trace.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.dist routed.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /sbin
+WINDOWS_INSTALLDIR = /sbin
+PDO_UNIX_INSTALLDIR = /sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/routed.tproj/Makefile.dist b/routed.tproj/Makefile.dist
new file mode 100644
index 0000000..d9dd7f8
--- /dev/null
+++ b/routed.tproj/Makefile.dist
@@ -0,0 +1,22 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/19/93
+
+PROG=	routed
+SRCS=	af.c if.c input.c main.c output.c startup.c tables.c timer.c \
+	trace.c inet.c
+MAN8=	routed.0
+#SUBDIR=	query trace
+DPADD=	${LIBCOMPAT}
+LDADD=	-lcompat
+
+.include <bsd.prog.mk>
+
+.if (${MACHINE} == "vax")
+# The following can be deleted where not appropriate to use the kernel's
+# inline code expansions.
+INLINE=	/sys/vax/inline/obj/inline
+C2=	/usr/libexec/c2
+.c.o:
+	${CC} -S ${CFLAGS} ${.CURDIR}/${.PREFIX}.c
+	@${C2} ${.PREFIX}.s | ${INLINE} | ${AS} -o ${.PREFIX}.o
+	@rm -f ${.PREFIX}.s
+.endif
diff --git a/routed.tproj/Makefile.preamble b/routed.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/routed.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/routed.tproj/PB.project b/routed.tproj/PB.project
new file mode 100644
index 0000000..23f9195
--- /dev/null
+++ b/routed.tproj/PB.project
@@ -0,0 +1,53 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (af.h, defs.h, interface.h, pathnames.h, table.h, trace.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (
+            af.c, 
+            defs.c, 
+            if.c, 
+            inet.c, 
+            input.c, 
+            main.c, 
+            output.c, 
+            startup.c, 
+            tables.c, 
+            timer.c, 
+            trace.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.dist, routed.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_MAINNIB = routed; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_MAINNIB = routed; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = routed; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_MAINNIB = routed; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/routed.tproj/af.c b/routed.tproj/af.c
new file mode 100644
index 0000000..a879b6c
--- /dev/null
+++ b/routed.tproj/af.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+#include "defs.h"
+
+/*
+ * Address family support routines
+ */
+int	inet_hash(), inet_netmatch(), inet_output(),
+	inet_portmatch(), inet_portcheck(),
+	inet_checkhost(), inet_rtflags(), inet_sendroute(), inet_canon();
+char	*inet_format();
+
+#define NIL	{ 0 }
+#define	INET \
+	{ inet_hash,		inet_netmatch,		inet_output, \
+	  inet_portmatch,	inet_portcheck,		inet_checkhost, \
+	  inet_rtflags,		inet_sendroute,		inet_canon, \
+	  inet_format \
+	}
+
+struct afswitch afswitch[AF_MAX] = {
+	NIL,		/* 0- unused */
+	NIL,		/* 1- Unix domain, unused */
+	INET,		/* Internet */
+};
+
+int af_max = sizeof(afswitch) / sizeof(afswitch[0]);
+
+struct sockaddr_in inet_default = {
+#ifdef RTM_ADD
+	sizeof (inet_default),
+#endif
+	AF_INET, INADDR_ANY };
+
+inet_hash(sin, hp)
+	register struct sockaddr_in *sin;
+	struct afhash *hp;
+{
+	register u_long n;
+
+	n = inet_netof(sin->sin_addr);
+	if (n)
+	    while ((n & 0xff) == 0)
+		n >>= 8;
+	hp->afh_nethash = n;
+	hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);
+	hp->afh_hosthash &= 0x7fffffff;
+}
+
+inet_netmatch(sin1, sin2)
+	struct sockaddr_in *sin1, *sin2;
+{
+
+	return (inet_netof(sin1->sin_addr) == inet_netof(sin2->sin_addr));
+}
+
+/*
+ * Verify the message is from the right port.
+ */
+inet_portmatch(sin)
+	register struct sockaddr_in *sin;
+{
+	
+	return (sin->sin_port == sp->s_port);
+}
+
+/*
+ * Verify the message is from a "trusted" port.
+ */
+inet_portcheck(sin)
+	struct sockaddr_in *sin;
+{
+
+	return (ntohs(sin->sin_port) <= IPPORT_RESERVED);
+}
+
+/*
+ * Internet output routine.
+ */
+inet_output(s, flags, sin, size)
+	int s, flags;
+	struct sockaddr_in *sin;
+	int size;
+{
+	struct sockaddr_in dst;
+
+	dst = *sin;
+	sin = &dst;
+	if (sin->sin_port == 0)
+		sin->sin_port = sp->s_port;
+	if (sin->sin_len == 0)
+		sin->sin_len = sizeof (*sin);
+	if (sendto(s, packet, size, flags,
+	    (struct sockaddr *)sin, sizeof (*sin)) < 0)
+		perror("sendto");
+}
+
+/*
+ * Return 1 if the address is believed
+ * for an Internet host -- THIS IS A KLUDGE.
+ */
+inet_checkhost(sin)
+	struct sockaddr_in *sin;
+{
+	u_long i = ntohl(sin->sin_addr.s_addr);
+
+#ifndef IN_EXPERIMENTAL
+#define	IN_EXPERIMENTAL(i)	(((long) (i) & 0xe0000000) == 0xe0000000)
+#endif
+
+	if (IN_EXPERIMENTAL(i) || sin->sin_port != 0)
+		return (0);
+	if (i != 0 && (i & 0xff000000) == 0)
+		return (0);
+	for (i = 0; i < sizeof(sin->sin_zero)/sizeof(sin->sin_zero[0]); i++)
+		if (sin->sin_zero[i])
+			return (0);
+	return (1);
+}
+
+inet_canon(sin)
+	struct sockaddr_in *sin;
+{
+
+	sin->sin_port = 0;
+	sin->sin_len = sizeof(*sin);
+}
+
+char *
+inet_format(sin)
+	struct sockaddr_in *sin;
+{
+	char *inet_ntoa();
+
+	return (inet_ntoa(sin->sin_addr));
+}
diff --git a/routed.tproj/af.h b/routed.tproj/af.h
new file mode 100644
index 0000000..02f48b0
--- /dev/null
+++ b/routed.tproj/af.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+/*
+ * Routing table management daemon.
+ */
+
+/*
+ * Per address family routines.
+ */
+struct afswitch {
+	int	(*af_hash)();		/* returns keys based on address */
+	int	(*af_netmatch)();	/* verifies net # matching */
+	int	(*af_output)();		/* interprets address for sending */
+	int	(*af_portmatch)();	/* packet from some other router? */
+	int	(*af_portcheck)();	/* packet from privileged peer? */
+	int	(*af_checkhost)();	/* tells if address is valid */
+	int	(*af_rtflags)();	/* get flags for route (host or net) */
+	int	(*af_sendroute)();	/* check bounds of subnet broadcast */
+	int	(*af_canon)();		/* canonicalize address for compares */
+	char	*(*af_format)();	/* convert address to string */
+};
+
+/*
+ * Structure returned by af_hash routines.
+ */
+struct afhash {
+	u_int	afh_hosthash;		/* host based hash */
+	u_int	afh_nethash;		/* network based hash */
+};
+
+extern struct	afswitch afswitch[];	/* table proper */
+extern int	af_max;			/* number of entries in table */
diff --git a/routed.tproj/defs.c b/routed.tproj/defs.c
new file mode 100644
index 0000000..5b176bc
--- /dev/null
+++ b/routed.tproj/defs.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* NeXT */
+#define EXTERN
+#include "defs.h"
diff --git a/routed.tproj/defs.h b/routed.tproj/defs.h
new file mode 100644
index 0000000..fad0ae1
--- /dev/null
+++ b/routed.tproj/defs.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+/*
+ * Internal data structure definitions for
+ * user routing process.  Based on Xerox NS
+ * protocol specs with mods relevant to more
+ * general addressing scheme.
+ */
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <net/route.h>
+#include <netinet/in.h>
+#include <protocols/routed.h>
+
+#include <stdio.h>
+#include <netdb.h>
+
+/* NeXT */
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+#include "trace.h"
+#include "interface.h"
+#include "table.h"
+#include "af.h"
+
+/*
+ * When we find any interfaces marked down we rescan the
+ * kernel every CHECK_INTERVAL seconds to see if they've
+ * come up.
+ */
+#define	CHECK_INTERVAL	(1*60)
+
+#define equal(a1, a2) \
+	(memcmp((a1), (a2), sizeof (struct sockaddr)) == 0)
+
+EXTERN struct	sockaddr_in addr;	/* address of daemon's socket */
+
+EXTERN int	s;			/* source and sink of all data */
+EXTERN int	r;			/* routing socket */
+EXTERN pid_t	pid;			/* process id for identifying messages */
+EXTERN uid_t	uid;			/* user id for identifying messages */
+EXTERN int	seqno;			/* sequence number for identifying messages */
+EXTERN int	kmem;
+extern int	supplier;		/* process should supply updates */
+extern int	install;		/* if 1 call kernel */
+extern int	lookforinterfaces;	/* if 1 probe kernel for new up interfaces */
+EXTERN int	performnlist;		/* if 1 check if /vmunix has changed */
+extern int	externalinterfaces;	/* # of remote and local interfaces */
+EXTERN struct	timeval now;		/* current idea of time */
+EXTERN struct	timeval lastbcast;	/* last time all/changes broadcast */
+EXTERN struct	timeval lastfullupdate;	/* last time full table broadcast */
+EXTERN struct	timeval nextbcast;	/* time to wait before changes broadcast */
+EXTERN int	needupdate;		/* true if we need update at nextbcast */
+
+EXTERN char	packet[MAXPACKETSIZE+1];
+extern struct	rip *msg;
+
+EXTERN char	**argv0;
+EXTERN struct	servent *sp;
+
+EXTERN struct	in_addr inet_makeaddr();
+EXTERN int	inet_addr();
+EXTERN int	inet_maskof();
+EXTERN int	sndmsg();
+EXTERN int	supply();
+EXTERN int	cleanup();
+
+EXTERN int	rtioctl();
+#define ADD 1
+#define DELETE 2
+#define CHANGE 3
diff --git a/routed.tproj/if.c b/routed.tproj/if.c
new file mode 100644
index 0000000..5235d58
--- /dev/null
+++ b/routed.tproj/if.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "defs.h"
+
+extern	struct interface *ifnet;
+
+/*
+ * Find the interface with address addr.
+ */
+struct interface *
+if_ifwithaddr(addr)
+	struct sockaddr *addr;
+{
+	register struct interface *ifp;
+
+#define	same(a1, a2) \
+	(memcmp((a1)->sa_data, (a2)->sa_data, 14) == 0)
+	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
+		if (ifp->int_flags & IFF_REMOTE)
+			continue;
+		if (ifp->int_addr.sa_family != addr->sa_family)
+			continue;
+		if (same(&ifp->int_addr, addr))
+			break;
+		if ((ifp->int_flags & IFF_BROADCAST) &&
+		    same(&ifp->int_broadaddr, addr))
+			break;
+	}
+	return (ifp);
+}
+
+/*
+ * Find the point-to-point interface with destination address addr.
+ */
+struct interface *
+if_ifwithdstaddr(addr)
+	struct sockaddr *addr;
+{
+	register struct interface *ifp;
+
+	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
+		if ((ifp->int_flags & IFF_POINTOPOINT) == 0)
+			continue;
+		if (same(&ifp->int_dstaddr, addr))
+			break;
+	}
+	return (ifp);
+}
+
+/*
+ * Find the interface on the network 
+ * of the specified address.
+ */
+struct interface *
+if_ifwithnet(addr)
+	register struct sockaddr *addr;
+{
+	register struct interface *ifp;
+	register int af = addr->sa_family;
+	register int (*netmatch)();
+
+	if (af >= af_max)
+		return (0);
+	netmatch = afswitch[af].af_netmatch;
+	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
+		if (ifp->int_flags & IFF_REMOTE)
+			continue;
+		if (af != ifp->int_addr.sa_family)
+			continue;
+		if ((*netmatch)(addr, &ifp->int_addr))
+			break;
+	}
+	return (ifp);
+}
+
+/*
+ * Find an interface from which the specified address
+ * should have come from.  Used for figuring out which
+ * interface a packet came in on -- for tracing.
+ */
+struct interface *
+if_iflookup(addr)
+	struct sockaddr *addr;
+{
+	register struct interface *ifp, *maybe;
+	register int af = addr->sa_family;
+	register int (*netmatch)();
+
+	if (af >= af_max)
+		return (0);
+	maybe = 0;
+	netmatch = afswitch[af].af_netmatch;
+	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
+		if (ifp->int_addr.sa_family != af)
+			continue;
+		if (same(&ifp->int_addr, addr))
+			break;
+		if ((ifp->int_flags & IFF_BROADCAST) &&
+		    same(&ifp->int_broadaddr, addr))
+			break;
+		if ((ifp->int_flags & IFF_POINTOPOINT) &&
+		    same(&ifp->int_dstaddr, addr))
+			break;
+		if (maybe == 0 && (*netmatch)(addr, &ifp->int_addr))
+			maybe = ifp;
+	}
+	if (ifp == 0)
+		ifp = maybe;
+	return (ifp);
+}
diff --git a/routed.tproj/inet.c b/routed.tproj/inet.c
new file mode 100644
index 0000000..ef194a8
--- /dev/null
+++ b/routed.tproj/inet.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+/*
+ * Temporarily, copy these routines from the kernel,
+ * as we need to know about subnets.
+ */
+#include "defs.h"
+
+extern struct interface *ifnet;
+
+/*
+ * Formulate an Internet address from network + host.
+ */
+__private_extern__
+struct in_addr
+inet_makeaddr(net, host)
+	u_long net, host;
+{
+	register struct interface *ifp;
+	register u_long mask;
+	u_long addr;
+
+	if (IN_CLASSA(net))
+		mask = IN_CLASSA_HOST;
+	else if (IN_CLASSB(net))
+		mask = IN_CLASSB_HOST;
+	else
+		mask = IN_CLASSC_HOST;
+	for (ifp = ifnet; ifp; ifp = ifp->int_next)
+		if ((ifp->int_netmask & net) == ifp->int_net) {
+			mask = ~ifp->int_subnetmask;
+			break;
+		}
+	addr = net | (host & mask);
+	addr = htonl(addr);
+	return (*(struct in_addr *)&addr);
+}
+
+/*
+ * Return the network number from an internet address.
+ */
+__private_extern__
+inet_netof(in)
+	struct in_addr in;
+{
+	register u_long i = ntohl(in.s_addr);
+	register u_long net;
+	register struct interface *ifp;
+
+	if (IN_CLASSA(i))
+		net = i & IN_CLASSA_NET;
+	else if (IN_CLASSB(i))
+		net = i & IN_CLASSB_NET;
+	else
+		net = i & IN_CLASSC_NET;
+
+	/*
+	 * Check whether network is a subnet;
+	 * if so, return subnet number.
+	 */
+	for (ifp = ifnet; ifp; ifp = ifp->int_next)
+		if ((ifp->int_netmask & net) == ifp->int_net)
+			return (i & ifp->int_subnetmask);
+	return (net);
+}
+
+/*
+ * Return the host portion of an internet address.
+ */
+inet_lnaof(in)
+	struct in_addr in;
+{
+	register u_long i = ntohl(in.s_addr);
+	register u_long net, host;
+	register struct interface *ifp;
+
+	if (IN_CLASSA(i)) {
+		net = i & IN_CLASSA_NET;
+		host = i & IN_CLASSA_HOST;
+	} else if (IN_CLASSB(i)) {
+		net = i & IN_CLASSB_NET;
+		host = i & IN_CLASSB_HOST;
+	} else {
+		net = i & IN_CLASSC_NET;
+		host = i & IN_CLASSC_HOST;
+	}
+
+	/*
+	 * Check whether network is a subnet;
+	 * if so, use the modified interpretation of `host'.
+	 */
+	for (ifp = ifnet; ifp; ifp = ifp->int_next)
+		if ((ifp->int_netmask & net) == ifp->int_net)
+			return (host &~ ifp->int_subnetmask);
+	return (host);
+}
+
+/*
+ * Return the netmask pertaining to an internet address.
+ */
+inet_maskof(inaddr)
+	u_long inaddr;
+{
+	register u_long i = ntohl(inaddr);
+	register u_long mask;
+	register struct interface *ifp;
+
+	if (i == 0) {
+		mask = 0;
+	} else if (IN_CLASSA(i)) {
+		mask = IN_CLASSA_NET;
+	} else if (IN_CLASSB(i)) {
+		mask = IN_CLASSB_NET;
+	} else
+		mask = IN_CLASSC_NET;
+
+	/*
+	 * Check whether network is a subnet;
+	 * if so, use the modified interpretation of `host'.
+	 */
+	for (ifp = ifnet; ifp; ifp = ifp->int_next)
+		if ((ifp->int_netmask & i) == ifp->int_net)
+			mask = ifp->int_subnetmask;
+	return (htonl(mask));
+}
+
+/*
+ * Return RTF_HOST if the address is
+ * for an Internet host, RTF_SUBNET for a subnet,
+ * 0 for a network.
+ */
+inet_rtflags(sin)
+	struct sockaddr_in *sin;
+{
+	register u_long i = ntohl(sin->sin_addr.s_addr);
+	register u_long net, host;
+	register struct interface *ifp;
+
+	if (IN_CLASSA(i)) {
+		net = i & IN_CLASSA_NET;
+		host = i & IN_CLASSA_HOST;
+	} else if (IN_CLASSB(i)) {
+		net = i & IN_CLASSB_NET;
+		host = i & IN_CLASSB_HOST;
+	} else {
+		net = i & IN_CLASSC_NET;
+		host = i & IN_CLASSC_HOST;
+	}
+
+	/*
+	 * Check whether this network is subnetted;
+	 * if so, check whether this is a subnet or a host.
+	 */
+	for (ifp = ifnet; ifp; ifp = ifp->int_next)
+		if (net == ifp->int_net) {
+			if (host &~ ifp->int_subnetmask)
+				return (RTF_HOST);
+			else if (ifp->int_subnetmask != ifp->int_netmask)
+				return (RTF_SUBNET);
+			else
+				return (0);		/* network */
+		}
+	if (host == 0)
+		return (0);	/* network */
+	else
+		return (RTF_HOST);
+}
+
+/*
+ * Return true if a route to subnet/host of route rt should be sent to dst.
+ * Send it only if dst is on the same logical network if not "internal",
+ * otherwise only if the route is the "internal" route for the logical net.
+ */
+inet_sendroute(rt, dst)
+	struct rt_entry *rt;
+	struct sockaddr_in *dst;
+{
+	register u_long r =
+	    ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr);
+	register u_long d = ntohl(dst->sin_addr.s_addr);
+
+	if (IN_CLASSA(r)) {
+		if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) {
+			if ((r & IN_CLASSA_HOST) == 0)
+				return ((rt->rt_state & RTS_INTERNAL) == 0);
+			return (1);
+		}
+		if (r & IN_CLASSA_HOST)
+			return (0);
+		return ((rt->rt_state & RTS_INTERNAL) != 0);
+	} else if (IN_CLASSB(r)) {
+		if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) {
+			if ((r & IN_CLASSB_HOST) == 0)
+				return ((rt->rt_state & RTS_INTERNAL) == 0);
+			return (1);
+		}
+		if (r & IN_CLASSB_HOST)
+			return (0);
+		return ((rt->rt_state & RTS_INTERNAL) != 0);
+	} else {
+		if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) {
+			if ((r & IN_CLASSC_HOST) == 0)
+				return ((rt->rt_state & RTS_INTERNAL) == 0);
+			return (1);
+		}
+		if (r & IN_CLASSC_HOST)
+			return (0);
+		return ((rt->rt_state & RTS_INTERNAL) != 0);
+	}
+}
diff --git a/routed.tproj/input.c b/routed.tproj/input.c
new file mode 100644
index 0000000..d39615f
--- /dev/null
+++ b/routed.tproj/input.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "defs.h"
+#include <sys/syslog.h>
+
+/*
+ * Process a newly received packet.
+ */
+rip_input(from, rip, size)
+	struct sockaddr *from;
+	register struct rip *rip;
+	int size;
+{
+	register struct rt_entry *rt;
+	register struct netinfo *n;
+	register struct interface *ifp;
+	struct interface *if_ifwithdstaddr();
+	int count, changes = 0;
+	register struct afswitch *afp;
+	static struct sockaddr badfrom, badfrom2;
+
+	ifp = 0;
+	TRACE_INPUT(ifp, from, (char *)rip, size);
+	if (from->sa_family >= af_max ||
+	    (afp = &afswitch[from->sa_family])->af_hash == (int (*)())0) {
+		syslog(LOG_INFO,
+	 "\"from\" address in unsupported address family (%d), cmd %d\n",
+		    from->sa_family, rip->rip_cmd);
+		return;
+	}
+	if (rip->rip_vers == 0) {
+		syslog(LOG_ERR,
+		    "RIP version 0 packet received from %s! (cmd %d)",
+		    (*afswitch[from->sa_family].af_format)(from), rip->rip_cmd);
+		return;
+	}
+	switch (rip->rip_cmd) {
+
+	case RIPCMD_REQUEST:
+		n = rip->rip_nets;
+		count = size - ((char *)n - (char *)rip);
+		if (count < sizeof (struct netinfo))
+			return;
+		for (; count > 0; n++) {
+			if (count < sizeof (struct netinfo))
+				break;
+			count -= sizeof (struct netinfo);
+
+#if BSD < 198810
+			if (sizeof(n->rip_dst.sa_family) > 1)	/* XXX */
+			    n->rip_dst.sa_family = ntohs(n->rip_dst.sa_family);
+#else
+#define osa(x) ((struct osockaddr *)(&(x)))
+			    n->rip_dst.sa_family =
+					ntohs(osa(n->rip_dst)->sa_family);
+			    n->rip_dst.sa_len = sizeof(n->rip_dst);
+#endif
+			n->rip_metric = ntohl(n->rip_metric);
+			/* 
+			 * A single entry with sa_family == AF_UNSPEC and
+			 * metric ``infinity'' means ``all routes''.
+			 * We respond to routers only if we are acting
+			 * as a supplier, or to anyone other than a router
+			 * (eg, query).
+			 */
+			if (n->rip_dst.sa_family == AF_UNSPEC &&
+			    n->rip_metric == HOPCNT_INFINITY && count == 0) {
+			    	if (supplier || (*afp->af_portmatch)(from) == 0)
+					supply(from, 0, 0, 0);
+				return;
+			}
+			if (n->rip_dst.sa_family < af_max &&
+			    afswitch[n->rip_dst.sa_family].af_hash)
+				rt = rtlookup(&n->rip_dst);
+			else
+				rt = 0;
+#define min(a, b) (a < b ? a : b)
+			n->rip_metric = rt == 0 ? HOPCNT_INFINITY :
+				min(rt->rt_metric + 1, HOPCNT_INFINITY);
+#if BSD < 198810
+			if (sizeof(n->rip_dst.sa_family) > 1)	/* XXX */
+			    n->rip_dst.sa_family = htons(n->rip_dst.sa_family);
+#else
+			    osa(n->rip_dst)->sa_family =
+						htons(n->rip_dst.sa_family);
+#endif
+			n->rip_metric = htonl(n->rip_metric);
+		}
+		rip->rip_cmd = RIPCMD_RESPONSE;
+		memmove(packet, rip, size);
+		(*afp->af_output)(s, 0, from, size);
+		return;
+
+	case RIPCMD_TRACEON:
+	case RIPCMD_TRACEOFF:
+		/* verify message came from a privileged port */
+		if ((*afp->af_portcheck)(from) == 0)
+			return;
+		if ((ifp = if_iflookup(from)) == 0 || (ifp->int_flags &
+		    (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0 ||
+		    ifp->int_flags & IFF_PASSIVE) {
+			syslog(LOG_ERR, "trace command from unknown router, %s",
+			    (*afswitch[from->sa_family].af_format)(from));
+			return;
+		}
+		((char *)rip)[size] = '\0';
+		if (rip->rip_cmd == RIPCMD_TRACEON)
+			traceon(rip->rip_tracefile);
+		else
+			traceoff();
+		return;
+
+	case RIPCMD_RESPONSE:
+		/* verify message came from a router */
+		if ((*afp->af_portmatch)(from) == 0)
+			return;
+		(*afp->af_canon)(from);
+		/* are we talking to ourselves? */
+		ifp = if_ifwithaddr(from);
+		if (ifp) {
+			if (ifp->int_flags & IFF_PASSIVE) {
+				syslog(LOG_ERR,
+				  "bogus input (from passive interface, %s)",
+				  (*afswitch[from->sa_family].af_format)(from));
+				return;
+			}
+			rt = rtfind(from);
+			if (rt == 0 || ((rt->rt_state & RTS_INTERFACE) == 0) &&
+			    rt->rt_metric >= ifp->int_metric) 
+				addrouteforif(ifp);
+			else
+				rt->rt_timer = 0;
+			return;
+		}
+		/*
+		 * Update timer for interface on which the packet arrived.
+		 * If from other end of a point-to-point link that isn't
+		 * in the routing tables, (re-)add the route.
+		 */
+		if ((rt = rtfind(from)) &&
+		    (rt->rt_state & (RTS_INTERFACE | RTS_REMOTE)))
+			rt->rt_timer = 0;
+		else if ((ifp = if_ifwithdstaddr(from)) &&
+		    (rt == 0 || rt->rt_metric >= ifp->int_metric))
+			addrouteforif(ifp);
+		/*
+		 * "Authenticate" router from which message originated.
+		 * We accept routing packets from routers directly connected
+		 * via broadcast or point-to-point networks,
+		 * and from those listed in /etc/gateways.
+		 */
+		if ((ifp = if_iflookup(from)) == 0 || (ifp->int_flags &
+		    (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0 ||
+		    ifp->int_flags & IFF_PASSIVE) {
+			if (memcmp(from, &badfrom, sizeof(badfrom)) != 0) {
+				syslog(LOG_ERR,
+				  "packet from unknown router, %s",
+				  (*afswitch[from->sa_family].af_format)(from));
+				badfrom = *from;
+			}
+			return;
+		}
+		size -= 4 * sizeof (char);
+		n = rip->rip_nets;
+		for (; size > 0; size -= sizeof (struct netinfo), n++) {
+			if (size < sizeof (struct netinfo))
+				break;
+#if BSD < 198810
+			if (sizeof(n->rip_dst.sa_family) > 1)	/* XXX */
+				n->rip_dst.sa_family =
+					ntohs(n->rip_dst.sa_family);
+#else
+			    n->rip_dst.sa_family =
+					ntohs(osa(n->rip_dst)->sa_family);
+			    n->rip_dst.sa_len = sizeof(n->rip_dst);
+#endif
+			n->rip_metric = ntohl(n->rip_metric);
+			if (n->rip_dst.sa_family >= af_max ||
+			    (afp = &afswitch[n->rip_dst.sa_family])->af_hash ==
+			    (int (*)())0) {
+				syslog(LOG_INFO,
+		"route in unsupported address family (%d), from %s (af %d)\n",
+				   n->rip_dst.sa_family,
+				   (*afswitch[from->sa_family].af_format)(from),
+				   from->sa_family);
+				continue;
+			}
+			if (((*afp->af_checkhost)(&n->rip_dst)) == 0) {
+				syslog(LOG_DEBUG,
+				    "bad host in route from %s (af %d)\n",
+				   (*afswitch[from->sa_family].af_format)(from),
+				   from->sa_family);
+				continue;
+			}
+			if (n->rip_metric == 0 ||
+			    (unsigned) n->rip_metric > HOPCNT_INFINITY) {
+				if (memcmp(from, &badfrom2,
+				    sizeof(badfrom2)) != 0) {
+					syslog(LOG_ERR,
+					    "bad metric (%d) from %s\n",
+					    n->rip_metric,
+				  (*afswitch[from->sa_family].af_format)(from));
+					badfrom2 = *from;
+				}
+				continue;
+			}
+			/*
+			 * Adjust metric according to incoming interface.
+			 */
+			if ((unsigned) n->rip_metric < HOPCNT_INFINITY)
+				n->rip_metric += ifp->int_metric;
+			if ((unsigned) n->rip_metric > HOPCNT_INFINITY)
+				n->rip_metric = HOPCNT_INFINITY;
+			rt = rtlookup(&n->rip_dst);
+			if (rt == 0 ||
+			    (rt->rt_state & (RTS_INTERNAL|RTS_INTERFACE)) ==
+			    (RTS_INTERNAL|RTS_INTERFACE)) {
+				/*
+				 * If we're hearing a logical network route
+				 * back from a peer to which we sent it,
+				 * ignore it.
+				 */
+				if (rt && rt->rt_state & RTS_SUBNET &&
+				    (*afp->af_sendroute)(rt, from))
+					continue;
+				if ((unsigned)n->rip_metric < HOPCNT_INFINITY) {
+				    /*
+				     * Look for an equivalent route that
+				     * includes this one before adding
+				     * this route.
+				     */
+				    rt = rtfind(&n->rip_dst);
+				    if (rt && equal(from, &rt->rt_router))
+					    continue;
+				    rtadd(&n->rip_dst, from, n->rip_metric, 0);
+				    changes++;
+				}
+				continue;
+			}
+
+			/*
+			 * Update if from gateway and different,
+			 * shorter, or equivalent but old route
+			 * is getting stale.
+			 */
+			if (equal(from, &rt->rt_router)) {
+				if (n->rip_metric != rt->rt_metric) {
+					rtchange(rt, from, n->rip_metric);
+					changes++;
+					rt->rt_timer = 0;
+					if (rt->rt_metric >= HOPCNT_INFINITY)
+						rt->rt_timer =
+						    GARBAGE_TIME - EXPIRE_TIME;
+				} else if (rt->rt_metric < HOPCNT_INFINITY)
+					rt->rt_timer = 0;
+			} else if ((unsigned) n->rip_metric < rt->rt_metric ||
+			    (rt->rt_metric == n->rip_metric &&
+			    rt->rt_timer > (EXPIRE_TIME/2) &&
+			    (unsigned) n->rip_metric < HOPCNT_INFINITY)) {
+				rtchange(rt, from, n->rip_metric);
+				changes++;
+				rt->rt_timer = 0;
+			}
+		}
+		break;
+	}
+
+	/*
+	 * If changes have occurred, and if we have not sent a broadcast
+	 * recently, send a dynamic update.  This update is sent only
+	 * on interfaces other than the one on which we received notice
+	 * of the change.  If we are within MIN_WAITTIME of a full update,
+	 * don't bother sending; if we just sent a dynamic update
+	 * and set a timer (nextbcast), delay until that time.
+	 * If we just sent a full update, delay the dynamic update.
+	 * Set a timer for a randomized value to suppress additional
+	 * dynamic updates until it expires; if we delayed sending
+	 * the current changes, set needupdate.
+	 */
+	if (changes && supplier &&
+	   now.tv_sec - lastfullupdate.tv_sec < SUPPLY_INTERVAL-MAX_WAITTIME) {
+		u_long delay;
+		extern long random();
+
+		if (now.tv_sec - lastbcast.tv_sec >= MIN_WAITTIME &&
+		    timercmp(&nextbcast, &now, <)) {
+			if (traceactions)
+				fprintf(ftrace, "send dynamic update\n");
+			toall(supply, RTS_CHANGED, ifp);
+			lastbcast = now;
+			needupdate = 0;
+			nextbcast.tv_sec = 0;
+		} else {
+			needupdate++;
+			if (traceactions)
+				fprintf(ftrace, "delay dynamic update\n");
+		}
+#define RANDOMDELAY()	(MIN_WAITTIME * 1000000 + \
+		(u_long)random() % ((MAX_WAITTIME - MIN_WAITTIME) * 1000000))
+
+		if (nextbcast.tv_sec == 0) {
+			delay = RANDOMDELAY();
+			if (traceactions)
+				fprintf(ftrace,
+				    "inhibit dynamic update for %d usec\n",
+				    delay);
+			nextbcast.tv_sec = delay / 1000000;
+			nextbcast.tv_usec = delay % 1000000;
+			timevaladd(&nextbcast, &now);
+			/*
+			 * If the next possibly dynamic update
+			 * is within MIN_WAITTIME of the next full update,
+			 * force the delay past the full update,
+			 * or we might send a dynamic update just before
+			 * the full update.
+			 */
+			if (nextbcast.tv_sec > lastfullupdate.tv_sec +
+			    SUPPLY_INTERVAL - MIN_WAITTIME)
+				nextbcast.tv_sec = lastfullupdate.tv_sec +
+				    SUPPLY_INTERVAL + 1;
+		}
+	}
+}
diff --git a/routed.tproj/interface.h b/routed.tproj/interface.h
new file mode 100644
index 0000000..8e2df84
--- /dev/null
+++ b/routed.tproj/interface.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+/*
+ * Routing table management daemon.
+ */
+
+/*
+ * An ``interface'' is similar to an ifnet structure,
+ * except it doesn't contain q'ing info, and it also
+ * handles ``logical'' interfaces (remote gateways
+ * that we want to keep polling even if they go down).
+ * The list of interfaces which we maintain is used
+ * in supplying the gratuitous routing table updates.
+ */
+struct interface {
+	struct	interface *int_next;
+	struct	sockaddr int_addr;		/* address on this host */
+	union {
+		struct	sockaddr intu_broadaddr;
+		struct	sockaddr intu_dstaddr;
+	} int_intu;
+#define	int_broadaddr	int_intu.intu_broadaddr	/* broadcast address */
+#define	int_dstaddr	int_intu.intu_dstaddr	/* other end of p-to-p link */
+	int	int_metric;			/* init's routing entry */
+	int	int_flags;			/* see below */
+	/* START INTERNET SPECIFIC */
+	u_long	int_net;			/* network # */
+	u_long	int_netmask;			/* net mask for addr */
+	u_long	int_subnet;			/* subnet # */
+	u_long	int_subnetmask;			/* subnet mask for addr */
+	/* END INTERNET SPECIFIC */
+	struct	ifdebug int_input, int_output;	/* packet tracing stuff */
+	int	int_ipackets;			/* input packets received */
+	int	int_opackets;			/* output packets sent */
+	char	*int_name;			/* from kernel if structure */
+	u_short	int_transitions;		/* times gone up-down */
+};
+
+/*
+ * 0x1 to 0x10 are reused from the kernel's ifnet definitions,
+ * the others agree with the RTS_ flags defined elsewhere.
+ */
+#define	IFF_UP		0x1		/* interface is up */
+#define	IFF_BROADCAST	0x2		/* broadcast address valid */
+#define	IFF_DEBUG	0x4		/* turn on debugging */
+#define	IFF_LOOPBACK	0x8		/* software loopback net */
+#define	IFF_POINTOPOINT	0x10		/* interface is point-to-point link */
+
+#define	IFF_SUBNET	0x100000	/* interface on subnetted network */
+#define	IFF_PASSIVE	0x200000	/* can't tell if up/down */
+#define	IFF_INTERFACE	0x400000	/* hardware interface */
+#define	IFF_REMOTE	0x800000	/* interface isn't on this machine */
+
+struct	interface *if_ifwithaddr();
+struct	interface *if_ifwithdstaddr();
+struct	interface *if_ifwithnet();
+struct	interface *if_iflookup();
diff --git a/routed.tproj/main.c b/routed.tproj/main.c
new file mode 100644
index 0000000..43597a5
--- /dev/null
+++ b/routed.tproj/main.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "defs.h"
+#include <sys/ioctl.h>
+#include <sys/file.h>
+
+#include <net/if.h>
+
+#include <sys/errno.h>
+#include <sys/signal.h>
+#include <sys/syslog.h>
+#include "pathnames.h"
+
+int	supplier = -1;		/* process should supply updates */
+int	gateway = 0;		/* 1 if we are a gateway to parts beyond */
+int	debug = 0;
+int	bufspace = 127*1024;	/* max. input buffer size to request */
+
+struct	rip *msg = (struct rip *)packet;
+void	hup(), rtdeleteall(), sigtrace(), timer();
+
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int n, cc, nfd, omask, tflags = 0;
+	struct sockaddr from;
+	struct timeval *tvp, waittime;
+	struct itimerval itval;
+	register struct rip *query = msg;
+	fd_set ibits;
+	u_char retry;
+	
+	argv0 = argv;
+#if BSD >= 43
+	openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON);
+	setlogmask(LOG_UPTO(LOG_WARNING));
+#else
+	openlog("routed", LOG_PID);
+#define LOG_UPTO(x) (x)
+#define setlogmask(x) (x)
+#endif
+	sp = getservbyname("router", "udp");
+	if (sp == NULL) {
+		fprintf(stderr, "routed: router/udp: unknown service\n");
+		exit(1);
+	}
+	addr.sin_family = AF_INET;
+	addr.sin_port = sp->s_port;
+	r = socket(AF_ROUTE, SOCK_RAW, 0);
+	/* later, get smart about lookingforinterfaces */
+	if (r)
+		shutdown(r, 0); /* for now, don't want reponses */
+	else {
+		fprintf(stderr, "routed: no routing socket\n");
+		exit(1);
+	}
+	s = getsocket(AF_INET, SOCK_DGRAM, &addr);
+	if (s < 0)
+		exit(1);
+	argv++, argc--;
+	while (argc > 0 && **argv == '-') {
+		if (strcmp(*argv, "-s") == 0) {
+			supplier = 1;
+			argv++, argc--;
+			continue;
+		}
+		if (strcmp(*argv, "-q") == 0) {
+			supplier = 0;
+			argv++, argc--;
+			continue;
+		}
+		if (strcmp(*argv, "-t") == 0) {
+			tflags++;
+			setlogmask(LOG_UPTO(LOG_DEBUG));
+			argv++, argc--;
+			continue;
+		}
+		if (strcmp(*argv, "-d") == 0) {
+			debug++;
+			setlogmask(LOG_UPTO(LOG_DEBUG));
+			argv++, argc--;
+			continue;
+		}
+		if (strcmp(*argv, "-g") == 0) {
+			gateway = 1;
+			argv++, argc--;
+			continue;
+		}
+		fprintf(stderr,
+			"usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n");
+		exit(1);
+	}
+
+	if (debug == 0 && tflags == 0)
+		daemon(0, 0);
+	/*
+	 * Any extra argument is considered
+	 * a tracing log file.
+	 */
+	if (argc > 0)
+		traceon(*argv);
+	while (tflags-- > 0)
+		bumploglevel();
+
+	(void) gettimeofday(&now, (struct timezone *)NULL);
+	/*
+	 * Collect an initial view of the world by
+	 * checking the interface configuration and the gateway kludge
+	 * file.  Then, send a request packet on all
+	 * directly connected networks to find out what
+	 * everyone else thinks.
+	 */
+	rtinit();
+	ifinit();
+	gwkludge();
+	if (gateway > 0)
+		rtdefault();
+	if (supplier < 0)
+		supplier = 0;
+	query->rip_cmd = RIPCMD_REQUEST;
+	query->rip_vers = RIPVERSION;
+	if (sizeof(query->rip_nets[0].rip_dst.sa_family) > 1)	/* XXX */
+		query->rip_nets[0].rip_dst.sa_family = htons((u_short)AF_UNSPEC);
+	else
+		query->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
+	query->rip_nets[0].rip_metric = htonl((u_long)HOPCNT_INFINITY);
+	toall(sndmsg);
+	signal(SIGALRM, timer);
+	signal(SIGHUP, hup);
+	signal(SIGTERM, hup);
+	signal(SIGINT, rtdeleteall);
+	signal(SIGUSR1, sigtrace);
+	signal(SIGUSR2, sigtrace);
+	itval.it_interval.tv_sec = TIMER_RATE;
+	itval.it_value.tv_sec = TIMER_RATE;
+	itval.it_interval.tv_usec = 0;
+	itval.it_value.tv_usec = 0;
+	srandom(getpid());
+	if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0)
+		syslog(LOG_ERR, "setitimer: %m\n");
+
+	FD_ZERO(&ibits);
+	nfd = s + 1;			/* 1 + max(fd's) */
+	for (;;) {
+		FD_SET(s, &ibits);
+		/*
+		 * If we need a dynamic update that was held off,
+		 * needupdate will be set, and nextbcast is the time
+		 * by which we want select to return.  Compute time
+		 * until dynamic update should be sent, and select only
+		 * until then.  If we have already passed nextbcast,
+		 * just poll.
+		 */
+		if (needupdate) {
+			waittime = nextbcast;
+			timevalsub(&waittime, &now);
+			if (waittime.tv_sec < 0) {
+				waittime.tv_sec = 0;
+				waittime.tv_usec = 0;
+			}
+			if (traceactions)
+				fprintf(ftrace,
+				 "select until dynamic update %d/%d sec/usec\n",
+				    waittime.tv_sec, waittime.tv_usec);
+			tvp = &waittime;
+		} else
+			tvp = (struct timeval *)NULL;
+		n = select(nfd, &ibits, 0, 0, tvp);
+		if (n <= 0) {
+			/*
+			 * Need delayed dynamic update if select returned
+			 * nothing and we timed out.  Otherwise, ignore
+			 * errors (e.g. EINTR).
+			 */
+			if (n < 0) {
+				if (errno == EINTR)
+					continue;
+				syslog(LOG_ERR, "select: %m");
+			}
+			omask = sigblock(sigmask(SIGALRM));
+			if (n == 0 && needupdate) {
+				if (traceactions)
+					fprintf(ftrace,
+					    "send delayed dynamic update\n");
+				(void) gettimeofday(&now,
+					    (struct timezone *)NULL);
+				toall(supply, RTS_CHANGED,
+				    (struct interface *)NULL);
+				lastbcast = now;
+				needupdate = 0;
+				nextbcast.tv_sec = 0;
+			}
+			sigsetmask(omask);
+			continue;
+		}
+		(void) gettimeofday(&now, (struct timezone *)NULL);
+		omask = sigblock(sigmask(SIGALRM));
+#ifdef doesntwork
+/*
+printf("s %d, ibits %x index %d, mod %d, sh %x, or %x &ibits %x\n",
+	s,
+	ibits.fds_bits[0],
+	(s)/(sizeof(fd_mask) * 8),
+	((s) % (sizeof(fd_mask) * 8)),
+	(1 << ((s) % (sizeof(fd_mask) * 8))),
+	ibits.fds_bits[(s)/(sizeof(fd_mask) * 8)] & (1 << ((s) % (sizeof(fd_mask) * 8))),
+	&ibits
+	);
+*/
+		if (FD_ISSET(s, &ibits))
+#else
+		if (ibits.fds_bits[s/32] & (1 << s))
+#endif
+			process(s);
+		/* handle ICMP redirects */
+		sigsetmask(omask);
+	}
+}
+
+timevaladd(t1, t2)
+	struct timeval *t1, *t2;
+{
+
+	t1->tv_sec += t2->tv_sec;
+	if ((t1->tv_usec += t2->tv_usec) > 1000000) {
+		t1->tv_sec++;
+		t1->tv_usec -= 1000000;
+	}
+}
+
+timevalsub(t1, t2)
+	struct timeval *t1, *t2;
+{
+
+	t1->tv_sec -= t2->tv_sec;
+	if ((t1->tv_usec -= t2->tv_usec) < 0) {
+		t1->tv_sec--;
+		t1->tv_usec += 1000000;
+	}
+}
+
+process(fd)
+	int fd;
+{
+	struct sockaddr from;
+	int fromlen, cc;
+	union {
+		char	buf[MAXPACKETSIZE+1];
+		struct	rip rip;
+	} inbuf;
+
+	for (;;) {
+		fromlen = sizeof (from);
+		cc = recvfrom(fd, &inbuf, sizeof (inbuf), 0, &from, &fromlen);
+		if (cc <= 0) {
+			if (cc < 0 && errno != EWOULDBLOCK)
+				perror("recvfrom");
+			break;
+		}
+		if (fromlen != sizeof (struct sockaddr_in))
+			break;
+		rip_input(&from, &inbuf.rip, cc);
+	}
+}
+
+getsocket(domain, type, sin)
+	int domain, type;
+	struct sockaddr_in *sin;
+{
+	int sock, on = 1;
+
+	if ((sock = socket(domain, type, 0)) < 0) {
+		perror("socket");
+		syslog(LOG_ERR, "socket: %m");
+		return (-1);
+	}
+#ifdef SO_BROADCAST
+	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
+		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
+		close(sock);
+		return (-1);
+	}
+#endif
+#ifdef SO_RCVBUF
+	for (on = bufspace; ; on -= 1024) {
+		if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+		    &on, sizeof (on)) == 0)
+			break;
+		if (on <= 8*1024) {
+			syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
+			break;
+		}
+	}
+	if (traceactions)
+		fprintf(ftrace, "recv buf %d\n", on);
+#endif
+	if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) {
+		perror("bind");
+		syslog(LOG_ERR, "bind: %m");
+		close(sock);
+		return (-1);
+	}
+	if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
+		syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
+	return (sock);
+}
diff --git a/routed.tproj/output.c b/routed.tproj/output.c
new file mode 100644
index 0000000..168c320
--- /dev/null
+++ b/routed.tproj/output.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "defs.h"
+
+/*
+ * Apply the function "f" to all non-passive
+ * interfaces.  If the interface supports the
+ * use of broadcasting use it, otherwise address
+ * the output to the known router.
+ */
+toall(f, rtstate, skipif)
+	int (*f)();
+	int rtstate;
+	struct interface *skipif;
+{
+	register struct interface *ifp;
+	register struct sockaddr *dst;
+	register int flags;
+	extern struct interface *ifnet;
+
+	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
+		if (ifp->int_flags & IFF_PASSIVE || ifp == skipif)
+			continue;
+		dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr :
+		      ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr :
+		      &ifp->int_addr;
+		flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
+		(*f)(dst, flags, ifp, rtstate);
+	}
+}
+
+/*
+ * Output a preformed packet.
+ */
+/*ARGSUSED*/
+sndmsg(dst, flags, ifp, rtstate)
+	struct sockaddr *dst;
+	int flags;
+	struct interface *ifp;
+	int rtstate;
+{
+
+	(*afswitch[dst->sa_family].af_output)(s, flags,
+		dst, sizeof (struct rip));
+	TRACE_OUTPUT(ifp, dst, sizeof (struct rip));
+}
+
+/*
+ * Supply dst with the contents of the routing tables.
+ * If this won't fit in one packet, chop it up into several.
+ */
+supply(dst, flags, ifp, rtstate)
+	struct sockaddr *dst;
+	int flags;
+	register struct interface *ifp;
+	int rtstate;
+{
+	register struct rt_entry *rt;
+	register struct netinfo *n = msg->rip_nets;
+	register struct rthash *rh;
+	struct rthash *base = hosthash;
+	int doinghost = 1, size;
+	int (*output)() = afswitch[dst->sa_family].af_output;
+	int (*sendroute)() = afswitch[dst->sa_family].af_sendroute;
+	int npackets = 0;
+
+	msg->rip_cmd = RIPCMD_RESPONSE;
+	msg->rip_vers = RIPVERSION;
+	memset(msg->rip_res1, 0, sizeof(msg->rip_res1));
+again:
+	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)
+	for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
+		/*
+		 * Don't resend the information on the network
+		 * from which it was received (unless sending
+		 * in response to a query).
+		 */
+		if (ifp && rt->rt_ifp == ifp &&
+		    (rt->rt_state & RTS_INTERFACE) == 0)
+			continue;
+		if (rt->rt_state & RTS_EXTERNAL)
+			continue;
+		/*
+		 * For dynamic updates, limit update to routes
+		 * with the specified state.
+		 */
+		if (rtstate && (rt->rt_state & rtstate) == 0)
+			continue;
+		/*
+		 * Limit the spread of subnet information
+		 * to those who are interested.
+		 */
+		if (doinghost == 0 && rt->rt_state & RTS_SUBNET) {
+			if (rt->rt_dst.sa_family != dst->sa_family)
+				continue;
+			if ((*sendroute)(rt, dst) == 0)
+				continue;
+		}
+		size = (char *)n - packet;
+		if (size > MAXPACKETSIZE - sizeof (struct netinfo)) {
+			TRACE_OUTPUT(ifp, dst, size);
+			(*output)(s, flags, dst, size);
+			/*
+			 * If only sending to ourselves,
+			 * one packet is enough to monitor interface.
+			 */
+			if (ifp && (ifp->int_flags &
+			   (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0)
+				return;
+			n = msg->rip_nets;
+			npackets++;
+		}
+		n->rip_dst = rt->rt_dst;
+#if BSD < 198810
+		if (sizeof(n->rip_dst.sa_family) > 1)	/* XXX */
+		n->rip_dst.sa_family = htons(n->rip_dst.sa_family);
+#else
+#define osa(x) ((struct osockaddr *)(&(x)))
+		osa(n->rip_dst)->sa_family = htons(n->rip_dst.sa_family);
+#endif
+		n->rip_metric = htonl(rt->rt_metric);
+		n++;
+	}
+	if (doinghost) {
+		doinghost = 0;
+		base = nethash;
+		goto again;
+	}
+	if (n != msg->rip_nets || (npackets == 0 && rtstate == 0)) {
+		size = (char *)n - packet;
+		TRACE_OUTPUT(ifp, dst, size);
+		(*output)(s, flags, dst, size);
+	}
+}
diff --git a/routed.tproj/pathnames.h b/routed.tproj/pathnames.h
new file mode 100644
index 0000000..12482f7
--- /dev/null
+++ b/routed.tproj/pathnames.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+#include <paths.h>
+
+#define	_PATH_GATEWAYS	"/etc/gateways"
diff --git a/routed.tproj/routed.8 b/routed.tproj/routed.8
new file mode 100644
index 0000000..8d9ea20
--- /dev/null
+++ b/routed.tproj/routed.8
@@ -0,0 +1,358 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)routed.8	8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt ROUTED 8
+.Os BSD 4.2
+.Sh NAME
+.Nm routed
+.Nd network routing daemon
+.Sh SYNOPSIS
+.Nm routed
+.Op Fl d
+.Op Fl g
+.Op Fl q
+.Op Fl s
+.Op Fl t
+.Op Ar logfile
+.Sh DESCRIPTION
+.Nm Routed
+is invoked at boot time to manage the network routing tables.
+The routing daemon uses a variant of the Xerox NS Routing
+Information Protocol in maintaining up to date kernel routing
+table entries.
+It used a generalized protocol capable of use with multiple
+address types, but is currently used only for Internet routing
+within a cluster of networks.
+.Pp
+In normal operation
+.Nm routed
+listens on the
+.Xr udp 4
+socket for the
+.Xr route 8
+service (see
+.Xr services 5 )
+for routing information packets.  If the host is an
+internetwork router, it periodically supplies copies
+of its routing tables to any directly connected hosts
+and networks.
+.Pp
+When
+.Nm routed
+is started, it uses the
+.Dv SIOCGIFCONF
+.Xr ioctl 2
+to find those
+directly connected interfaces configured into the
+system and marked ``up'' (the software loopback interface
+is ignored).  If multiple interfaces
+are present, it is assumed that the host will forward packets
+between networks.
+.Nm Routed
+then transmits a 
+.Em request
+packet on each interface (using a broadcast packet if
+the interface supports it) and enters a loop, listening
+for
+.Em request
+and
+.Em response
+packets from other hosts.
+.Pp
+When a
+.Em request
+packet is received, 
+.Nm routed
+formulates a reply based on the information maintained in its
+internal tables.  The
+.Em response
+packet generated contains a list of known routes, each marked
+with a ``hop count'' metric (a count of 16, or greater, is
+considered ``infinite'').  The metric associated with each
+route returned provides a metric
+.Em relative to the sender .
+.Pp
+.Em Response
+packets received by
+.Nm routed
+are used to update the routing tables if one of the following
+conditions is satisfied:
+.Bl -enum
+.It
+No routing table entry exists for the destination network
+or host, and the metric indicates the destination is ``reachable''
+(i.e. the hop count is not infinite).
+.It
+The source host of the packet is the same as the router in the
+existing routing table entry.  That is, updated information is
+being received from the very internetwork router through which
+packets for the destination are being routed.
+.It
+The existing entry in the routing table has not been updated for
+some time (defined to be 90 seconds) and the route is at least
+as cost effective as the current route.
+.It
+The new route describes a shorter route to the destination than
+the one currently stored in the routing tables; the metric of
+the new route is compared against the one stored in the table
+to decide this.
+.El
+.Pp
+When an update is applied,
+.Nm routed
+records the change in its internal tables and updates the kernel
+routing table.
+The change is reflected in the next
+.Em response
+packet sent.
+.Pp
+In addition to processing incoming packets,
+.Nm routed
+also periodically checks the routing table entries.
+If an entry has not been updated for 3 minutes, the entry's metric
+is set to infinity and marked for deletion.  Deletions are delayed
+an additional 60 seconds to insure the invalidation is propagated
+throughout the local internet.
+.Pp
+Hosts acting as internetwork routers gratuitously supply their
+routing tables every 30 seconds to all directly connected hosts
+and networks.
+The response is sent to the broadcast address on nets capable of that function,
+to the destination address on point-to-point links, and to the router's
+own address on other networks.
+The normal routing tables are bypassed when sending gratuitous responses.
+The reception of responses on each network is used to determine that the
+network and interface are functioning correctly.
+If no response is received on an interface, another route may be chosen
+to route around the interface, or the route may be dropped if no alternative
+is available.
+.Pp
+Options supported by
+.Nm routed :
+.Bl -tag -width Ds
+.It Fl d
+Enable additional debugging information to be logged,
+such as bad packets received.
+.It Fl g
+This flag is used on internetwork routers to offer a route
+to the ``default'' destination.
+This is typically used on a gateway to the Internet,
+or on a gateway that uses another routing protocol whose routes
+are not reported to other local routers.
+.It Fl s
+Supplying this
+option forces 
+.Nm routed
+to supply routing information whether it is acting as an internetwork
+router or not.
+This is the default if multiple network interfaces are present,
+or if a point-to-point link is in use.
+.It Fl q
+This
+is the opposite of the
+.Fl s
+option.
+.It Fl t
+If the
+.Fl t
+option is specified, all packets sent or received are
+printed on the standard output.  In addition,
+.Nm routed
+will not divorce itself from the controlling terminal
+so that interrupts from the keyboard will kill the process.
+.El
+.Pp
+Any other argument supplied is interpreted as the name
+of file in which 
+.Nm routed Ns \'s
+actions should be logged.  This log contains information
+about any changes to the routing tables and, if not tracing all packets,
+a history of recent messages sent and received which are related to
+the changed route.
+.Pp
+In addition to the facilities described above, 
+.Nm routed
+supports the notion of ``distant''
+.Em passive
+and 
+.Em active
+gateways.  When 
+.Nm routed
+is started up, it reads the file
+.Pa /etc/gateways
+to find gateways which may not be located using
+only information from the
+.Dv SIOGIFCONF
+.Xr ioctl 2 .
+Gateways specified in this manner should be marked passive
+if they are not expected to exchange routing information,
+while gateways marked active
+should be willing to exchange routing information (i.e.
+they should have a
+.Nm routed
+process running on the machine).
+Routes through passive gateways are installed in the
+kernel's routing tables once upon startup.
+Such routes are not included in
+any routing information transmitted.
+Active gateways are treated equally to network
+interfaces.  Routing information is distributed
+to the gateway and if no routing information is
+received for a period of time, the associated
+route is deleted.
+Gateways marked
+.Em external
+are also passive, but are not placed in the kernel
+routing table nor are they included in routing updates.
+The function of external entries is to inform
+.Nm routed
+that another routing process
+will install such a route, and that alternate routes to that destination
+should not be installed.
+Such entries are only required when both routers may learn of routes
+to the same destination.
+.Pp
+The 
+.Pa /etc/gateways
+is comprised of a series of lines, each in
+the following format:
+.Bd -ragged
+.Pf < Cm net No \&|
+.Cm host Ns >
+.Ar name1
+.Cm gateway
+.Ar name2
+.Cm metric
+.Ar value
+.Pf < Cm passive No \&|
+.Cm active No \&|
+.Cm external Ns >
+.Ed
+.Pp
+The 
+.Cm net
+or
+.Cm host
+keyword indicates if the route is to a network or specific host.
+.Pp
+.Ar Name1
+is the name of the destination network or host.  This may be a
+symbolic name located in
+.Pa /etc/networks
+or
+.Pa /etc/hosts
+(or, if started after
+.Xr named 8 ,
+known to the name server), 
+or an Internet address specified in ``dot'' notation; see
+.Xr inet 3 .
+.Pp
+.Ar Name2
+is the name or address of the gateway to which messages should
+be forwarded.
+.Pp
+.Ar Value
+is a metric indicating the hop count to the destination host
+or network.
+.Pp
+One of the keywords
+.Cm passive ,
+.Cm active
+or
+.Cm external
+indicates if the gateway should be treated as 
+.Em passive
+or
+.Em active
+(as described above),
+or whether the gateway is
+.Em external
+to the scope of the
+.Nm routed
+protocol.
+.Pp
+Internetwork routers that are directly attached to the Arpanet or Milnet
+should use the Exterior Gateway Protocol
+.Pq Tn EGP
+to gather routing information
+rather then using a static routing table of passive gateways.
+.Tn EGP
+is required in order to provide routes for local networks to the rest
+of the Internet system.
+.Sh FILES
+.Bl -tag -width /etc/gateways -compact
+.It Pa /etc/gateways
+for distant gateways
+.El
+.Sh SEE ALSO
+.Xr udp 4 ,
+.Xr icmp 4 ,
+.Xr XNSrouted 8 ,
+.Xr htable 8
+.Rs
+.%T Internet Transport Protocols
+.%R XSIS 028112
+.%Q Xerox System Integration Standard
+.Re
+.Sh BUGS
+The kernel's routing tables may not correspond to those of
+.Nm routed
+when redirects change or add routes.
+.Nm Routed
+should note any redirects received by reading
+the
+.Tn ICMP
+packets received via a raw socket.
+.Pp
+.Nm Routed
+should incorporate other routing protocols,
+such as Xerox
+.Tn \&NS
+.Pq Xr XNSrouted 8
+and
+.Tn EGP .
+Using separate processes for each requires configuration options
+to avoid redundant or competing routes.
+.Pp
+.Nm Routed
+should listen to intelligent interfaces, such as an
+.Tn IMP ,
+to gather more information.
+It does not always detect unidirectional failures in network interfaces
+(e.g., when the output side fails).
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/routed.tproj/startup.c b/routed.tproj/startup.c
new file mode 100644
index 0000000..c183ac6
--- /dev/null
+++ b/routed.tproj/startup.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "defs.h"
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <syslog.h>
+#include <stdlib.h>
+#include "pathnames.h"
+
+struct	interface *ifnet;
+struct	interface **ifnext = &ifnet;
+int	lookforinterfaces = 1;
+int	externalinterfaces = 0;		/* # of remote and local interfaces */
+int	foundloopback;			/* valid flag for loopaddr */
+struct	sockaddr loopaddr;		/* our address on loopback */
+
+
+void
+quit(s)
+	char *s;
+{
+	extern int errno;
+	int sverrno = errno;
+
+	(void) fprintf(stderr, "route: ");
+	if (s)
+		(void) fprintf(stderr, "%s: ", s);
+	(void) fprintf(stderr, "%s\n", strerror(sverrno));
+	exit(1);
+	/* NOTREACHED */
+}
+
+struct rt_addrinfo info;
+/* Sleazy use of local variables throughout file, warning!!!! */
+#define netmask	info.rti_info[RTAX_NETMASK]
+#define ifaaddr	info.rti_info[RTAX_IFA]
+#define brdaddr	info.rti_info[RTAX_BRD]
+
+#define ROUNDUP(a) \
+	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+void
+rt_xaddrs(cp, cplim, rtinfo)
+	register caddr_t cp, cplim;
+	register struct rt_addrinfo *rtinfo;
+{
+	register struct sockaddr *sa;
+	register int i;
+
+	memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
+	for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
+		if ((rtinfo->rti_addrs & (1 << i)) == 0)
+			continue;
+		rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
+		ADVANCE(cp, sa);
+	}
+}
+
+/*
+ * Find the network interfaces which have configured themselves.
+ * If the interface is present but not yet up (for example an
+ * ARPANET IMP), set the lookforinterfaces flag so we'll
+ * come back later and look again.
+ */
+ifinit()
+{
+	struct interface ifs, *ifp;
+	size_t needed;
+	int mib[6], no_ipaddr = 0, flags = 0;
+	char *buf, *cplim, *cp;
+	register struct if_msghdr *ifm;
+	register struct ifa_msghdr *ifam;
+	struct sockaddr_dl *sdl;
+        struct sockaddr_in *sin;
+	u_long i;
+
+        mib[0] = CTL_NET;
+        mib[1] = PF_ROUTE;
+        mib[2] = 0;
+        mib[3] = AF_INET;
+        mib[4] = NET_RT_IFLIST;
+        mib[5] = 0;
+        if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+                quit("route-sysctl-estimate");
+	if ((buf = malloc(needed)) == NULL)
+		quit("malloc");
+        if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+		quit("actual retrieval of interface table");
+	lookforinterfaces = 0;
+	cplim = buf + needed;
+	for (cp = buf; cp < cplim; cp += ifm->ifm_msglen) {
+		ifm = (struct if_msghdr *)cp;
+		if (ifm->ifm_type == RTM_IFINFO) {
+			memset(&ifs, 0, sizeof(ifs));
+			ifs.int_flags = flags = (0xffff & ifm->ifm_flags) | IFF_INTERFACE;
+			if ((flags & IFF_UP) == 0 || no_ipaddr)
+				lookforinterfaces = 1;
+			sdl = (struct sockaddr_dl *) (ifm + 1);
+			sdl->sdl_data[sdl->sdl_nlen] = 0;
+			no_ipaddr = 1;
+			continue;
+		}
+		if (ifm->ifm_type != RTM_NEWADDR)
+			quit("ifinit: out of sync");
+		if ((flags & IFF_UP) == 0)
+			continue;
+		ifam = (struct ifa_msghdr *)ifm;
+		info.rti_addrs = ifam->ifam_addrs;
+		rt_xaddrs((char *)(ifam + 1), cp + ifam->ifam_msglen, &info);
+		if (ifaaddr == 0) {
+			syslog(LOG_ERR, "%s: (get addr)", sdl->sdl_data);
+			continue;
+		}
+		ifs.int_addr = *ifaaddr;
+		if (ifs.int_addr.sa_family != AF_INET)
+			continue;
+		no_ipaddr = 0;
+		if (ifs.int_flags & IFF_POINTOPOINT) {
+			if (brdaddr == 0) {
+				syslog(LOG_ERR, "%s: (get dstaddr)",
+					sdl->sdl_data);
+				continue;
+			}
+			if (brdaddr->sa_family == AF_UNSPEC) {
+				lookforinterfaces = 1;
+				continue;
+			}
+			ifs.int_dstaddr = *brdaddr;
+		}
+		/*
+		 * already known to us?
+		 * This allows multiple point-to-point links
+		 * to share a source address (possibly with one
+		 * other link), but assumes that there will not be
+		 * multiple links with the same destination address.
+		 */
+		if (ifs.int_flags & IFF_POINTOPOINT) {
+			if (if_ifwithdstaddr(&ifs.int_dstaddr))
+				continue;
+		} else if (if_ifwithaddr(&ifs.int_addr))
+			continue;
+		if (ifs.int_flags & IFF_LOOPBACK) {
+			ifs.int_flags |= IFF_PASSIVE;
+			foundloopback = 1;
+			loopaddr = ifs.int_addr;
+			for (ifp = ifnet; ifp; ifp = ifp->int_next)
+			    if (ifp->int_flags & IFF_POINTOPOINT)
+				add_ptopt_localrt(ifp);
+		}
+		if (ifs.int_flags & IFF_BROADCAST) {
+			if (brdaddr == 0) {
+				syslog(LOG_ERR, "%s: (get broadaddr)",
+					sdl->sdl_data);
+				continue;
+			}
+			ifs.int_dstaddr = *brdaddr;
+		}
+		/*
+		 * Use a minimum metric of one;
+		 * treat the interface metric (default 0)
+		 * as an increment to the hop count of one.
+		 */
+		ifs.int_metric = ifam->ifam_metric + 1;
+		if (netmask == 0) {
+				syslog(LOG_ERR, "%s: (get netmask)",
+					sdl->sdl_data);
+				continue;
+		}
+		sin = (struct sockaddr_in *)netmask;
+		ifs.int_subnetmask = ntohl(sin->sin_addr.s_addr);
+		sin = (struct sockaddr_in *)&ifs.int_addr;
+		i = ntohl(sin->sin_addr.s_addr);
+		if (IN_CLASSA(i))
+			ifs.int_netmask = IN_CLASSA_NET;
+		else if (IN_CLASSB(i))
+			ifs.int_netmask = IN_CLASSB_NET;
+		else
+			ifs.int_netmask = IN_CLASSC_NET;
+		ifs.int_net = i & ifs.int_netmask;
+		ifs.int_subnet = i & ifs.int_subnetmask;
+		if (ifs.int_subnetmask != ifs.int_netmask)
+			ifs.int_flags |= IFF_SUBNET;
+		ifp = (struct interface *)
+			malloc(sdl->sdl_nlen + 1 + sizeof(ifs));
+		if (ifp == 0) {
+			printf("routed: out of memory\n");
+			lookforinterfaces = 1;
+			break;
+		}
+		*ifp = ifs;
+		/*
+		 * Count the # of directly connected networks
+		 * and point to point links which aren't looped
+		 * back to ourself.  This is used below to
+		 * decide if we should be a routing ``supplier''.
+		 */
+		if ((ifs.int_flags & IFF_LOOPBACK) == 0 &&
+		    ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
+		    if_ifwithaddr(&ifs.int_dstaddr) == 0))
+			externalinterfaces++;
+		/*
+		 * If we have a point-to-point link, we want to act
+		 * as a supplier even if it's our only interface,
+		 * as that's the only way our peer on the other end
+		 * can tell that the link is up.
+		 */
+		if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0)
+			supplier = 1;
+		ifp->int_name = (char *)(ifp + 1);
+		strcpy(ifp->int_name, sdl->sdl_data);
+		*ifnext = ifp;
+		ifnext = &ifp->int_next;
+		traceinit(ifp);
+		addrouteforif(ifp);
+	}
+	if (externalinterfaces > 1 && supplier < 0)
+		supplier = 1;
+	free(buf);
+}
+
+/*
+ * Add route for interface if not currently installed.
+ * Create route to other end if a point-to-point link,
+ * otherwise a route to this (sub)network.
+ * INTERNET SPECIFIC.
+ */
+addrouteforif(ifp)
+	register struct interface *ifp;
+{
+	struct sockaddr_in net;
+	struct sockaddr *dst;
+	int state;
+	register struct rt_entry *rt;
+
+	if (ifp->int_flags & IFF_POINTOPOINT)
+		dst = &ifp->int_dstaddr;
+	else {
+		memset(&net, 0, sizeof (net));
+		net.sin_family = AF_INET;
+		net.sin_addr = inet_makeaddr(ifp->int_subnet, INADDR_ANY);
+		dst = (struct sockaddr *)&net;
+	}
+	rt = rtfind(dst);
+	if (rt &&
+	    (rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE)
+		return;
+	if (rt)
+		rtdelete(rt);
+	/*
+	 * If interface on subnetted network,
+	 * install route to network as well.
+	 * This is meant for external viewers.
+	 */
+	if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) {
+		struct in_addr subnet;
+
+		subnet = net.sin_addr;
+		net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
+		rt = rtfind(dst);
+		if (rt == 0)
+			rtadd(dst, &ifp->int_addr, ifp->int_metric,
+			    ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) |
+			    RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET));
+		else if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) == 
+		    (RTS_INTERNAL|RTS_SUBNET) &&
+		    ifp->int_metric < rt->rt_metric)
+			rtchange(rt, &rt->rt_router, ifp->int_metric);
+		net.sin_addr = subnet;
+	}
+	if (ifp->int_transitions++ > 0)
+		syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
+	state = ifp->int_flags &
+	    (IFF_INTERFACE | IFF_PASSIVE | IFF_REMOTE | IFF_SUBNET);
+	if (ifp->int_flags & IFF_POINTOPOINT &&
+	    (ntohl(((struct sockaddr_in *)&ifp->int_dstaddr)->sin_addr.s_addr) &
+	    ifp->int_netmask) != ifp->int_net)
+		state &= ~RTS_SUBNET;
+	if (ifp->int_flags & IFF_LOOPBACK)
+		state |= RTS_EXTERNAL;
+	rtadd(dst, &ifp->int_addr, ifp->int_metric, state);
+	if (ifp->int_flags & IFF_POINTOPOINT && foundloopback)
+		add_ptopt_localrt(ifp);
+}
+
+/*
+ * Add route to local end of point-to-point using loopback.
+ * If a route to this network is being sent to neighbors on other nets,
+ * mark this route as subnet so we don't have to propagate it too.
+ */
+add_ptopt_localrt(ifp)
+	register struct interface *ifp;
+{
+	struct rt_entry *rt;
+	struct sockaddr *dst;
+	struct sockaddr_in net;
+	int state;
+
+	state = RTS_INTERFACE | RTS_PASSIVE;
+
+	/* look for route to logical network */
+	memset(&net, 0, sizeof (net));
+	net.sin_family = AF_INET;
+	net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
+	dst = (struct sockaddr *)&net;
+	rt = rtfind(dst);
+	if (rt && rt->rt_state & RTS_INTERNAL)
+		state |= RTS_SUBNET;
+
+	dst = &ifp->int_addr;
+	if (rt = rtfind(dst)) {
+		if (rt && rt->rt_state & RTS_INTERFACE)
+			return;
+		rtdelete(rt);
+	}
+	rtadd(dst, &loopaddr, 1, state);
+}
+
+/*
+ * As a concession to the ARPANET we read a list of gateways
+ * from /etc/gateways and add them to our tables.  This file
+ * exists at each ARPANET gateway and indicates a set of ``remote''
+ * gateways (i.e. a gateway which we can't immediately determine
+ * if it's present or not as we can do for those directly connected
+ * at the hardware level).  If a gateway is marked ``passive''
+ * in the file, then we assume it doesn't have a routing process
+ * of our design and simply assume it's always present.  Those
+ * not marked passive are treated as if they were directly
+ * connected -- they're added into the interface list so we'll
+ * send them routing updates.
+ *
+ * PASSIVE ENTRIES AREN'T NEEDED OR USED ON GATEWAYS RUNNING EGP.
+ */
+gwkludge()
+{
+	struct sockaddr_in dst, gate;
+	FILE *fp;
+	char *type, *dname, *gname, *qual, buf[BUFSIZ];
+	struct interface *ifp;
+	int metric, n;
+	struct rt_entry route;
+
+	fp = fopen(_PATH_GATEWAYS, "r");
+	if (fp == NULL)
+		return;
+	qual = buf;
+	dname = buf + 64;
+	gname = buf + ((BUFSIZ - 64) / 3);
+	type = buf + (((BUFSIZ - 64) * 2) / 3);
+	memset(&dst, 0, sizeof (dst));
+	memset(&gate, 0, sizeof (gate));
+	memset(&route, 0, sizeof(route));
+/* format: {net | host} XX gateway XX metric DD [passive | external]\n */
+#define	readentry(fp) \
+	fscanf((fp), "%s %s gateway %s metric %d %s\n", \
+		type, dname, gname, &metric, qual)
+	for (;;) {
+		if ((n = readentry(fp)) == EOF)
+			break;
+		if (!getnetorhostname(type, dname, &dst))
+			continue;
+		if (!gethostnameornumber(gname, &gate))
+			continue;
+		if (metric == 0)			/* XXX */
+			metric = 1;
+		if (strcmp(qual, "passive") == 0) {
+			/*
+			 * Passive entries aren't placed in our tables,
+			 * only the kernel's, so we don't copy all of the
+			 * external routing information within a net.
+			 * Internal machines should use the default
+			 * route to a suitable gateway (like us).
+			 */
+			route.rt_dst = *(struct sockaddr *) &dst;
+			route.rt_router = *(struct sockaddr *) &gate;
+			route.rt_flags = RTF_UP;
+			if (strcmp(type, "host") == 0)
+				route.rt_flags |= RTF_HOST;
+			if (metric)
+				route.rt_flags |= RTF_GATEWAY;
+			(void) rtioctl(ADD, &route.rt_rt);
+			continue;
+		}
+		if (strcmp(qual, "external") == 0) {
+			/*
+			 * Entries marked external are handled
+			 * by other means, e.g. EGP,
+			 * and are placed in our tables only
+			 * to prevent overriding them
+			 * with something else.
+			 */
+			rtadd(&dst, &gate, metric, RTS_EXTERNAL|RTS_PASSIVE);
+			continue;
+		}
+		/* assume no duplicate entries */
+		externalinterfaces++;
+		ifp = (struct interface *)malloc(sizeof (*ifp));
+		memset(ifp, 0, sizeof (*ifp));
+		ifp->int_flags = IFF_REMOTE;
+		/* can't identify broadcast capability */
+		ifp->int_net = inet_netof(dst.sin_addr);
+		if (strcmp(type, "host") == 0) {
+			ifp->int_flags |= IFF_POINTOPOINT;
+			ifp->int_dstaddr = *((struct sockaddr *)&dst);
+		}
+		ifp->int_addr = *((struct sockaddr *)&gate);
+		ifp->int_metric = metric;
+		ifp->int_next = ifnet;
+		ifnet = ifp;
+		addrouteforif(ifp);
+	}
+	fclose(fp);
+}
+
+getnetorhostname(type, name, sin)
+	char *type, *name;
+	struct sockaddr_in *sin;
+{
+
+	if (strcmp(type, "net") == 0) {
+		struct netent *np = getnetbyname(name);
+		int n;
+
+		if (np == 0)
+			n = inet_network(name);
+		else {
+			if (np->n_addrtype != AF_INET)
+				return (0);
+			n = np->n_net;
+			/*
+			 * getnetbyname returns right-adjusted value.
+			 */
+			if (n < 128)
+				n <<= IN_CLASSA_NSHIFT;
+			else if (n < 65536)
+				n <<= IN_CLASSB_NSHIFT;
+			else
+				n <<= IN_CLASSC_NSHIFT;
+		}
+		sin->sin_family = AF_INET;
+		sin->sin_addr = inet_makeaddr(n, INADDR_ANY);
+		return (1);
+	}
+	if (strcmp(type, "host") == 0) {
+		struct hostent *hp = gethostbyname(name);
+
+		if (hp == 0)
+			sin->sin_addr.s_addr = inet_addr(name);
+		else {
+			if (hp->h_addrtype != AF_INET)
+				return (0);
+			memmove(&sin->sin_addr, hp->h_addr, hp->h_length);
+		}
+		sin->sin_family = AF_INET;
+		return (1);
+	}
+	return (0);
+}
+
+gethostnameornumber(name, sin)
+	char *name;
+	struct sockaddr_in *sin;
+{
+	struct hostent *hp;
+
+	hp = gethostbyname(name);
+	if (hp) {
+		memmove(&sin->sin_addr, hp->h_addr, hp->h_length);
+		sin->sin_family = hp->h_addrtype;
+		return (1);
+	}
+	sin->sin_addr.s_addr = inet_addr(name);
+	sin->sin_family = AF_INET;
+	return (sin->sin_addr.s_addr != -1);
+}
diff --git a/routed.tproj/table.h b/routed.tproj/table.h
new file mode 100644
index 0000000..3e0246d
--- /dev/null
+++ b/routed.tproj/table.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+/*
+ * Routing table management daemon.
+ */
+
+/*
+ * Routing table structure; differs a bit from kernel tables.
+ *
+ * Note: the union below must agree in the first 4 members
+ * so the ioctl's will work.
+ */
+struct rthash {
+	struct	rt_entry *rt_forw;
+	struct	rt_entry *rt_back;
+};
+#ifdef RTM_ADD
+#define rtentry ortentry
+#endif
+
+struct rt_entry {
+	struct	rt_entry *rt_forw;
+	struct	rt_entry *rt_back;
+	union {
+		struct	rtentry rtu_rt;
+		struct rtuentry {
+			u_long	rtu_hash;
+			struct	sockaddr rtu_dst;
+			struct	sockaddr rtu_router;
+			short	rtu_rtflags; /* used by rtioctl */
+			short	rtu_wasted[5];
+			int	rtu_flags;
+			int	rtu_state;
+			int	rtu_timer;
+			int	rtu_metric;
+			int	rtu_ifmetric;
+			struct	interface *rtu_ifp;
+		} rtu_entry;
+	} rt_rtu;
+};
+
+#define	rt_rt		rt_rtu.rtu_entry		/* pass to ioctl */
+#define	rt_hash		rt_rtu.rtu_entry.rtu_hash	/* for net or host */
+#define	rt_dst		rt_rtu.rtu_entry.rtu_dst	/* match value */
+#define	rt_router	rt_rtu.rtu_entry.rtu_router	/* who to forward to */
+#define	rt_flags	rt_rtu.rtu_entry.rtu_flags	/* kernel flags */
+#define	rt_timer	rt_rtu.rtu_entry.rtu_timer	/* for invalidation */
+#define	rt_state	rt_rtu.rtu_entry.rtu_state	/* see below */
+#define	rt_metric	rt_rtu.rtu_entry.rtu_metric	/* cost of route */
+#define	rt_ifmetric	rt_rtu.rtu_entry.rtu_ifmetric	/* cost of route if */
+#define	rt_ifp		rt_rtu.rtu_entry.rtu_ifp	/* interface to take */
+
+#define	ROUTEHASHSIZ	32		/* must be a power of 2 */
+#define	ROUTEHASHMASK	(ROUTEHASHSIZ - 1)
+
+/*
+ * "State" of routing table entry.
+ */
+#define	RTS_CHANGED	0x1		/* route has been altered recently */
+#define	RTS_EXTERNAL	0x2		/* extern info, not installed or sent */
+#define	RTS_INTERNAL	0x4		/* internal route, not installed */
+#define	RTS_PASSIVE	IFF_PASSIVE	/* don't time out route */
+#define	RTS_INTERFACE	IFF_INTERFACE	/* route is for network interface */
+#define	RTS_REMOTE	IFF_REMOTE	/* route is for ``remote'' entity */
+#define	RTS_SUBNET	IFF_SUBNET	/* route is for network subnet */
+
+/*
+ * Flags are same as kernel, with this addition for af_rtflags:
+ */
+#define	RTF_SUBNET	0x80000		/* pseudo: route to subnet */
+
+EXTERN struct	rthash nethash[ROUTEHASHSIZ];
+EXTERN struct	rthash hosthash[ROUTEHASHSIZ];
+struct	rt_entry *rtlookup();
+struct	rt_entry *rtfind();
diff --git a/routed.tproj/tables.c b/routed.tproj/tables.c
new file mode 100644
index 0000000..f9ade65
--- /dev/null
+++ b/routed.tproj/tables.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "defs.h"
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <sys/syslog.h>
+
+#ifndef DEBUG
+#define	DEBUG	0
+#endif
+
+#ifdef RTM_ADD
+#define FIXLEN(s) {if ((s)->sa_len == 0) (s)->sa_len = sizeof *(s);}
+#else
+#define FIXLEN(s) { }
+#endif
+
+int	install = !DEBUG;		/* if 1 call kernel */
+
+/*
+ * Lookup dst in the tables for an exact match.
+ */
+struct rt_entry *
+rtlookup(dst)
+	struct sockaddr *dst;
+{
+	register struct rt_entry *rt;
+	register struct rthash *rh;
+	register u_int hash;
+	struct afhash h;
+	int doinghost = 1;
+
+	if (dst->sa_family >= af_max)
+		return (0);
+	(*afswitch[dst->sa_family].af_hash)(dst, &h);
+	hash = h.afh_hosthash;
+	rh = &hosthash[hash & ROUTEHASHMASK];
+again:
+	for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
+		if (rt->rt_hash != hash)
+			continue;
+		if (equal(&rt->rt_dst, dst))
+			return (rt);
+	}
+	if (doinghost) {
+		doinghost = 0;
+		hash = h.afh_nethash;
+		rh = &nethash[hash & ROUTEHASHMASK];
+		goto again;
+	}
+	return (0);
+}
+
+struct sockaddr wildcard;	/* zero valued cookie for wildcard searches */
+
+/*
+ * Find a route to dst as the kernel would.
+ */
+struct rt_entry *
+rtfind(dst)
+	struct sockaddr *dst;
+{
+	register struct rt_entry *rt;
+	register struct rthash *rh;
+	register u_int hash;
+	struct afhash h;
+	int af = dst->sa_family;
+	int doinghost = 1, (*match)();
+
+	if (af >= af_max)
+		return (0);
+	(*afswitch[af].af_hash)(dst, &h);
+	hash = h.afh_hosthash;
+	rh = &hosthash[hash & ROUTEHASHMASK];
+
+again:
+	for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
+		if (rt->rt_hash != hash)
+			continue;
+		if (doinghost) {
+			if (equal(&rt->rt_dst, dst))
+				return (rt);
+		} else {
+			if (rt->rt_dst.sa_family == af &&
+			    (*match)(&rt->rt_dst, dst))
+				return (rt);
+		}
+	}
+	if (doinghost) {
+		doinghost = 0;
+		hash = h.afh_nethash;
+		rh = &nethash[hash & ROUTEHASHMASK];
+		match = afswitch[af].af_netmatch;
+		goto again;
+	}
+#ifdef notyet
+	/*
+	 * Check for wildcard gateway, by convention network 0.
+	 */
+	if (dst != &wildcard) {
+		dst = &wildcard, hash = 0;
+		goto again;
+	}
+#endif
+	return (0);
+}
+
+rtadd(dst, gate, metric, state)
+	struct sockaddr *dst, *gate;
+	int metric, state;
+{
+	struct afhash h;
+	register struct rt_entry *rt;
+	struct rthash *rh;
+	int af = dst->sa_family, flags;
+	u_int hash;
+
+	if (af >= af_max)
+		return;
+	(*afswitch[af].af_hash)(dst, &h);
+	flags = (*afswitch[af].af_rtflags)(dst);
+	/*
+	 * Subnet flag isn't visible to kernel, move to state.	XXX
+	 */
+	FIXLEN(dst);
+	FIXLEN(gate);
+	if (flags & RTF_SUBNET) {
+		state |= RTS_SUBNET;
+		flags &= ~RTF_SUBNET;
+	}
+	if (flags & RTF_HOST) {
+		hash = h.afh_hosthash;
+		rh = &hosthash[hash & ROUTEHASHMASK];
+	} else {
+		hash = h.afh_nethash;
+		rh = &nethash[hash & ROUTEHASHMASK];
+	}
+	rt = (struct rt_entry *)malloc(sizeof (*rt));
+	if (rt == 0)
+		return;
+	rt->rt_hash = hash;
+	rt->rt_dst = *dst;
+	rt->rt_router = *gate;
+	rt->rt_timer = 0;
+	rt->rt_flags = RTF_UP | flags;
+	rt->rt_state = state | RTS_CHANGED;
+	rt->rt_ifp = if_ifwithdstaddr(&rt->rt_dst);
+	if (rt->rt_ifp == 0)
+		rt->rt_ifp = if_ifwithnet(&rt->rt_router);
+	if ((state & RTS_INTERFACE) == 0)
+		rt->rt_flags |= RTF_GATEWAY;
+	rt->rt_metric = metric;
+	insque(rt, rh);
+	TRACE_ACTION("ADD", rt);
+	/*
+	 * If the ioctl fails because the gateway is unreachable
+	 * from this host, discard the entry.  This should only
+	 * occur because of an incorrect entry in /etc/gateways.
+	 */
+	if ((rt->rt_state & (RTS_INTERNAL | RTS_EXTERNAL)) == 0 &&
+	    rtioctl(ADD, &rt->rt_rt) < 0) {
+		if (errno != EEXIST && gate->sa_family < af_max)
+			syslog(LOG_ERR,
+			"adding route to net/host %s through gateway %s: %m\n",
+			   (*afswitch[dst->sa_family].af_format)(dst),
+			   (*afswitch[gate->sa_family].af_format)(gate));
+		perror("ADD ROUTE");
+		if (errno == ENETUNREACH) {
+			TRACE_ACTION("DELETE", rt);
+			remque(rt);
+			free((char *)rt);
+		}
+	}
+}
+
+rtchange(rt, gate, metric)
+	struct rt_entry *rt;
+	struct sockaddr *gate;
+	short metric;
+{
+	int add = 0, delete = 0, newgateway = 0;
+	struct rtuentry oldroute;
+
+	FIXLEN(gate);
+	FIXLEN(&(rt->rt_router));
+	FIXLEN(&(rt->rt_dst));
+	if (!equal(&rt->rt_router, gate)) {
+		newgateway++;
+		TRACE_ACTION("CHANGE FROM ", rt);
+	} else if (metric != rt->rt_metric)
+		TRACE_NEWMETRIC(rt, metric);
+	if ((rt->rt_state & RTS_INTERNAL) == 0) {
+		/*
+		 * If changing to different router, we need to add
+		 * new route and delete old one if in the kernel.
+		 * If the router is the same, we need to delete
+		 * the route if has become unreachable, or re-add
+		 * it if it had been unreachable.
+		 */
+		if (newgateway) {
+			add++;
+			if (rt->rt_metric != HOPCNT_INFINITY)
+				delete++;
+		} else if (metric == HOPCNT_INFINITY)
+			delete++;
+		else if (rt->rt_metric == HOPCNT_INFINITY)
+			add++;
+	}
+	if (delete)
+		oldroute = rt->rt_rt;
+	if ((rt->rt_state & RTS_INTERFACE) && delete) {
+		rt->rt_state &= ~RTS_INTERFACE;
+		rt->rt_flags |= RTF_GATEWAY;
+		if (metric > rt->rt_metric && delete)
+			syslog(LOG_ERR, "%s route to interface %s (timed out)",
+			    add? "changing" : "deleting",
+			    rt->rt_ifp ? rt->rt_ifp->int_name : "?");
+	}
+	if (add) {
+		rt->rt_router = *gate;
+		rt->rt_ifp = if_ifwithdstaddr(&rt->rt_router);
+		if (rt->rt_ifp == 0)
+			rt->rt_ifp = if_ifwithnet(&rt->rt_router);
+	}
+	rt->rt_metric = metric;
+	rt->rt_state |= RTS_CHANGED;
+	if (newgateway)
+		TRACE_ACTION("CHANGE TO   ", rt);
+#ifndef RTM_ADD
+	if (add && rtioctl(ADD, &rt->rt_rt) < 0)
+		perror("ADD ROUTE");
+	if (delete && rtioctl(DELETE, &oldroute) < 0)
+		perror("DELETE ROUTE");
+#else
+	if (delete && !add) {
+		if (rtioctl(DELETE, &oldroute) < 0)
+			perror("DELETE ROUTE");
+	} else if (!delete && add) {
+		if (rtioctl(ADD, &rt->rt_rt) < 0)
+			perror("ADD ROUTE");
+	} else if (delete && add) {
+		if (rtioctl(CHANGE, &rt->rt_rt) < 0)
+			perror("CHANGE ROUTE");
+	}
+#endif
+}
+
+rtdelete(rt)
+	struct rt_entry *rt;
+{
+
+	TRACE_ACTION("DELETE", rt);
+	FIXLEN(&(rt->rt_router));
+	FIXLEN(&(rt->rt_dst));
+	if (rt->rt_metric < HOPCNT_INFINITY) {
+	    if ((rt->rt_state & (RTS_INTERFACE|RTS_INTERNAL)) == RTS_INTERFACE)
+		syslog(LOG_ERR,
+		    "deleting route to interface %s? (timed out?)",
+		    rt->rt_ifp->int_name);
+	    if ((rt->rt_state & (RTS_INTERNAL | RTS_EXTERNAL)) == 0 &&
+					    rtioctl(DELETE, &rt->rt_rt) < 0)
+		    perror("rtdelete");
+	}
+	remque(rt);
+	free((char *)rt);
+}
+
+rtdeleteall(sig)
+	int sig;
+{
+	register struct rthash *rh;
+	register struct rt_entry *rt;
+	struct rthash *base = hosthash;
+	int doinghost = 1;
+
+again:
+	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
+		rt = rh->rt_forw;
+		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
+			if (rt->rt_state & RTS_INTERFACE ||
+			    rt->rt_metric >= HOPCNT_INFINITY)
+				continue;
+			TRACE_ACTION("DELETE", rt);
+			if ((rt->rt_state & (RTS_INTERNAL|RTS_EXTERNAL)) == 0 &&
+			    rtioctl(DELETE, &rt->rt_rt) < 0)
+				perror("rtdeleteall");
+		}
+	}
+	if (doinghost) {
+		doinghost = 0;
+		base = nethash;
+		goto again;
+	}
+	exit(sig);
+}
+
+/*
+ * If we have an interface to the wide, wide world,
+ * add an entry for an Internet default route (wildcard) to the internal
+ * tables and advertise it.  This route is not added to the kernel routes,
+ * but this entry prevents us from listening to other people's defaults
+ * and installing them in the kernel here.
+ */
+rtdefault()
+{
+	extern struct sockaddr inet_default;
+
+	rtadd(&inet_default, &inet_default, 1,
+		RTS_CHANGED | RTS_PASSIVE | RTS_INTERNAL);
+}
+
+rtinit()
+{
+	register struct rthash *rh;
+
+	for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++)
+		rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
+	for (rh = hosthash; rh < &hosthash[ROUTEHASHSIZ]; rh++)
+		rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
+}
+
+rtioctl(action, ort)
+	int action;
+	struct rtuentry *ort;
+{
+#ifndef RTM_ADD
+	if (install == 0)
+		return (errno = 0);
+	ort->rtu_rtflags = ort->rtu_flags;
+	switch (action) {
+
+	case ADD:
+		return (ioctl(s, SIOCADDRT, (char *)ort));
+
+	case DELETE:
+		return (ioctl(s, SIOCDELRT, (char *)ort));
+
+	default:
+		return (-1);
+	}
+#else /* RTM_ADD */
+	struct {
+		struct rt_msghdr w_rtm;
+		struct sockaddr_in w_dst;
+		struct sockaddr w_gate;
+		struct sockaddr_in w_netmask;
+	} w;
+#define rtm w.w_rtm
+
+	memset(&w, 0, sizeof(w));
+	rtm.rtm_msglen = sizeof(w);
+	rtm.rtm_version = RTM_VERSION;
+	rtm.rtm_type = (action == ADD ? RTM_ADD :
+				(action == DELETE ? RTM_DELETE : RTM_CHANGE));
+#undef rt_dst
+	rtm.rtm_flags = ort->rtu_flags;
+	rtm.rtm_seq = ++seqno;
+	rtm.rtm_addrs = RTA_DST|RTA_GATEWAY;
+	memmove(&w.w_dst, &ort->rtu_dst, sizeof(w.w_dst));
+	memmove(&w.w_gate, &ort->rtu_router, sizeof(w.w_gate));
+	w.w_dst.sin_family = AF_INET;
+	w.w_dst.sin_len = sizeof(w.w_dst);
+	w.w_gate.sa_family = AF_INET;
+	w.w_gate.sa_len = sizeof(w.w_gate);
+	if (rtm.rtm_flags & RTF_HOST) {
+		rtm.rtm_msglen -= sizeof(w.w_netmask);
+	} else {
+		register char *cp;
+		int len;
+
+		rtm.rtm_addrs |= RTA_NETMASK;
+		w.w_netmask.sin_addr.s_addr =
+			inet_maskof(w.w_dst.sin_addr.s_addr);
+		for (cp = (char *)(1 + &w.w_netmask.sin_addr);
+				    --cp > (char *) &w.w_netmask; )
+			if (*cp)
+				break;
+		len = cp - (char *)&w.w_netmask;
+		if (len) {
+			len++;
+			w.w_netmask.sin_len = len;
+			len = 1 + ((len - 1) | (sizeof(long) - 1));
+		} else 
+			len = sizeof(long);
+		rtm.rtm_msglen -= (sizeof(w.w_netmask) - len);
+	}
+	errno = 0;
+	return (install ? write(r, (char *)&w, rtm.rtm_msglen) : (errno = 0));
+#endif  /* RTM_ADD */
+}
diff --git a/routed.tproj/timer.c b/routed.tproj/timer.c
new file mode 100644
index 0000000..cf8e3ba
--- /dev/null
+++ b/routed.tproj/timer.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "defs.h"
+
+int	faketime;
+
+/*
+ * Timer routine.  Performs routing information supply
+ * duties and manages timers on routing table entries.
+ * Management of the RTS_CHANGED bit assumes that we broadcast
+ * each time called.
+ */
+void
+timer()
+{
+	register struct rthash *rh;
+	register struct rt_entry *rt;
+	struct rthash *base = hosthash;
+	int doinghost = 1, timetobroadcast;
+	extern int externalinterfaces;
+
+	(void) gettimeofday(&now, (struct timezone *)NULL);
+	faketime += TIMER_RATE;
+	if (lookforinterfaces && (faketime % CHECK_INTERVAL) == 0)
+		ifinit();
+	timetobroadcast = supplier && (faketime % SUPPLY_INTERVAL) == 0;
+again:
+	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
+		rt = rh->rt_forw;
+		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
+			/*
+			 * We don't advance time on a routing entry for
+			 * a passive gateway, or any interface if we're
+			 * not acting as supplier.
+			 */
+			if (!(rt->rt_state & RTS_PASSIVE) &&
+			    (supplier || !(rt->rt_state & RTS_INTERFACE)))
+				rt->rt_timer += TIMER_RATE;
+			if (rt->rt_timer >= GARBAGE_TIME) {
+				rt = rt->rt_back;
+				rtdelete(rt->rt_forw);
+				continue;
+			}
+			if (rt->rt_timer >= EXPIRE_TIME &&
+			    rt->rt_metric < HOPCNT_INFINITY)
+				rtchange(rt, &rt->rt_router, HOPCNT_INFINITY);
+			rt->rt_state &= ~RTS_CHANGED;
+		}
+	}
+	if (doinghost) {
+		doinghost = 0;
+		base = nethash;
+		goto again;
+	}
+	if (timetobroadcast) {
+		toall(supply, 0, (struct interface *)NULL);
+		lastbcast = now;
+		lastfullupdate = now;
+		needupdate = 0;		/* cancel any pending dynamic update */
+		nextbcast.tv_sec = 0;
+	}
+}
+
+/*
+ * On hangup, let everyone know we're going away.
+ */
+hup()
+{
+	register struct rthash *rh;
+	register struct rt_entry *rt;
+	struct rthash *base = hosthash;
+	int doinghost = 1;
+
+	if (supplier) {
+again:
+		for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
+			rt = rh->rt_forw;
+			for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
+				rt->rt_metric = HOPCNT_INFINITY;
+		}
+		if (doinghost) {
+			doinghost = 0;
+			base = nethash;
+			goto again;
+		}
+		toall(supply, 0, (struct interface *)NULL);
+	}
+	exit(1);
+}
diff --git a/routed.tproj/trace.c b/routed.tproj/trace.c
new file mode 100644
index 0000000..8695cf9
--- /dev/null
+++ b/routed.tproj/trace.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#define	RIPCMDS
+#include "defs.h"
+#include <sys/stat.h>
+#include <sys/signal.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include "pathnames.h"
+
+#define	NRECORDS	50		/* size of circular trace buffer */
+#ifdef DEBUG
+FILE	*ftrace = stdout;
+int	traceactions = 0;
+#endif
+static	struct timeval lastlog;
+static	char *savetracename;
+
+traceinit(ifp)
+	register struct interface *ifp;
+{
+	static int iftraceinit();
+
+	if (iftraceinit(ifp, &ifp->int_input) &&
+	    iftraceinit(ifp, &ifp->int_output))
+		return;
+	tracehistory = 0;
+	fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name);
+}
+
+static
+iftraceinit(ifp, ifd)
+	struct interface *ifp;
+	register struct ifdebug *ifd;
+{
+	register struct iftrace *t;
+
+	ifd->ifd_records =
+	  (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
+	if (ifd->ifd_records == 0)
+		return (0);
+	ifd->ifd_front = ifd->ifd_records;
+	ifd->ifd_count = 0;
+	for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
+		t->ift_size = 0;
+		t->ift_packet = 0;
+	}
+	ifd->ifd_if = ifp;
+	return (1);
+}
+
+traceon(file)
+	char *file;
+{
+	struct stat stbuf;
+
+	if (ftrace != NULL)
+		return;
+	if (stat(file, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG)
+		return;
+	savetracename = file;
+	(void) gettimeofday(&now, (struct timezone *)NULL);
+	ftrace = fopen(file, "a");
+	if (ftrace == NULL)
+		return;
+	dup2(fileno(ftrace), 1);
+	dup2(fileno(ftrace), 2);
+	traceactions = 1;
+	fprintf(ftrace, "Tracing enabled %s\n", ctime((time_t *)&now.tv_sec));
+}
+
+traceoff()
+{
+	if (!traceactions)
+		return;
+	if (ftrace != NULL) {
+		int fd = open(_PATH_DEVNULL, O_RDWR);
+
+		fprintf(ftrace, "Tracing disabled %s\n",
+		    ctime((time_t *)&now.tv_sec));
+		fflush(ftrace);
+		(void) dup2(fd, 1);
+		(void) dup2(fd, 2);
+		(void) close(fd);
+		fclose(ftrace);
+		ftrace = NULL;
+	}
+	traceactions = 0;
+	tracehistory = 0;
+	tracepackets = 0;
+	tracecontents = 0;
+}
+
+void
+sigtrace(s)
+	int s;
+{
+
+	if (s == SIGUSR2)
+		traceoff();
+	else if (ftrace == NULL && savetracename)
+		traceon(savetracename);
+	else
+		bumploglevel();
+}
+
+/*
+ * Move to next higher level of tracing when -t option processed or
+ * SIGUSR1 is received.  Successive levels are:
+ *	traceactions
+ *	traceactions + tracepackets
+ *	traceactions + tracehistory (packets and contents after change)
+ *	traceactions + tracepackets + tracecontents
+ */
+bumploglevel()
+{
+
+	(void) gettimeofday(&now, (struct timezone *)NULL);
+	if (traceactions == 0) {
+		traceactions++;
+		if (ftrace)
+			fprintf(ftrace, "Tracing actions started %s\n",
+			    ctime((time_t *)&now.tv_sec));
+	} else if (tracepackets == 0) {
+		tracepackets++;
+		tracehistory = 0;
+		tracecontents = 0;
+		if (ftrace)
+			fprintf(ftrace, "Tracing packets started %s\n",
+			    ctime((time_t *)&now.tv_sec));
+	} else if (tracehistory == 0) {
+		tracehistory++;
+		if (ftrace)
+			fprintf(ftrace, "Tracing history started %s\n",
+			    ctime((time_t *)&now.tv_sec));
+	} else {
+		tracepackets++;
+		tracecontents++;
+		tracehistory = 0;
+		if (ftrace)
+			fprintf(ftrace, "Tracing packet contents started %s\n",
+			    ctime((time_t *)&now.tv_sec));
+	}
+	if (ftrace)
+		fflush(ftrace);
+}
+
+trace(ifd, who, p, len, m)
+	register struct ifdebug *ifd;
+	struct sockaddr *who;
+	char *p;
+	int len, m;
+{
+	register struct iftrace *t;
+
+	if (ifd->ifd_records == 0)
+		return;
+	t = ifd->ifd_front++;
+	if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
+		ifd->ifd_front = ifd->ifd_records;
+	if (ifd->ifd_count < NRECORDS)
+		ifd->ifd_count++;
+	if (t->ift_size > 0 && t->ift_size < len && t->ift_packet) {
+		free(t->ift_packet);
+		t->ift_packet = 0;
+	}
+	t->ift_stamp = now;
+	t->ift_who = *who;
+	if (len > 0 && t->ift_packet == 0) {
+		t->ift_packet = malloc(len);
+		if (t->ift_packet == 0)
+			len = 0;
+	}
+	if (len > 0)
+		memmove(t->ift_packet, p, len);
+	t->ift_size = len;
+	t->ift_metric = m;
+}
+
+traceaction(fd, action, rt)
+	FILE *fd;
+	char *action;
+	struct rt_entry *rt;
+{
+	struct sockaddr_in *dst, *gate;
+	static struct bits {
+		int	t_bits;
+		char	*t_name;
+	} flagbits[] = {
+		{ RTF_UP,	"UP" },
+		{ RTF_GATEWAY,	"GATEWAY" },
+		{ RTF_HOST,	"HOST" },
+		{ 0 }
+	}, statebits[] = {
+		{ RTS_PASSIVE,	"PASSIVE" },
+		{ RTS_REMOTE,	"REMOTE" },
+		{ RTS_INTERFACE,"INTERFACE" },
+		{ RTS_CHANGED,	"CHANGED" },
+		{ RTS_INTERNAL,	"INTERNAL" },
+		{ RTS_EXTERNAL,	"EXTERNAL" },
+		{ RTS_SUBNET,	"SUBNET" },
+		{ 0 }
+	};
+	register struct bits *p;
+	register int first;
+	char *cp;
+	struct interface *ifp;
+
+	if (fd == NULL)
+		return;
+	if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) {
+		fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec));
+		lastlog = now;
+	}
+	fprintf(fd, "%s ", action);
+	dst = (struct sockaddr_in *)&rt->rt_dst;
+	gate = (struct sockaddr_in *)&rt->rt_router;
+	fprintf(fd, "dst %s, ", inet_ntoa(dst->sin_addr));
+	fprintf(fd, "router %s, metric %d, flags",
+	     inet_ntoa(gate->sin_addr), rt->rt_metric);
+	cp = " %s";
+	for (first = 1, p = flagbits; p->t_bits > 0; p++) {
+		if ((rt->rt_flags & p->t_bits) == 0)
+			continue;
+		fprintf(fd, cp, p->t_name);
+		if (first) {
+			cp = "|%s";
+			first = 0;
+		}
+	}
+	fprintf(fd, " state");
+	cp = " %s";
+	for (first = 1, p = statebits; p->t_bits > 0; p++) {
+		if ((rt->rt_state & p->t_bits) == 0)
+			continue;
+		fprintf(fd, cp, p->t_name);
+		if (first) {
+			cp = "|%s";
+			first = 0;
+		}
+	}
+	fprintf(fd, " timer %d\n", rt->rt_timer);
+	if (tracehistory && !tracepackets &&
+	    (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
+		dumpif(fd, rt->rt_ifp);
+	fflush(fd);
+	if (ferror(fd))
+		traceoff();
+}
+
+tracenewmetric(fd, rt, newmetric)
+	FILE *fd;
+	struct rt_entry *rt;
+	int newmetric;
+{
+	struct sockaddr_in *dst, *gate;
+
+	if (fd == NULL)
+		return;
+	if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) {
+		fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec));
+		lastlog = now;
+	}
+	dst = (struct sockaddr_in *)&rt->rt_dst;
+	gate = (struct sockaddr_in *)&rt->rt_router;
+	fprintf(fd, "CHANGE metric dst %s, ", inet_ntoa(dst->sin_addr));
+	fprintf(fd, "router %s, from %d to %d\n",
+	     inet_ntoa(gate->sin_addr), rt->rt_metric, newmetric);
+	fflush(fd);
+	if (ferror(fd))
+		traceoff();
+}
+
+dumpif(fd, ifp)
+	FILE *fd;
+	register struct interface *ifp;
+{
+	if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) {
+		fprintf(fd, "*** Packet history for interface %s ***\n",
+			ifp->int_name);
+#ifdef notneeded
+		dumptrace(fd, "to", &ifp->int_output);
+#endif
+		dumptrace(fd, "from", &ifp->int_input);
+		fprintf(fd, "*** end packet history ***\n");
+	}
+}
+
+dumptrace(fd, dir, ifd)
+	FILE *fd;
+	char *dir;
+	register struct ifdebug *ifd;
+{
+	register struct iftrace *t;
+	char *cp = !strcmp(dir, "to") ? "Output" : "Input";
+
+	if (ifd->ifd_front == ifd->ifd_records &&
+	    ifd->ifd_front->ift_size == 0) {
+		fprintf(fd, "%s: no packets.\n", cp);
+		fflush(fd);
+		return;
+	}
+	fprintf(fd, "%s trace:\n", cp);
+	t = ifd->ifd_front - ifd->ifd_count;
+	if (t < ifd->ifd_records)
+		t += NRECORDS;
+	for ( ; ifd->ifd_count; ifd->ifd_count--, t++) {
+		if (t >= ifd->ifd_records + NRECORDS)
+			t = ifd->ifd_records;
+		if (t->ift_size == 0)
+			continue;
+		dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size,
+		    &t->ift_stamp);
+	}
+}
+
+dumppacket(fd, dir, who, cp, size, stamp)
+	FILE *fd;
+	struct sockaddr_in *who;		/* should be sockaddr */
+	char *dir, *cp;
+	register int size;
+	struct timeval *stamp;
+{
+	register struct rip *msg = (struct rip *)cp;
+	register struct netinfo *n;
+
+	if (fd == NULL)
+		return;
+	if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX)
+		fprintf(fd, "%s %s %s.%d %.19s:\n", ripcmds[msg->rip_cmd],
+		    dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port),
+		    ctime((time_t *)&stamp->tv_sec));
+	else {
+		fprintf(fd, "Bad cmd 0x%x %s %x.%d %.19s\n", msg->rip_cmd,
+		    dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port));
+		fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet,
+		    ctime((time_t *)&stamp->tv_sec));
+		fflush(fd);
+		return;
+	}
+	if (tracepackets && tracecontents == 0) {
+		fflush(fd);
+		return;
+	}
+	switch (msg->rip_cmd) {
+
+	case RIPCMD_REQUEST:
+	case RIPCMD_RESPONSE:
+		size -= 4 * sizeof (char);
+		n = msg->rip_nets;
+		for (; size > 0; n++, size -= sizeof (struct netinfo)) {
+			if (size < sizeof (struct netinfo)) {
+				fprintf(fd, "(truncated record, len %d)\n",
+				    size);
+				break;
+			}
+			if (sizeof(n->rip_dst.sa_family) > 1)
+			    n->rip_dst.sa_family = ntohs(n->rip_dst.sa_family);
+
+			switch ((int)n->rip_dst.sa_family) {
+
+			case AF_INET:
+				fprintf(fd, "\tdst %s metric %d\n",
+#define	satosin(sa)	((struct sockaddr_in *)&sa)
+				     inet_ntoa(satosin(n->rip_dst)->sin_addr),
+				     ntohl(n->rip_metric));
+				break;
+
+			default:
+				fprintf(fd, "\taf %d? metric %d\n",
+				     n->rip_dst.sa_family,
+				     ntohl(n->rip_metric));
+				break;
+			}
+		}
+		break;
+
+	case RIPCMD_TRACEON:
+		fprintf(fd, "\tfile=%*s\n", size, msg->rip_tracefile);
+		break;
+
+	case RIPCMD_TRACEOFF:
+		break;
+	}
+	fflush(fd);
+	if (ferror(fd))
+		traceoff();
+}
diff --git a/routed.tproj/trace.h b/routed.tproj/trace.h
new file mode 100644
index 0000000..aa7f753
--- /dev/null
+++ b/routed.tproj/trace.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/5/93
+ */
+
+/*
+ * Routing table management daemon.
+ */
+
+/*
+ * Trace record format.
+ */
+struct	iftrace {
+	struct	timeval ift_stamp;	/* time stamp */
+	struct	sockaddr ift_who;	/* from/to */
+	char	*ift_packet;		/* pointer to packet */
+	short	ift_size;		/* size of packet */
+	short	ift_metric;		/* metric on associated metric */
+};
+
+/*
+ * Per interface packet tracing buffers.  An incoming and
+ * outgoing circular buffer of packets is maintained, per
+ * interface, for debugging.  Buffers are dumped whenever
+ * an interface is marked down.
+ */
+struct	ifdebug {
+	struct	iftrace *ifd_records;	/* array of trace records */
+	struct	iftrace *ifd_front;	/* next empty trace record */
+	int	ifd_count;		/* number of unprinted records */
+	struct	interface *ifd_if;	/* for locating stuff */
+};
+
+/*
+ * Packet tracing stuff.
+ */
+EXTERN int	tracepackets;		/* watch packets as they go by */
+EXTERN int	tracecontents;		/* watch packet contents as they go by */
+EXTERN int	traceactions;		/* on/off */
+EXTERN int	tracehistory;		/* on/off */
+EXTERN FILE	*ftrace;		/* output trace file */
+
+#define	TRACE_ACTION(action, route) { \
+	  if (traceactions) \
+		traceaction(ftrace, action, route); \
+	}
+#define	TRACE_NEWMETRIC(route, newmetric) { \
+	  if (traceactions) \
+		tracenewmetric(ftrace, route, newmetric); \
+	}
+#define	TRACE_INPUT(ifp, src, pack, size) { \
+	  if (tracehistory) { \
+		ifp = if_iflookup(src); \
+		if (ifp) \
+			trace(&ifp->int_input, src, pack, size, \
+				ntohl(ifp->int_metric)); \
+	  } \
+	  if (tracepackets) \
+		dumppacket(ftrace, "from", src, pack, size, &now); \
+	}
+#define	TRACE_OUTPUT(ifp, dst, size) { \
+	  if (tracehistory && ifp) \
+		trace(&ifp->int_output, dst, packet, size, ifp->int_metric); \
+	  if (tracepackets) \
+		dumppacket(ftrace, "to", dst, packet, size, &now); \
+	}
diff --git a/rpc_yppasswdd.tproj/Makefile b/rpc_yppasswdd.tproj/Makefile
new file mode 100644
index 0000000..9c1a49e
--- /dev/null
+++ b/rpc_yppasswdd.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rpc.yppasswdd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = yppasswd.h
+
+CFILES = passwd.c rpc.yppasswdd.c yppasswdd_mkpw.c yppasswdd_proc.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
+            rpc.yppasswdd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rpc_yppasswdd.tproj/Makefile.postamble b/rpc_yppasswdd.tproj/Makefile.postamble
new file mode 100644
index 0000000..509e7f5
--- /dev/null
+++ b/rpc_yppasswdd.tproj/Makefile.postamble
@@ -0,0 +1,101 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGE: langage in which the project is written (default "English")
+#  LOCAL_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/rpc_yppasswdd.tproj/Makefile.preamble b/rpc_yppasswdd.tproj/Makefile.preamble
new file mode 100644
index 0000000..83f25c7
--- /dev/null
+++ b/rpc_yppasswdd.tproj/Makefile.preamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. <<default?>>
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSION: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
diff --git a/rpc_yppasswdd.tproj/PB.project b/rpc_yppasswdd.tproj/PB.project
new file mode 100644
index 0000000..4e3a617
--- /dev/null
+++ b/rpc_yppasswdd.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (yppasswd.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (passwd.c, rpc.yppasswdd.c, yppasswdd_mkpw.c, yppasswdd_proc.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, rpc.yppasswdd.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rpc.yppasswdd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rpc_yppasswdd.tproj/passwd.c b/rpc_yppasswdd.tproj/passwd.c
new file mode 100644
index 0000000..a5d9982
--- /dev/null
+++ b/rpc_yppasswdd.tproj/passwd.c
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$NetBSD: passwd.c,v 1.11 1997/12/31 05:47:15 thorpej Exp $	*/
+
+/*
+ * Copyright (c) 1987, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: passwd.c,v 1.11 1997/12/31 05:47:15 thorpej Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <paths.h>
+#include <signal.h>
+#include <limits.h>
+#include <util.h>
+
+static void	pw_cont __P((int sig));
+static int	pw_equal __P((char *buf, struct passwd *old_pw));
+
+int
+pw_lock(retries)
+	int retries;
+{
+	int i, fd;
+	mode_t old_mode;
+
+	/* Acquire the lock file. */
+	old_mode = umask(0);
+	fd = open(_PATH_MASTERPASSWD_LOCK, O_WRONLY|O_CREAT|O_EXCL, 0600);
+	for (i = 0; i < retries && fd < 0 && errno == EEXIST; i++) {
+		sleep(1);
+		fd = open(_PATH_MASTERPASSWD_LOCK, O_WRONLY|O_CREAT|O_EXCL,
+			  0600);
+	}
+	umask(old_mode);
+	return(fd);
+}
+
+int
+pw_mkdb()
+{
+	int pstat;
+	pid_t pid;
+	struct stat sb;
+
+	/* A zero length passwd file is never ok */
+	if (stat(_PATH_MASTERPASSWD_LOCK, &sb) == 0) {
+		if (sb.st_size == 0) {
+			warnx("%s is zero length", _PATH_MASTERPASSWD_LOCK);
+			return (-1);
+		}
+	}
+
+	pid = vfork();
+	if (pid == 0) {
+		execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p",
+		      _PATH_MASTERPASSWD_LOCK, NULL);
+		_exit(1);
+	}
+	pid = waitpid(pid, &pstat, 0);
+	if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
+		return(-1);
+	return(0);
+}
+
+int
+pw_abort()
+{
+	return(unlink(_PATH_MASTERPASSWD_LOCK));
+}
+
+/* Everything below this point is intended for the convenience of programs
+ * which allow a user to interactively edit the passwd file.  Errors in the
+ * routines below will cause the process to abort. */
+
+static pid_t editpid = -1;
+
+static void
+pw_cont(sig)
+	int sig;
+{
+
+	if (editpid != -1)
+		kill(editpid, sig);
+}
+
+void
+pw_init()
+{
+	struct rlimit rlim;
+
+	/* Unlimited resource limits. */
+	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
+	(void)setrlimit(RLIMIT_CPU, &rlim);
+	(void)setrlimit(RLIMIT_FSIZE, &rlim);
+	(void)setrlimit(RLIMIT_STACK, &rlim);
+	(void)setrlimit(RLIMIT_DATA, &rlim);
+	(void)setrlimit(RLIMIT_RSS, &rlim);
+
+	/* Don't drop core (not really necessary, but GP's). */
+	rlim.rlim_cur = rlim.rlim_max = 0;
+	(void)setrlimit(RLIMIT_CORE, &rlim);
+
+	/* Turn off signals. */
+	(void)signal(SIGALRM, SIG_IGN);
+	(void)signal(SIGHUP, SIG_IGN);
+	(void)signal(SIGINT, SIG_IGN);
+	(void)signal(SIGPIPE, SIG_IGN);
+	(void)signal(SIGQUIT, SIG_IGN);
+	(void)signal(SIGTERM, SIG_IGN);
+	(void)signal(SIGCONT, pw_cont);
+}
+
+void
+pw_edit(notsetuid, filename)
+	int notsetuid;
+	const char *filename;
+{
+	int i, xargc, pstat;
+	char *p, *editor;
+	char **xargv;
+#ifdef __GNUC__
+	(void) &editor;
+#endif
+
+	if (filename == NULL)
+		filename = _PATH_MASTERPASSWD_LOCK;
+	if ((editor = getenv("EDITOR")) == NULL)
+		editor = strdup(_PATH_VI);
+	else
+		editor = strdup(editor);
+	if ((p = strrchr(editor, '/')))
+		++p;
+	else
+		p = editor;
+
+	/* Scan editor string, count spaces, allocate arg vector. */
+	for (i = 0, xargc = 0; p[i] != '\0'; i++) {
+		if (isspace(p[i])) {
+			while (isspace(p[i++]))
+				/* skip white space */ ;
+			if (p[i] == '\0')
+				break;
+			xargc++;
+		}
+	}
+
+	/* argv[0] + <xargc args> + filename + NULL */
+	xargv = (char **)malloc(sizeof(char *) * (xargc + 3));
+	if (xargv == NULL)
+		pw_error("malloc failed", 1, 1);
+
+	i = 0;
+	xargv[i++] = p;
+	for (; *p != '\0'; p++) {
+		if (isspace(*p)) {
+			while(isspace(*p))
+				*p++ = '\0';	/* blast whitespace */
+			if (*p == '\0')
+				break;
+			xargv[i++] = p;
+		}
+	}
+
+	xargv[i++] = (char *)filename;
+	xargv[i] = NULL;
+
+	if (!(editpid = vfork())) {
+		if (notsetuid) {
+			setgid(getgid());
+			setuid(getuid());
+		}
+		execvp(editor, xargv);
+		_exit(1);
+	}
+	for (;;) {
+		editpid = waitpid(editpid, (int *)&pstat, WUNTRACED);
+		if (editpid == -1)
+			pw_error(editor, 1, 1);
+		else if (WIFSTOPPED(pstat))
+			raise(WSTOPSIG(pstat));
+		else if (WIFEXITED(pstat) && WEXITSTATUS(pstat) == 0)
+			break;
+		else
+			pw_error(editor, 1, 1);
+	}
+	editpid = -1;
+	free(editor);
+	free(xargv);
+}
+
+void
+pw_prompt()
+{
+	int c;
+
+	(void)printf("re-edit the password file? [y]: ");
+	(void)fflush(stdout);
+	c = getchar();
+	if (c != EOF && c != '\n')
+		while (getchar() != '\n');
+	if (c == 'n')
+		pw_error(NULL, 0, 0);
+}
+
+/* for use in pw_copy(). Compare a pw entry to a pw struct. */
+static int
+pw_equal (buf, pw)
+	char *buf;
+	struct passwd *pw;
+{
+	struct passwd buf_pw;
+	int len = strlen (buf);
+	if (buf[len-1] == '\n')
+		buf[len-1] = '\0';
+	if (!pw_scan(buf, &buf_pw, NULL))
+		return 0;
+	return !strcmp(pw->pw_name, buf_pw.pw_name)
+		&& pw->pw_uid == buf_pw.pw_uid
+		&& pw->pw_gid == buf_pw.pw_gid
+		&& !strcmp(pw->pw_class, buf_pw.pw_class)
+		&& (long)pw->pw_change == (long)buf_pw.pw_change
+		&& (long)pw->pw_expire == (long)buf_pw.pw_expire
+		&& !strcmp(pw->pw_gecos, buf_pw.pw_gecos)
+		&& !strcmp(pw->pw_dir, buf_pw.pw_dir)
+		&& !strcmp(pw->pw_shell, buf_pw.pw_shell);
+}
+
+void
+pw_copy(ffd, tfd, pw, old_pw)
+	int ffd, tfd;
+	struct passwd *pw, *old_pw;
+{
+	FILE *from, *to;
+	int done;
+	char *p, buf[8192];
+
+	if (!(from = fdopen(ffd, "r")))
+		pw_error(_PATH_MASTERPASSWD, 1, 1);
+	if (!(to = fdopen(tfd, "w")))
+		pw_error(_PATH_MASTERPASSWD_LOCK, 1, 1);
+
+	for (done = 0; fgets(buf, sizeof(buf), from);) {
+		if (!strchr(buf, '\n')) {
+			warnx("%s: line too long", _PATH_MASTERPASSWD);
+			pw_error(NULL, 0, 1);
+		}
+		if (done) {
+			(void)fprintf(to, "%s", buf);
+			if (ferror(to))
+				goto err;
+			continue;
+		}
+		if (buf[0] == '#') {
+			/* skip comments for Rhapsody. */
+			continue;
+		}
+		if (!(p = strchr(buf, ':'))) {
+			warnx("%s: corrupted entry", _PATH_MASTERPASSWD);
+			pw_error(NULL, 0, 1);
+		}
+		*p = '\0';
+		if (strcmp(buf, pw->pw_name)) {
+			*p = ':';
+			(void)fprintf(to, "%s", buf);
+			if (ferror(to))
+				goto err;
+			continue;
+		}
+		*p = ':';
+		if (old_pw && !pw_equal(buf, old_pw)) {
+			warnx("%s: entry inconsistent",
+			      _PATH_MASTERPASSWD);
+			pw_error(NULL, 0, 1);
+		}
+		(void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
+		    pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
+		    pw->pw_class, (long)pw->pw_change, (long)pw->pw_expire,
+		    pw->pw_gecos, pw->pw_dir, pw->pw_shell);
+		done = 1;
+		if (ferror(to))
+			goto err;
+	}
+	/* Only append a new entry if real uid is root! */
+	if (!done) 
+		if (getuid() == 0)
+			(void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
+			    pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
+			    pw->pw_class, (long)pw->pw_change,
+			    (long)pw->pw_expire, pw->pw_gecos, pw->pw_dir,
+			    pw->pw_shell);
+		else
+			warnx("%s: changes not made, no such entry",
+		      	    _PATH_MASTERPASSWD);
+
+	if (ferror(to))
+err:		pw_error(NULL, 1, 1);
+	(void)fclose(to);
+}
+
+int
+pw_scan(bp, pw, flags)
+	char *bp;
+	struct passwd *pw;
+	int *flags;
+{
+	unsigned long id;
+	int root;
+	char *p, *sh, *ep;
+
+	if (flags != (int *)NULL)
+		*flags = 0;
+
+	if (!(pw->pw_name = strsep(&bp, ":")))		/* login */
+		goto fmt;
+	root = !strcmp(pw->pw_name, "root");
+
+	if (!(pw->pw_passwd = strsep(&bp, ":")))	/* passwd */
+		goto fmt;
+
+	if (!(p = strsep(&bp, ":")))			/* uid */
+		goto fmt;
+	id = strtoul(p, &ep, 10);
+	if (root && id) {
+		warnx("root uid should be 0");
+		return (0);
+	}
+	if (id > UID_MAX || *ep != '\0') {
+		warnx("invalid uid '%s'", p);
+		return (0);
+	}
+	pw->pw_uid = (uid_t)id;
+	if ((*p == '\0') && (flags != (int *)NULL))
+		*flags |= _PASSWORD_NOUID;
+
+	if (!(p = strsep(&bp, ":")))			/* gid */
+		goto fmt;
+	id = strtoul(p, &ep, 10);
+	if (id > GID_MAX || *ep != '\0') {
+		warnx("invalid gid '%s'", p);
+		return (0);
+	}
+	pw->pw_gid = (gid_t)id;
+	if ((*p == '\0') && (flags != (int *)NULL))
+		*flags |= _PASSWORD_NOGID;
+
+	pw->pw_class = strsep(&bp, ":");		/* class */
+	if (!(p = strsep(&bp, ":")))			/* change */
+		goto fmt;
+	pw->pw_change = atol(p);
+	if ((*p == '\0') && (flags != (int *)NULL))
+		*flags |= _PASSWORD_NOCHG;
+	if (!(p = strsep(&bp, ":")))			/* expire */
+		goto fmt;
+	pw->pw_expire = atol(p);
+	if ((*p == '\0') && (flags != (int *)NULL))
+		*flags |= _PASSWORD_NOEXP;
+	pw->pw_gecos = strsep(&bp, ":");		/* gecos */
+	pw->pw_dir = strsep(&bp, ":");			/* directory */
+	if (!(pw->pw_shell = strsep(&bp, ":")))		/* shell */
+		goto fmt;
+
+	p = pw->pw_shell;
+	if (root && *p)					/* empty == /bin/sh */
+		for (setusershell();;) {
+			if (!(sh = getusershell())) {
+				warnx("warning, unknown root shell");
+				break;
+			}
+			if (!strcmp(p, sh))
+				break;	
+		}
+
+	if ((p = strsep(&bp, ":"))) {			/* too many */
+fmt:		warnx("corrupted entry");
+		return (0);
+	}
+
+	return (1);
+}
+
+void
+pw_error(name, err, eval)
+	const char *name;
+	int err, eval;
+{
+	if (err)
+		warn(name);
+
+	warnx("%s: unchanged", _PATH_MASTERPASSWD);
+	pw_abort();
+	exit(eval);
+}
+
diff --git a/rpc_yppasswdd.tproj/rpc.yppasswdd.8 b/rpc_yppasswdd.tproj/rpc.yppasswdd.8
new file mode 100644
index 0000000..8cda3b5
--- /dev/null
+++ b/rpc_yppasswdd.tproj/rpc.yppasswdd.8
@@ -0,0 +1,97 @@
+.\"	$OpenBSD: rpc.yppasswdd.8,v 1.7 1997/08/19 07:00:50 niklas Exp $
+.\"
+.\" Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by Mats O Jansson
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"
+.Dd July 3, 1994
+.Dt RPC.YPPASSWDD 8
+.Os
+.Sh NAME
+.Nm rpc.yppasswdd
+.Nd YP update password file daemon
+.Sh SYNOPSIS
+.Nm rpc.yppasswdd
+.Op Fl d Ar directory
+.Op Fl noshell
+.Op Fl nogecos
+.Op Fl nopw
+.Op Fl m Ar arg1 arg2 ... 
+.Sh DESCRIPTION
+.Nm rpc.yppasswdd
+must be running on the YP master server to allow users to change information
+in the password file. If the user needs to change his password this is
+normally done with a program called
+.Nm yppasswd .
+This program doesn't exist in OpenBSD but is integrated into
+.Xr passwd 1 .
+.Nm passwd
+will automatically determine which password database should
+be modified.
+To force a change of a YP password when a local one also exists, use
+.Nm passwd -y .
+.Pp
+Other user information can be changed with
+.Xr chpass 1 .
+.Pp
+If the file
+.Nm /var/yp/yppasswdd.log
+exists then messages will be written to the file.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl d Ar directory
+Use the specified directory to get at the password-related files instead
+of /etc.
+.It Fl noshell
+Don't allow changes of the shell field in the passwd file.
+.It Fl nogecos
+Don't allow changes of the gecos field in the passwd file.
+.It Fl nopw
+Don't allow changes of the password in the passwd file.
+.It Fl m Ar arg1 arg2 ...
+Don't use 
+.Ar /var/yp/securenet .
+Use another file with another file format. For futher information see
+man page for
+.Ar ypserv.acl .
+.El
+.Sh FILES
+.Bl -tag -width /var/yp/yppasswdd.log -compact
+.It Pa /var/yp/yppasswdd.log
+.It Pa /etc/passwd
+.It Pa /etc/master.passwd
+.El
+.Sh SEE ALSO
+.Xr yp 8 ,
+.Xr ypserv.acl 5 ,
+.Xr securenet 5 ,
+.Xr ypbind 1 
+.Sh AUTHOR
+Mats O Jansson <moj@stacken.kth.se>
diff --git a/rpc_yppasswdd.tproj/rpc.yppasswdd.c b/rpc_yppasswdd.tproj/rpc.yppasswdd.c
new file mode 100644
index 0000000..1a88517
--- /dev/null
+++ b/rpc_yppasswdd.tproj/rpc.yppasswdd.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: rpc.yppasswdd.c,v 1.9 1997/08/19 07:00:51 niklas Exp $	*/
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: rpc.yppasswdd.c,v 1.9 1997/08/19 07:00:51 niklas Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <pwd.h>
+#include <util.h>
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+
+#include "yppasswd.h"
+
+static void yppasswddprog_1();
+void    sig_child();
+
+int     noshell, nogecos, nopw, domake;
+char    make_arg[1024] = "make";
+char   *progname = "yppasswdd";
+char   *tempname;
+int	debug = 0;
+
+void
+usage()
+{
+	fprintf(stderr, "%s%s",
+	    "usage: rpc.yppasswdd ",
+	    "[-d] [-noshell] [-nogecos] [-nopw] [-m arg1 arg2 ... ]\n");
+	exit(1);
+}
+
+int
+main(argc, argv)
+	int     argc;
+	char   *argv[];
+{
+	SVCXPRT *transp;
+	int     i = 1;
+
+	while (i < argc) {
+		if (argv[i][0] == '-') {
+			if (strcmp("-noshell", argv[i]) == 0) {
+				noshell = 1;
+			} else if (strcmp("-nogecos", argv[i]) == 0) {
+				nogecos = 1;
+			} else if (strcmp("-nopw", argv[i]) == 0) {
+				nopw = 1;
+			} else if (strcmp("-m", argv[i]) == 0) {
+				domake = 1;
+				while (i < argc) {
+					strcat(make_arg, " ");
+					strcat(make_arg, argv[i]);
+					i++;
+				}
+			} else if (strcmp("-d", argv[i]) == 0) {
+				debug = 1;
+			} else
+				usage();
+			i++;
+		} else
+			usage();
+	}
+
+	if (debug == 0) {
+		(void) daemon(0, 0);
+	}
+	chdir("/etc");
+
+/*
+	freopen("/dev/null", "r", stdin);
+	freopen("/var/yp/stderr", "w", stderr);
+	freopen("/var/yp/stdout", "w", stdout);
+*/
+	(void) pmap_unset(YPPASSWDPROG, YPPASSWDVERS);
+
+	(void) signal(SIGCHLD, sig_child);
+
+	transp = svcudp_create(RPC_ANYSOCK);
+	if (transp == NULL) {
+		(void) fprintf(stderr, "cannot create udp service.\n");
+		exit(1);
+	}
+	if (!svc_register(transp, YPPASSWDPROG, YPPASSWDVERS, yppasswddprog_1,
+	    IPPROTO_UDP)) {
+		fprintf(stderr, "unable to register YPPASSWDPROG, YPPASSWDVERS, udp\n");
+		exit(1);
+	}
+	transp = svctcp_create(RPC_ANYSOCK, 0, 0);
+	if (transp == NULL) {
+		(void) fprintf(stderr, "cannot create tcp service.\n");
+		exit(1);
+	}
+	if (!svc_register(transp, YPPASSWDPROG, YPPASSWDVERS, yppasswddprog_1,
+	    IPPROTO_TCP)) {
+		fprintf(stderr, "unable to register YPPASSWDPROG, YPPASSWDVERS, tcp\n");
+		exit(1);
+	}
+	svc_run();
+	(void) fprintf(stderr, "svc_run returned\n");
+	exit(1);
+}
+
+static void
+yppasswddprog_1(rqstp, transp)
+	struct svc_req *rqstp;
+	SVCXPRT *transp;
+{
+	union {
+		yppasswd yppasswdproc_update_1_arg;
+	}       argument;
+	char   *result;
+	bool_t(*xdr_argument) (), (*xdr_result) ();
+	char   *(*local) ();
+
+	switch (rqstp->rq_proc) {
+	case NULLPROC:
+		(void) svc_sendreply(transp, xdr_void, (char *) NULL);
+		return;
+	case YPPASSWDPROC_UPDATE:
+		xdr_argument = xdr_yppasswd;
+		xdr_result = xdr_int;
+		local = (char *(*) ()) yppasswdproc_update_1_svc;
+		break;
+	default:
+		svcerr_noproc(transp);
+		return;
+	}
+	bzero((char *) &argument, sizeof(argument));
+	if (!svc_getargs(transp, xdr_argument, (caddr_t) & argument)) {
+		svcerr_decode(transp);
+		return;
+	}
+	result = (*local) (&argument, rqstp, transp);
+}
+
+void
+sig_child()
+{
+	int save_errno = errno;
+
+	while (wait3((int *) NULL, WNOHANG, (struct rusage *) NULL) > 0)
+		;
+	errno = save_errno;
+}
diff --git a/rpc_yppasswdd.tproj/yppasswd.h b/rpc_yppasswdd.tproj/yppasswd.h
new file mode 100644
index 0000000..5592e87
--- /dev/null
+++ b/rpc_yppasswdd.tproj/yppasswd.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppasswd.h,v 1.4 1997/08/19 07:00:51 niklas Exp $*/
+
+/*
+ * Copyright (c) 1995 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _YPPASSWD_H_RPCGEN
+#define _YPPASSWD_H_RPCGEN
+
+struct x_passwd {
+	char *pw_name;
+	char *pw_passwd;
+	int pw_uid;
+	int pw_gid;
+	char *pw_gecos;
+	char *pw_dir;
+	char *pw_shell;
+};
+typedef struct x_passwd x_passwd;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_x_passwd(XDR *, x_passwd*);
+#elif defined(__STDC__)
+extern  bool_t xdr_x_passwd(XDR *, x_passwd*);
+#else /* Old Style C */
+bool_t xdr_x_passwd();
+#endif /* Old Style C */
+
+
+struct yppasswd {
+	char *oldpass;
+	x_passwd newpw;
+};
+typedef struct yppasswd yppasswd;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_yppasswd(XDR *, yppasswd*);
+#elif defined(__STDC__)
+extern  bool_t xdr_yppasswd(XDR *, yppasswd*);
+#else /* Old Style C */ 
+bool_t xdr_yppasswd();
+#endif /* Old Style C */ 
+
+
+#define YPPASSWDPROG ((u_long)100009)
+#define YPPASSWDVERS ((u_long)1)
+
+#ifdef __cplusplus
+#define YPPASSWDPROC_UPDATE ((u_long)1)
+extern "C" int * yppasswdproc_update_1(yppasswd *, CLIENT *);
+extern "C" int * yppasswdproc_update_1_svc(yppasswd *, struct svc_req *, SVCXPRT *);
+
+#elif defined(__STDC__)
+#define YPPASSWDPROC_UPDATE ((u_long)1)
+extern  int * yppasswdproc_update_1(yppasswd *, CLIENT *);
+extern  int * yppasswdproc_update_1_svc(yppasswd *, struct svc_req *, SVCXPRT *);
+
+#else /* Old Style C */ 
+#define YPPASSWDPROC_UPDATE ((u_long)1)
+extern  int * yppasswdproc_update_1();
+extern  int * yppasswdproc_update_1_svc();
+#endif /* Old Style C */ 
+
+#endif /* !_YPPASSWD_H_RPCGEN */
diff --git a/rpc_yppasswdd.tproj/yppasswdd_mkpw.c b/rpc_yppasswdd.tproj/yppasswdd_mkpw.c
new file mode 100644
index 0000000..6904c44
--- /dev/null
+++ b/rpc_yppasswdd.tproj/yppasswdd_mkpw.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppasswdd_mkpw.c,v 1.16 1997/11/17 23:56:20 gene Exp $	*/
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: yppasswdd_mkpw.c,v 1.16 1997/11/17 23:56:20 gene Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yppasswd.h>
+#include <db.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <util.h>
+#include <ctype.h>
+#include <string.h>
+#include <syslog.h>
+#include <err.h>
+
+extern int noshell;
+extern int nogecos;
+extern int nopw;
+extern int make;
+extern char make_arg[];
+
+static void _pw_copy(int, int, struct passwd *);
+
+/* This is imported from OpenBSD's libutil because it's argument
+ * incompatible with NetBSD's. However, the NetBSD libutil is
+ * at least what the prototypes suggest is in System.framework,
+ * even though I can't find the code. I assume it will be there
+ * eventually. We need to use NetBSD's because it works with the
+ * pwd_mkdb binary that's shipped with Rhapsody. This is an area
+ * where OpenBSD diverges; however, we wanted to keep the OpenBSD
+ * rpc.yppasswdd because the rest of our YP code is from OpenBSD.
+ * What a mess.
+ */
+static void
+_pw_copy(ffd, tfd, pw)
+	int ffd, tfd;
+	struct passwd *pw;
+{
+	FILE   *from, *to;
+	int	done;
+	char   *p, buf[8192];
+
+	if (!(from = fdopen(ffd, "r")))
+		pw_error(_PATH_MASTERPASSWD, 1, 1);
+	if (!(to = fdopen(tfd, "w")))
+		pw_error(_PATH_MASTERPASSWD_LOCK, 1, 1);
+
+	for (done = 0; fgets(buf, sizeof(buf), from);) {
+		if (!strchr(buf, '\n')) {
+			warnx("%s: line too long", _PATH_MASTERPASSWD);
+			pw_error(NULL, 0, 1);
+		}
+		if (done) {
+			(void)fprintf(to, "%s", buf);
+			if (ferror(to))
+				goto err;
+			continue;
+		}
+		if (!(p = strchr(buf, ':'))) {
+			warnx("%s: corrupted entry", _PATH_MASTERPASSWD);
+			pw_error(NULL, 0, 1);
+		}
+		*p = '\0';
+		if (strcmp(buf, pw->pw_name)) {
+			*p = ':';
+			(void)fprintf(to, "%s", buf);
+			if (ferror(to))
+				goto err;
+			continue;
+		}
+		(void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
+		    pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
+		    pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos,
+		    pw->pw_dir, pw->pw_shell);
+		done = 1;
+		if (ferror(to))
+			goto err;
+	}
+	if (!done)
+		(void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
+		    pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
+		    pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos,
+		    pw->pw_dir, pw->pw_shell);
+
+	if (ferror(to))
+err:
+	pw_error(NULL, 0, 1);
+	(void)fclose(to);
+}
+
+
+int
+badchars(base)
+	char *base;
+{
+	int ampr = 0;
+	char *s;
+
+	for (s = base; *s; s++) {
+		if (*s == '&')
+			ampr++;
+		if (!isprint(*s))
+			return 1;
+		if (strchr(":\n\t\r", *s))
+			return 1;
+	}
+	if (ampr > 10)
+		return 1;
+	return 0;
+}
+
+int
+subst(s, from, to)
+	char *s;
+	char from, to;
+{
+	int	n = 0;
+
+	while (*s) {
+		if (*s == from) {
+			*s = to;
+			n++;
+		}
+		s++;
+	}
+	return (n);
+}
+
+int
+make_passwd(argp)
+	yppasswd *argp;
+{
+	struct passwd pw;
+	int     pfd, tfd;
+	char	buf[10], *bp = NULL, *p, *t;
+	int	n;
+	ssize_t cnt;
+	size_t	resid;
+	struct stat st;
+
+	pw_init();
+	pfd = open(_PATH_MASTERPASSWD, O_RDONLY);
+	if (pfd < 0)
+		goto fail;
+	if (fstat(pfd, &st))
+		goto fail;
+	p = bp = malloc((resid = st.st_size) + 1);
+	do {
+		cnt = read(pfd, p, resid);
+		if (cnt < 0)
+			goto fail;
+		p += cnt;
+		resid -= cnt;
+	} while (resid > 0);
+	close(pfd);
+	pfd = -1;
+	*p = '\0';		/* Buf oflow prevention */
+
+	p = bp;
+	subst(p, '\n', '\0');
+	for (n = 1; p < bp + st.st_size; n++, p = t) {
+		t = strchr(p, '\0') + 1;
+		/* Rhapsody allows the passwd file to have comments in it. */
+		if (p[0] == '#') {
+			continue;
+		}
+		cnt = subst(p, ':', '\0');
+		if (cnt != 9) {
+			syslog(LOG_WARNING, "bad entry at line %d of %s", n,
+			    _PATH_MASTERPASSWD);
+			continue;
+		}
+
+		if (strcmp(p, argp->newpw.pw_name) == 0)
+			break;
+	}
+	if (p >= bp + st.st_size)
+		goto fail;
+
+#define	EXPAND(e)	e = p; while (*p++);
+	EXPAND(pw.pw_name);
+	EXPAND(pw.pw_passwd);
+	pw.pw_uid = atoi(p); EXPAND(t);
+	pw.pw_gid = atoi(p); EXPAND(t);
+	EXPAND(pw.pw_class);
+	pw.pw_change = (time_t)atol(p); EXPAND(t);
+	pw.pw_expire = (time_t)atol(p); EXPAND(t);
+	EXPAND(pw.pw_gecos);
+	EXPAND(pw.pw_dir);
+	EXPAND(pw.pw_shell);
+
+	/* crypt() is broken under Rhapsody. It doesn't deal with
+	 * empty keys or salts like other Unices.
+	 */
+	if (pw.pw_passwd[0] != '\0' && argp->oldpass != NULL && argp->oldpass[0] != '\0') {
+		if (strcmp(crypt(argp->oldpass, pw.pw_passwd), pw.pw_passwd) != 0)
+			goto fail;
+	}
+	
+	if (!nopw && badchars(argp->newpw.pw_passwd))
+		goto fail;
+	if (!nogecos && badchars(argp->newpw.pw_gecos))
+		goto fail;
+	if (!nogecos && badchars(argp->newpw.pw_shell))
+		goto fail;
+
+	/*
+	 * Get the new password.  Reset passwd change time to zero; when
+	 * classes are implemented, go and get the "offset" value for this
+	 * class and reset the timer.
+	 */
+	if (!nopw) {
+		pw.pw_passwd = argp->newpw.pw_passwd;
+		pw.pw_change = 0;
+	}
+	if (!nogecos)
+		pw.pw_gecos = argp->newpw.pw_gecos;
+	if (!noshell)
+		pw.pw_shell = argp->newpw.pw_shell;
+
+	for (n = 0, p = pw.pw_gecos; *p; p++)
+		if (*p == '&')
+			n = n + strlen(pw.pw_name) - 1;
+	if (strlen(pw.pw_name) + 1 + strlen(pw.pw_passwd) + 1 +
+	    strlen((sprintf(buf, "%d", pw.pw_uid), buf)) + 1 +
+	    strlen((sprintf(buf, "%d", pw.pw_gid), buf)) + 1 +
+	    strlen(pw.pw_gecos) + n + 1 + strlen(pw.pw_dir) + 1 +
+	    strlen(pw.pw_shell) >= 1023)
+		goto fail;
+
+	pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
+	if (pfd < 0) {
+		syslog(LOG_ERR, "cannot open %s", _PATH_MASTERPASSWD);
+		goto fail;
+	}
+
+	tfd = pw_lock(0);
+	if (tfd < 0)
+		goto fail;
+
+	_pw_copy(pfd, tfd, &pw);
+	pw_mkdb();
+	free(bp);
+
+	if (fork() == 0) {
+		chdir("/var/yp");
+		(void)umask(022);
+		system(make_arg);
+		exit(0);
+	}
+	return (0);
+
+fail:
+	if (bp)
+		free(bp);
+	if (pfd >= 0)
+		close(pfd);
+	return (1);
+}
diff --git a/rpc_yppasswdd.tproj/yppasswdd_proc.c b/rpc_yppasswdd.tproj/yppasswdd_proc.c
new file mode 100644
index 0000000..2053263
--- /dev/null
+++ b/rpc_yppasswdd.tproj/yppasswdd_proc.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppasswdd_proc.c,v 1.5 1997/08/19 07:00:52 niklas Exp $	*/
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: yppasswdd_proc.c,v 1.5 1997/08/19 07:00:52 niklas Exp $";
+#endif
+
+#include <sys/types.h>
+#include <rpc/rpc.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "yppasswd.h"
+
+int make_passwd __P((yppasswd *));
+
+int *
+yppasswdproc_update_1_svc(argp, rqstp, transp)
+	yppasswd *argp;
+	struct svc_req *rqstp;
+	SVCXPRT *transp;
+{
+	static int res;
+
+	bzero((char *)&res, sizeof(res));
+	res = make_passwd(argp);
+
+	if (!svc_sendreply(transp, xdr_int, (char *)&res))
+		svcerr_systemerr(transp);
+
+	if (!svc_freeargs(transp, xdr_yppasswd, (caddr_t) argp)) {
+		(void)fprintf(stderr, "unable to free arguments\n");
+		exit(1);
+	}
+	return ((void *)&res);
+}
diff --git a/rpcinfo.tproj/Makefile b/rpcinfo.tproj/Makefile
new file mode 100644
index 0000000..808dfe4
--- /dev/null
+++ b/rpcinfo.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rpcinfo
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = rpcinfo.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
+            h.template
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rpcinfo.tproj/Makefile.postamble b/rpcinfo.tproj/Makefile.postamble
new file mode 100644
index 0000000..7ede358
--- /dev/null
+++ b/rpcinfo.tproj/Makefile.postamble
@@ -0,0 +1,111 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
diff --git a/rpcinfo.tproj/Makefile.preamble b/rpcinfo.tproj/Makefile.preamble
new file mode 100644
index 0000000..30aa1b5
--- /dev/null
+++ b/rpcinfo.tproj/Makefile.preamble
@@ -0,0 +1,119 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+INSTALLDIR = /usr/sbin
diff --git a/rpcinfo.tproj/PB.project b/rpcinfo.tproj/PB.project
new file mode 100644
index 0000000..00a575f
--- /dev/null
+++ b/rpcinfo.tproj/PB.project
@@ -0,0 +1,45 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        LIBRARYSEARCH = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (rpcinfo.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, m.template, h.template); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_MAINNIB = rpcinfo; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_MAINNIB = rpcinfo; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rpcinfo; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_MAINNIB = rpcinfo; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rpcinfo.tproj/h.template b/rpcinfo.tproj/h.template
new file mode 100644
index 0000000..5dcbc5d
--- /dev/null
+++ b/rpcinfo.tproj/h.template
@@ -0,0 +1,9 @@
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+@interface $FILENAMESANSEXTENSION$ : Object
+{
+
+}
+
+@end
diff --git a/rpcinfo.tproj/m.template b/rpcinfo.tproj/m.template
new file mode 100644
index 0000000..1216fe5
--- /dev/null
+++ b/rpcinfo.tproj/m.template
@@ -0,0 +1,18 @@
+$$ Lines starting with $$ are not inserted into newly created files
+$$ The following substitutions are made:
+$$
+$$ $FILENAME$                e.g. foo.m
+$$ $FILENAMESANSEXTENSION$   e.g. foo
+$$ $DIRECTORY$               e.g. /tmp/MyNewApp
+$$ $PROJECTNAME$             e.g. MyNewApp
+$$ $SUBPROJECTNAME$          e.g. TheGoodPart.subproj
+$$ $USERNAME$                e.g. mwagner
+$$ $DATE$                    e.g. Jan-1-1994
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+#import "$FILENAMESANSEXTENSION$.h"
+
+@implementation $FILENAMESANSEXTENSION$
+
+@end
diff --git a/rpcinfo.tproj/rpcinfo.c b/rpcinfo.tproj/rpcinfo.c
new file mode 100644
index 0000000..3315bda
--- /dev/null
+++ b/rpcinfo.tproj/rpcinfo.c
@@ -0,0 +1,690 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* @(#)rpcinfo.c	2.2 88/08/11 4.0 RPCSRC */
+#ifndef lint
+static	char sccsid[] = "@(#)rpcinfo.c 1.22 87/08/12 SMI";
+#endif
+
+/*
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+/*
+ * rpcinfo: ping a particular rpc program
+ *     or dump the portmapper
+ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#include <rpc/rpc.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <signal.h>
+#include <ctype.h>
+
+#define MAXHOSTLEN 256
+
+#define	MIN_VERS	((u_long) 0)
+#define	MAX_VERS	((u_long) 4294967295L)
+
+static void	udpping(/*u_short portflag, int argc, char **argv*/);
+static void	tcpping(/*u_short portflag, int argc, char **argv*/);
+static int	pstatus(/*CLIENT *client, u_long prognum, u_long vers*/);
+static void	pmapdump(/*int argc, char **argv*/);
+static bool_t	reply_proc(/*void *res, struct sockaddr_in *who*/);
+static void	brdcst(/*int argc, char **argv*/);
+static void	deletereg(/* int argc, char **argv */) ;
+static void	usage(/*void*/);
+static u_long	getprognum(/*char *arg*/);
+static u_long	getvers(/*char *arg*/);
+static void	get_inet_address(/*struct sockaddr_in *addr, char *host*/);
+extern u_long inet_addr();  /* in 4.2BSD, arpa/inet.h called that a in_addr */
+extern char *inet_ntoa();
+
+/*
+ * Functions to be performed.
+ */
+#define	NONE		0	/* no function */
+#define	PMAPDUMP	1	/* dump portmapper registrations */
+#define	TCPPING		2	/* ping TCP service */
+#define	UDPPING		3	/* ping UDP service */
+#define	BRDCST		4	/* ping broadcast UDP service */
+#define DELETES		5	/* delete registration for the service */
+
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	register int c;
+	extern char *optarg;
+	extern int optind;
+	int errflg;
+	int function;
+	u_short portnum;
+
+	function = NONE;
+	portnum = 0;
+	errflg = 0;
+	while ((c = getopt(argc, argv, "ptubdn:")) != EOF) {
+		switch (c) {
+
+		case 'p':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = PMAPDUMP;
+			break;
+
+		case 't':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = TCPPING;
+			break;
+
+		case 'u':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = UDPPING;
+			break;
+
+		case 'b':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = BRDCST;
+			break;
+
+		case 'n':
+			portnum = (u_short) atoi(optarg);   /* hope we don't get bogus # */
+			break;
+
+		case 'd':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = DELETES;
+			break;
+
+		case '?':
+			errflg = 1;
+		}
+	}
+
+	if (errflg || function == NONE) {
+		usage();
+		return (1);
+	}
+
+	switch (function) {
+
+	case PMAPDUMP:
+		if (portnum != 0) {
+			usage();
+			return (1);
+		}
+		pmapdump(argc - optind, argv + optind);
+		break;
+
+	case UDPPING:
+		udpping(portnum, argc - optind, argv + optind);
+		break;
+
+	case TCPPING:
+		tcpping(portnum, argc - optind, argv + optind);
+		break;
+
+	case BRDCST:
+		if (portnum != 0) {
+			usage();
+			return (1);
+		}
+		brdcst(argc - optind, argv + optind);
+		break;
+
+	case DELETES:
+		deletereg(argc - optind, argv + optind);
+		break;
+	}
+
+	return (0);
+}
+		
+static void
+udpping(portnum, argc, argv)
+	u_short portnum;
+	int argc;
+	char **argv;
+{
+	struct timeval to;
+	struct sockaddr_in addr;
+	enum clnt_stat rpc_stat;
+	CLIENT *client;
+	u_long prognum, vers, minvers, maxvers;
+	int sock = RPC_ANYSOCK;
+	struct rpc_err rpcerr;
+	int failure;
+    
+	if (argc < 2 || argc > 3) {
+		usage();
+		exit(1);
+	}
+	prognum = getprognum(argv[1]);
+	get_inet_address(&addr, argv[0]);
+	/* Open the socket here so it will survive calls to clnt_destroy */
+	sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (sock < 0) {
+		perror("rpcinfo: socket");
+		exit(1);
+	}
+	failure = 0;
+	if (argc == 2) {
+		/*
+		 * A call to version 0 should fail with a program/version
+		 * mismatch, and give us the range of versions supported.
+		 */
+		addr.sin_port = htons(portnum);
+		to.tv_sec = 5;
+		to.tv_usec = 0;
+		if ((client = clntudp_create(&addr, prognum, (u_long)0,
+		    to, &sock)) == NULL) {
+			clnt_pcreateerror("rpcinfo");
+			printf("program %lu is not available\n",
+			    prognum);
+			exit(1);
+		}
+		to.tv_sec = 10;
+		to.tv_usec = 0;
+		rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
+		    xdr_void, (char *)NULL, to);
+		if (rpc_stat == RPC_PROGVERSMISMATCH) {
+			clnt_geterr(client, &rpcerr);
+			minvers = rpcerr.re_vers.low;
+			maxvers = rpcerr.re_vers.high;
+		} else if (rpc_stat == RPC_SUCCESS) {
+			/*
+			 * Oh dear, it DOES support version 0.
+			 * Let's try version MAX_VERS.
+			 */
+			addr.sin_port = htons(portnum);
+			to.tv_sec = 5;
+			to.tv_usec = 0;
+			if ((client = clntudp_create(&addr, prognum, MAX_VERS,
+			    to, &sock)) == NULL) {
+				clnt_pcreateerror("rpcinfo");
+				printf("program %lu version %lu is not available\n",
+				    prognum, MAX_VERS);
+				exit(1);
+			}
+			to.tv_sec = 10;
+			to.tv_usec = 0;
+			rpc_stat = clnt_call(client, NULLPROC, xdr_void,
+			    (char *)NULL, xdr_void, (char *)NULL, to);
+			if (rpc_stat == RPC_PROGVERSMISMATCH) {
+				clnt_geterr(client, &rpcerr);
+				minvers = rpcerr.re_vers.low;
+				maxvers = rpcerr.re_vers.high;
+			} else if (rpc_stat == RPC_SUCCESS) {
+				/*
+				 * It also supports version MAX_VERS.
+				 * Looks like we have a wise guy.
+				 * OK, we give them information on all
+				 * 4 billion versions they support...
+				 */
+				minvers = 0;
+				maxvers = MAX_VERS;
+			} else {
+				(void) pstatus(client, prognum, MAX_VERS);
+				exit(1);
+			}
+		} else {
+			(void) pstatus(client, prognum, (u_long)0);
+			exit(1);
+		}
+		clnt_destroy(client);
+		for (vers = minvers; vers <= maxvers; vers++) {
+			addr.sin_port = htons(portnum);
+			to.tv_sec = 5;
+			to.tv_usec = 0;
+			if ((client = clntudp_create(&addr, prognum, vers,
+			    to, &sock)) == NULL) {
+				clnt_pcreateerror("rpcinfo");
+				printf("program %lu version %lu is not available\n",
+				    prognum, vers);
+				exit(1);
+			}
+			to.tv_sec = 10;
+			to.tv_usec = 0;
+			rpc_stat = clnt_call(client, NULLPROC, xdr_void,
+			    (char *)NULL, xdr_void, (char *)NULL, to);
+			if (pstatus(client, prognum, vers) < 0)
+				failure = 1;
+			clnt_destroy(client);
+		}
+	}
+	else {
+		vers = getvers(argv[2]);
+		addr.sin_port = htons(portnum);
+		to.tv_sec = 5;
+		to.tv_usec = 0;
+		if ((client = clntudp_create(&addr, prognum, vers,
+		    to, &sock)) == NULL) {
+			clnt_pcreateerror("rpcinfo");
+			printf("program %lu version %lu is not available\n",
+			    prognum, vers);
+			exit(1);
+		}
+		to.tv_sec = 10;
+		to.tv_usec = 0;
+		rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
+		    xdr_void, (char *)NULL, to);
+		if (pstatus(client, prognum, vers) < 0)
+			failure = 1;
+	}
+	(void) close(sock); /* Close it up again */
+	if (failure)
+		exit(1);
+}
+
+static void
+tcpping(portnum, argc, argv)
+	u_short portnum;
+	int argc;
+	char **argv;
+{
+	struct timeval to;
+	struct sockaddr_in addr;
+	enum clnt_stat rpc_stat;
+	CLIENT *client;
+	u_long prognum, vers, minvers, maxvers;
+	int sock = RPC_ANYSOCK;
+	struct rpc_err rpcerr;
+	int failure;
+
+	if (argc < 2 || argc > 3) {
+		usage();
+		exit(1);
+	}
+	prognum = getprognum(argv[1]);
+	get_inet_address(&addr, argv[0]);
+	failure = 0;
+	if (argc == 2) {
+		/*
+		 * A call to version 0 should fail with a program/version
+		 * mismatch, and give us the range of versions supported.
+		 */
+		addr.sin_port = htons(portnum);
+		if ((client = clnttcp_create(&addr, prognum, MIN_VERS,
+		    &sock, 0, 0)) == NULL) {
+			clnt_pcreateerror("rpcinfo");
+			printf("program %lu is not available\n",
+			    prognum);
+			exit(1);
+		}
+		to.tv_sec = 10;
+		to.tv_usec = 0;
+		rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
+		    xdr_void, (char *)NULL, to);
+		if (rpc_stat == RPC_PROGVERSMISMATCH) {
+			clnt_geterr(client, &rpcerr);
+			minvers = rpcerr.re_vers.low;
+			maxvers = rpcerr.re_vers.high;
+		} else if (rpc_stat == RPC_SUCCESS) {
+			/*
+			 * Oh dear, it DOES support version 0.
+			 * Let's try version MAX_VERS.
+			 */
+			addr.sin_port = htons(portnum);
+			if ((client = clnttcp_create(&addr, prognum, MAX_VERS,
+			    &sock, 0, 0)) == NULL) {
+				clnt_pcreateerror("rpcinfo");
+				printf("program %lu version %lu is not available\n",
+				    prognum, MAX_VERS);
+				exit(1);
+			}
+			to.tv_sec = 10;
+			to.tv_usec = 0;
+			rpc_stat = clnt_call(client, NULLPROC, xdr_void,
+			    (char *)NULL, xdr_void, (char *)NULL, to);
+			if (rpc_stat == RPC_PROGVERSMISMATCH) {
+				clnt_geterr(client, &rpcerr);
+				minvers = rpcerr.re_vers.low;
+				maxvers = rpcerr.re_vers.high;
+			} else if (rpc_stat == RPC_SUCCESS) {
+				/*
+				 * It also supports version MAX_VERS.
+				 * Looks like we have a wise guy.
+				 * OK, we give them information on all
+				 * 4 billion versions they support...
+				 */
+				minvers = 0;
+				maxvers = MAX_VERS;
+			} else {
+				(void) pstatus(client, prognum, MAX_VERS);
+				exit(1);
+			}
+		} else {
+			(void) pstatus(client, prognum, MIN_VERS);
+			exit(1);
+		}
+		clnt_destroy(client);
+		(void) close(sock);
+		sock = RPC_ANYSOCK; /* Re-initialize it for later */
+		for (vers = minvers; vers <= maxvers; vers++) {
+			addr.sin_port = htons(portnum);
+			if ((client = clnttcp_create(&addr, prognum, vers,
+			    &sock, 0, 0)) == NULL) {
+				clnt_pcreateerror("rpcinfo");
+				printf("program %lu version %lu is not available\n",
+				    prognum, vers);
+				exit(1);
+			}
+			to.tv_usec = 0;
+			to.tv_sec = 10;
+			rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
+			    xdr_void, (char *)NULL, to);
+			if (pstatus(client, prognum, vers) < 0)
+				failure = 1;
+			clnt_destroy(client);
+			(void) close(sock);
+			sock = RPC_ANYSOCK;
+		}
+	}
+	else {
+		vers = getvers(argv[2]);
+		addr.sin_port = htons(portnum);
+		if ((client = clnttcp_create(&addr, prognum, vers, &sock,
+		    0, 0)) == NULL) {
+			clnt_pcreateerror("rpcinfo");
+			printf("program %lu version %lu is not available\n",
+			    prognum, vers);
+			exit(1);
+		}
+		to.tv_usec = 0;
+		to.tv_sec = 10;
+		rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
+		    xdr_void, (char *)NULL, to);
+		if (pstatus(client, prognum, vers) < 0)
+			failure = 1;
+	}
+	if (failure)
+		exit(1);
+}
+
+/*
+ * This routine should take a pointer to an "rpc_err" structure, rather than
+ * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
+ * a CLIENT structure rather than a pointer to an "rpc_err" structure.
+ * As such, we have to keep the CLIENT structure around in order to print
+ * a good error message.
+ */
+static int
+pstatus(client, prognum, vers)
+	register CLIENT *client;
+	u_long prognum;
+	u_long vers;
+{
+	struct rpc_err rpcerr;
+
+	clnt_geterr(client, &rpcerr);
+	if (rpcerr.re_status != RPC_SUCCESS) {
+		clnt_perror(client, "rpcinfo");
+		printf("program %lu version %lu is not available\n",
+		    prognum, vers);
+		return (-1);
+	} else {
+		printf("program %lu version %lu ready and waiting\n",
+		    prognum, vers);
+		return (0);
+	}
+}
+
+static void
+pmapdump(argc, argv)
+	int argc;
+	char **argv;
+{
+	struct sockaddr_in server_addr;
+	register struct hostent *hp;
+	struct pmaplist *head = NULL;
+	int socket = RPC_ANYSOCK;
+	struct timeval minutetimeout;
+	register CLIENT *client;
+	struct rpcent *rpc;
+	
+	if (argc > 1) {
+		usage();
+		exit(1);
+	}
+	if (argc == 1)
+		get_inet_address(&server_addr, argv[0]);
+	else {
+		bzero((char *)&server_addr, sizeof server_addr);
+		server_addr.sin_family = AF_INET;
+		if ((hp = gethostbyname("localhost")) != NULL)
+			bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
+			    hp->h_length);
+		else
+			server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
+	}
+	minutetimeout.tv_sec = 60;
+	minutetimeout.tv_usec = 0;
+	server_addr.sin_port = htons(PMAPPORT);
+	if ((client = clnttcp_create(&server_addr, PMAPPROG,
+	    PMAPVERS, &socket, 50, 500)) == NULL) {
+		clnt_pcreateerror("rpcinfo: can't contact portmapper");
+		exit(1);
+	}
+	if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
+	    xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
+		fprintf(stderr, "rpcinfo: can't contact portmapper: ");
+		clnt_perror(client, "rpcinfo");
+		exit(1);
+	}
+	if (head == NULL) {
+		printf("No remote programs registered.\n");
+	} else {
+		printf("   program vers proto   port\n");
+		for (; head != NULL; head = head->pml_next) {
+			printf("%10ld%5ld",
+			    head->pml_map.pm_prog,
+			    head->pml_map.pm_vers);
+			if (head->pml_map.pm_prot == IPPROTO_UDP)
+				printf("%6s",  "udp");
+			else if (head->pml_map.pm_prot == IPPROTO_TCP)
+				printf("%6s", "tcp");
+			else
+				printf("%6ld",  head->pml_map.pm_prot);
+			printf("%7ld",  head->pml_map.pm_port);
+			rpc = getrpcbynumber(head->pml_map.pm_prog);
+			if (rpc)
+				printf("  %s\n", rpc->r_name);
+			else
+				printf("\n");
+		}
+	}
+}
+
+/* 
+ * reply_proc collects replies from the broadcast. 
+ * to get a unique list of responses the output of rpcinfo should
+ * be piped through sort(1) and then uniq(1).
+ */
+
+/*ARGSUSED*/
+static bool_t
+reply_proc(res, who)
+	void *res;		/* Nothing comes back */
+	struct sockaddr_in *who; /* Who sent us the reply */
+{
+	register struct hostent *hp;
+
+	hp = gethostbyaddr((char *) &who->sin_addr, sizeof who->sin_addr,
+	    AF_INET);
+	printf("%s %s\n", inet_ntoa(who->sin_addr),
+	    (hp == NULL) ? "(unknown)" : hp->h_name);
+	return(FALSE);
+}
+
+static void
+brdcst(argc, argv)
+	int argc;
+	char **argv;
+{
+	enum clnt_stat rpc_stat;
+	u_long prognum, vers;
+
+	if (argc != 2) {
+		usage();
+		exit(1);
+	}
+	prognum = getprognum(argv[0]);
+	vers = getvers(argv[1]);
+	rpc_stat = clnt_broadcast(prognum, vers, NULLPROC, xdr_void,
+	    (char *)NULL, xdr_void, (char *)NULL, reply_proc);
+	if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) {
+		fprintf(stderr, "rpcinfo: broadcast failed: %s\n",
+		    clnt_sperrno(rpc_stat));
+		exit(1);
+	}
+	exit(0);
+}
+
+static void
+deletereg(argc, argv)
+	int argc;
+	char **argv;
+{	u_long prog_num, version_num ;
+
+	if (argc != 2) {
+		usage() ;
+		exit(1) ;
+	}
+	if (getuid()) { /* This command allowed only to root */
+		fprintf(stderr, "Sorry. You are not root\n") ;
+		exit(1) ;
+	}
+	prog_num = getprognum(argv[0]);
+	version_num = getvers(argv[1]);
+	if ((pmap_unset(prog_num, version_num)) == 0) {
+		fprintf(stderr, "rpcinfo: Could not delete registration for prog %s version %s\n",
+			argv[0], argv[1]) ;
+		exit(1) ;
+	}
+}
+
+static void
+usage()
+{
+	fprintf(stderr, "Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n");
+	fprintf(stderr, "       rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n");
+	fprintf(stderr, "       rpcinfo -p [ host ]\n");
+	fprintf(stderr, "       rpcinfo -b prognum versnum\n");
+	fprintf(stderr, "       rpcinfo -d prognum versnum\n") ;
+}
+
+static u_long
+getprognum(arg)
+	char *arg;
+{
+	register struct rpcent *rpc;
+	register u_long prognum;
+
+	if (isalpha(*arg)) {
+		rpc = getrpcbyname(arg);
+		if (rpc == NULL) {
+			fprintf(stderr, "rpcinfo: %s is unknown service\n",
+			    arg);
+			exit(1);
+		}
+		prognum = rpc->r_number;
+	} else {
+		prognum = (u_long) atoi(arg);
+	}
+
+	return (prognum);
+}
+
+static u_long
+getvers(arg)
+	char *arg;
+{
+	register u_long vers;
+
+	vers = (int) atoi(arg);
+	return (vers);
+}
+
+static void
+get_inet_address(addr, host)
+	struct sockaddr_in *addr;
+	char *host;
+{
+	register struct hostent *hp;
+
+	bzero((char *)addr, sizeof *addr);
+	addr->sin_addr.s_addr = (u_long) inet_addr(host);
+	if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0) {
+		if ((hp = gethostbyname(host)) == NULL) {
+			fprintf(stderr, "rpcinfo: %s is unknown host\n", host);
+			exit(1);
+		}
+		bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length);
+	}
+	addr->sin_family = AF_INET;
+}
diff --git a/rsh.tproj/Makefile b/rsh.tproj/Makefile
new file mode 100644
index 0000000..c387527
--- /dev/null
+++ b/rsh.tproj/Makefile
@@ -0,0 +1,50 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rsh
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = pathnames.h
+
+CFILES = rsh.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble rsh.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rsh.tproj/Makefile.postamble b/rsh.tproj/Makefile.postamble
new file mode 100644
index 0000000..625a231
--- /dev/null
+++ b/rsh.tproj/Makefile.postamble
@@ -0,0 +1,5 @@
+VPATH += :../rlogin.tproj
+INSTALL_PERMISSIONS = 4555
+
+after_install::
+	$(CHFLAGS) schg $(DSTROOT)$(INSTALLDIR)/$(NAME)
diff --git a/rsh.tproj/Makefile.preamble b/rsh.tproj/Makefile.preamble
new file mode 100644
index 0000000..87a4321
--- /dev/null
+++ b/rsh.tproj/Makefile.preamble
@@ -0,0 +1,4 @@
+RLOGIN_CFILES = krcmd.c des_rw.c
+OTHER_OFILES = $(RLOGIN_CFILES:.c=.o)
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/rsh.tproj/PB.project b/rsh.tproj/PB.project
new file mode 100644
index 0000000..33594fc
--- /dev/null
+++ b/rsh.tproj/PB.project
@@ -0,0 +1,30 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        CLASSES = (); 
+        FRAMEWORKS = (); 
+        H_FILES = (pathnames.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (rsh.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, rsh.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = rsh; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_MAINNIB = rsh; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rsh; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_MAINNIB = rsh; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rsh.tproj/pathnames.h b/rsh.tproj/pathnames.h
new file mode 100644
index 0000000..812b0d0
--- /dev/null
+++ b/rsh.tproj/pathnames.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: @(#)pathnames.h	8.1 (Berkeley) 6/6/93
+ */
+
+#define	_PATH_RLOGIN	"/usr/bin/rlogin"
diff --git a/rsh.tproj/rsh.1 b/rsh.tproj/rsh.1
new file mode 100644
index 0000000..78ec2f1
--- /dev/null
+++ b/rsh.tproj/rsh.1
@@ -0,0 +1,187 @@
+.\" Copyright (c) 1983, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)rsh.1	8.2 (Berkeley) 4/29/95
+.\"
+.Dd April 29, 1995
+.Dt RSH 1
+.Os BSD 4.2
+.Sh NAME
+.Nm rsh
+.Nd remote shell
+.Sh SYNOPSIS
+.Nm rsh
+.Op Fl Kdnx
+.Op Fl k Ar realm
+.Op Fl l Ar username
+.Ar host
+.Nm rsh
+.Op Fl Kdnx
+.Op Fl k Ar realm
+.Ar username@host
+.Op command
+.Sh DESCRIPTION
+.Nm Rsh
+executes
+.Ar command
+on
+.Ar host  .
+.Pp
+.Nm Rsh
+copies its standard input to the remote command, the standard
+output of the remote command to its standard output, and the
+standard error of the remote command to its standard error.
+Interrupt, quit and terminate signals are propagated to the remote
+command;
+.Nm rsh
+normally terminates when the remote command does.
+The options are as follows:
+.Bl -tag -width flag
+.It Fl K
+The
+.Fl K
+option turns off all Kerberos authentication.
+.It Fl d
+The
+.Fl d
+option turns on socket debugging (using
+.Xr setsockopt  2  )
+on the
+.Tn TCP
+sockets used for communication with the remote host.
+.It Fl k
+The
+.Fl k
+option causes
+.Nm rsh
+to obtain tickets for the remote host in
+.Ar realm
+instead of the remote host's realm as determined by
+.Xr krb_realmofhost  3  .
+.It Fl l
+By default, the remote username is the same as the local username.
+The
+.Fl l
+option or the
+.Pa username@host
+format allow the remote name to be specified.
+Kerberos authentication is used, and authorization is determined
+as in
+.Xr rlogin  1  .
+.It Fl n
+The
+.Fl n
+option redirects input from the special device
+.Pa /dev/null
+(see the
+.Sx BUGS
+section of this manual page).
+.It Fl x
+The
+.Fl x
+option turns on
+.Tn DES
+encryption for all data exchange.
+This may introduce a significant delay in response time.
+.El
+.Pp
+If no
+.Ar command
+is specified, you will be logged in on the remote host using
+.Xr rlogin  1  .
+.Pp
+Shell metacharacters which are not quoted are interpreted on local machine,
+while quoted metacharacters are interpreted on the remote machine.
+For example, the command
+.Pp
+.Dl rsh otherhost cat remotefile >> localfile
+.Pp
+appends the remote file
+.Ar remotefile
+to the local file
+.Ar localfile ,
+while
+.Pp
+.Dl rsh otherhost cat remotefile \&">>\&" other_remotefile
+.Pp
+appends
+.Ar remotefile
+to
+.Ar other_remotefile .
+.\" .Pp
+.\" Many sites specify a large number of host names as commands in the
+.\" directory /usr/hosts.
+.\" If this directory is included in your search path, you can use the
+.\" shorthand ``host command'' for the longer form ``rsh host command''.
+.Sh FILES
+.Bl -tag -width /etc/hosts -compact
+.It Pa /etc/hosts
+.El
+.Sh SEE ALSO
+.Xr rlogin 1 ,
+.Xr kerberos 3 ,
+.Xr krb_sendauth 3 ,
+.Xr krb_realmofhost 3
+.Sh HISTORY
+The
+.Nm rsh
+command appeared in
+.Bx 4.2 .
+.Sh BUGS
+If you are using
+.Xr csh  1
+and put a
+.Nm rsh
+in the background without redirecting its input away from the terminal,
+it will block even if no reads are posted by the remote command.
+If no input is desired you should redirect the input of
+.Nm rsh
+to
+.Pa /dev/null
+using the
+.Fl n
+option.
+.Pp
+You cannot run an interactive command
+(like
+.Xr rogue  6
+or
+.Xr vi  1  )
+using
+.Nm rsh  ;
+use
+.Xr rlogin  1
+instead.
+.Pp
+Stop signals stop the local
+.Nm rsh
+process only; this is arguably wrong, but currently hard to fix for reasons
+too complicated to explain here.
diff --git a/rsh.tproj/rsh.c b/rsh.tproj/rsh.c
new file mode 100644
index 0000000..9474164
--- /dev/null
+++ b/rsh.tproj/rsh.c
@@ -0,0 +1,504 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1983, 1990, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/*
+ * $Source: /cvs/Darwin/Commands/NeXT/network_cmds/rsh.tproj/rsh.c,v $
+ * $Header: /cvs/Darwin/Commands/NeXT/network_cmds/rsh.tproj/rsh.c,v 1.1.1.1 1999/05/02 03:58:17 wsanchez Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <err.h>
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <varargs.h>
+
+#include "pathnames.h"
+
+#ifdef KERBEROS
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+
+CREDENTIALS cred;
+Key_schedule schedule;
+int use_kerberos = 1, doencrypt;
+char dst_realm_buf[REALM_SZ], *dest_realm;
+extern char *krb_realmofhost();
+#endif
+
+/*
+ * rsh - remote shell
+ */
+int	rfd2;
+
+char   *copyargs __P((char **));
+void	sendsig __P((int));
+void	talk __P((int, long, pid_t, int));
+void	usage __P((void));
+void	warning __P(());
+
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	struct passwd *pw;
+	struct servent *sp;
+	long omask;
+	int argoff, asrsh, ch, dflag, nflag, one, rem;
+	pid_t pid;
+	uid_t uid;
+	char *args, *host, *p, *user;
+
+	argoff = asrsh = dflag = nflag = 0;
+	one = 1;
+	host = user = NULL;
+
+	/* if called as something other than "rsh", use it as the host name */
+	if (p = strrchr(argv[0], '/'))
+		++p;
+	else
+		p = argv[0];
+	if (strcmp(p, "rsh"))
+		host = p;
+	else
+		asrsh = 1;
+
+	/* handle "rsh host flags" */
+	if (!host && argc > 2 && argv[1][0] != '-') {
+		host = argv[1];
+		argoff = 1;
+	}
+
+#ifdef KERBEROS
+#ifdef CRYPT
+#define	OPTIONS	"8KLdek:l:nwx"
+#else
+#define	OPTIONS	"8KLdek:l:nw"
+#endif
+#else
+#define	OPTIONS	"8KLdel:nw"
+#endif
+	while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != EOF)
+		switch(ch) {
+		case 'K':
+#ifdef KERBEROS
+			use_kerberos = 0;
+#endif
+			break;
+		case 'L':	/* -8Lew are ignored to allow rlogin aliases */
+		case 'e':
+		case 'w':
+		case '8':
+			break;
+		case 'd':
+			dflag = 1;
+			break;
+		case 'l':
+			user = optarg;
+			break;
+#ifdef KERBEROS
+		case 'k':
+			dest_realm = dst_realm_buf;
+			strncpy(dest_realm, optarg, REALM_SZ);
+			break;
+#endif
+		case 'n':
+			nflag = 1;
+			break;
+#ifdef KERBEROS
+#ifdef CRYPT
+		case 'x':
+			doencrypt = 1;
+			des_set_key(cred.session, schedule);
+			break;
+#endif
+#endif
+		case '?':
+		default:
+			usage();
+		}
+	optind += argoff;
+
+	/* if haven't gotten a host yet, do so */
+	if (!host && !(host = argv[optind++]))
+		usage();
+
+	/* if no further arguments, must have been called as rlogin. */
+	if (!argv[optind]) {
+		if (asrsh)
+			*argv = "rlogin";
+		execv(_PATH_RLOGIN, argv);
+		err(1, "can't exec %s", _PATH_RLOGIN);
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (!(pw = getpwuid(uid = getuid())))
+		errx(1, "unknown user id");
+	/* Accept user1@host format, though "-l user2" overrides user1 */
+	p = strchr(host, '@');
+	if (p) {
+		*p = '\0';
+		if (!user && p > host)
+			user = host;
+		host = p + 1;
+		if (*host == '\0')
+			usage();
+	}
+	if (!user)
+		user = pw->pw_name;
+
+#ifdef KERBEROS
+#ifdef CRYPT
+	/* -x turns off -n */
+	if (doencrypt)
+		nflag = 0;
+#endif
+#endif
+
+	args = copyargs(argv);
+
+	sp = NULL;
+#ifdef KERBEROS
+	if (use_kerberos) {
+		sp = getservbyname((doencrypt ? "ekshell" : "kshell"), "tcp");
+		if (sp == NULL) {
+			use_kerberos = 0;
+			warning("can't get entry for %s/tcp service",
+			    doencrypt ? "ekshell" : "kshell");
+		}
+	}
+#endif
+	if (sp == NULL)
+		sp = getservbyname("shell", "tcp");
+	if (sp == NULL)
+		errx(1, "shell/tcp: unknown service");
+
+#ifdef KERBEROS
+try_connect:
+	if (use_kerberos) {
+		struct hostent *hp;
+
+		/* fully qualify hostname (needed for krb_realmofhost) */
+		hp = gethostbyname(host);
+		if (hp != NULL && !(host = strdup(hp->h_name)))
+			err(1, NULL);
+
+		rem = KSUCCESS;
+		errno = 0;
+		if (dest_realm == NULL)
+			dest_realm = krb_realmofhost(host);
+
+#ifdef CRYPT
+		if (doencrypt)
+			rem = krcmd_mutual(&host, sp->s_port, user, args,
+			    &rfd2, dest_realm, &cred, schedule);
+		else
+#endif
+			rem = krcmd(&host, sp->s_port, user, args, &rfd2,
+			    dest_realm);
+		if (rem < 0) {
+			use_kerberos = 0;
+			sp = getservbyname("shell", "tcp");
+			if (sp == NULL)
+				errx(1, "shell/tcp: unknown service");
+			if (errno == ECONNREFUSED)
+				warning("remote host doesn't support Kerberos");
+			if (errno == ENOENT)
+				warning("can't provide Kerberos auth data");
+			goto try_connect;
+		}
+	} else {
+		if (doencrypt)
+			errx(1, "the -x flag requires Kerberos authentication");
+		rem = rcmd(&host, sp->s_port, pw->pw_name, user, args, &rfd2);
+	}
+#else
+	rem = rcmd(&host, sp->s_port, pw->pw_name, user, args, &rfd2);
+#endif
+
+	if (rem < 0)
+		exit(1);
+
+	if (rfd2 < 0)
+		errx(1, "can't establish stderr");
+	if (dflag) {
+		if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one,
+		    sizeof(one)) < 0)
+			warn("setsockopt");
+		if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one,
+		    sizeof(one)) < 0)
+			warn("setsockopt");
+	}
+
+	(void)setuid(uid);
+	omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTERM));
+	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+		(void)signal(SIGINT, sendsig);
+	if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
+		(void)signal(SIGQUIT, sendsig);
+	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
+		(void)signal(SIGTERM, sendsig);
+
+	if (!nflag) {
+		pid = fork();
+		if (pid < 0)
+			err(1, "fork");
+	}
+
+#ifdef KERBEROS
+#ifdef CRYPT
+	if (!doencrypt)
+#endif
+#endif
+	{
+		(void)ioctl(rfd2, FIONBIO, &one);
+		(void)ioctl(rem, FIONBIO, &one);
+	}
+
+	talk(nflag, omask, pid, rem);
+
+	if (!nflag)
+		(void)kill(pid, SIGKILL);
+	exit(0);
+}
+
+void
+talk(nflag, omask, pid, rem)
+	int nflag;
+	long omask;
+	pid_t pid;
+	int rem;
+{
+	int cc, wc;
+	fd_set readfrom, ready, rembits;
+	char *bp, buf[BUFSIZ];
+
+	if (!nflag && pid == 0) {
+		(void)close(rfd2);
+
+reread:		errno = 0;
+		if ((cc = read(0, buf, sizeof buf)) <= 0)
+			goto done;
+		bp = buf;
+
+rewrite:	
+		FD_ZERO(&rembits);
+		FD_SET(rem, &rembits);
+		if (select(16, 0, &rembits, 0, 0) < 0) {
+			if (errno != EINTR)
+				err(1, "select");
+			goto rewrite;
+		}
+		if (!FD_ISSET(rem, &rembits))
+			goto rewrite;
+#ifdef KERBEROS
+#ifdef CRYPT
+		if (doencrypt)
+			wc = des_write(rem, bp, cc);
+		else
+#endif
+#endif
+			wc = write(rem, bp, cc);
+		if (wc < 0) {
+			if (errno == EWOULDBLOCK)
+				goto rewrite;
+			goto done;
+		}
+		bp += wc;
+		cc -= wc;
+		if (cc == 0)
+			goto reread;
+		goto rewrite;
+done:
+		(void)shutdown(rem, 1);
+		exit(0);
+	}
+
+	(void)sigsetmask(omask);
+	FD_ZERO(&readfrom);
+	FD_SET(rfd2, &readfrom);
+	FD_SET(rem, &readfrom);
+	do {
+		ready = readfrom;
+		if (select(16, &ready, 0, 0, 0) < 0) {
+			if (errno != EINTR)
+				err(1, "select");
+			continue;
+		}
+		if (FD_ISSET(rfd2, &ready)) {
+			errno = 0;
+#ifdef KERBEROS
+#ifdef CRYPT
+			if (doencrypt)
+				cc = des_read(rfd2, buf, sizeof buf);
+			else
+#endif
+#endif
+				cc = read(rfd2, buf, sizeof buf);
+			if (cc <= 0) {
+				if (errno != EWOULDBLOCK)
+					FD_CLR(rfd2, &readfrom);
+			} else
+				(void)write(2, buf, cc);
+		}
+		if (FD_ISSET(rem, &ready)) {
+			errno = 0;
+#ifdef KERBEROS
+#ifdef CRYPT
+			if (doencrypt)
+				cc = des_read(rem, buf, sizeof buf);
+			else
+#endif
+#endif
+				cc = read(rem, buf, sizeof buf);
+			if (cc <= 0) {
+				if (errno != EWOULDBLOCK)
+					FD_CLR(rem, &readfrom);
+			} else
+				(void)write(1, buf, cc);
+		}
+	} while (FD_ISSET(rfd2, &readfrom) || FD_ISSET(rem, &readfrom));
+}
+
+void
+sendsig(sig)
+	int sig;
+{
+	char signo;
+
+	signo = sig;
+#ifdef KERBEROS
+#ifdef CRYPT
+	if (doencrypt)
+		(void)des_write(rfd2, &signo, 1);
+	else
+#endif
+#endif
+		(void)write(rfd2, &signo, 1);
+}
+
+#ifdef KERBEROS
+/* VARARGS */
+void
+warning(va_alist)
+va_dcl
+{
+	va_list ap;
+	char *fmt;
+
+	(void)fprintf(stderr, "rsh: warning, using standard rsh: ");
+	va_start(ap);
+	fmt = va_arg(ap, char *);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	(void)fprintf(stderr, ".\n");
+}
+#endif
+
+char *
+copyargs(argv)
+	char **argv;
+{
+	int cc;
+	char **ap, *args, *p;
+
+	cc = 0;
+	for (ap = argv; *ap; ++ap)
+		cc += strlen(*ap) + 1;
+	if (!(args = malloc((u_int)cc)))
+		err(1, NULL);
+	for (p = args, ap = argv; *ap; ++ap) {
+		(void)strcpy(p, *ap);
+		for (p = strcpy(p, *ap); *p; ++p);
+		if (ap[1])
+			*p++ = ' ';
+	}
+	return (args);
+}
+
+void
+usage()
+{
+
+	(void)fprintf(stderr,
+	    "usage: rsh [-nd%s]%s[-l login] [login@]host [command]\n",
+#ifdef KERBEROS
+#ifdef CRYPT
+	    "x", " [-k realm] ");
+#else
+	    "", " [-k realm] ");
+#endif
+#else
+	    "", " ");
+#endif
+	exit(1);
+}
diff --git a/rshd.tproj/Makefile b/rshd.tproj/Makefile
new file mode 100644
index 0000000..3ebcdb8
--- /dev/null
+++ b/rshd.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rshd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = rshd.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble rshd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rshd.tproj/Makefile.postamble b/rshd.tproj/Makefile.postamble
new file mode 100644
index 0000000..fd0e632
--- /dev/null
+++ b/rshd.tproj/Makefile.postamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
+VPATH += :../rlogin.tproj
+
diff --git a/rshd.tproj/Makefile.preamble b/rshd.tproj/Makefile.preamble
new file mode 100644
index 0000000..6301c77
--- /dev/null
+++ b/rshd.tproj/Makefile.preamble
@@ -0,0 +1,119 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS = 
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR = 
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+OTHER_OFILES = des_rw.o
+
+-include ../Makefile.include
diff --git a/rshd.tproj/PB.project b/rshd.tproj/PB.project
new file mode 100644
index 0000000..1252083
--- /dev/null
+++ b/rshd.tproj/PB.project
@@ -0,0 +1,42 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (rshd.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, rshd.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_DOCUMENTEXTENSIONS = (); 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rshd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rshd.tproj/rshd.8 b/rshd.tproj/rshd.8
new file mode 100644
index 0000000..82e1991
--- /dev/null
+++ b/rshd.tproj/rshd.8
@@ -0,0 +1,209 @@
+.\" Copyright (c) 1983, 1989, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)rshd.8	8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt RSHD 8
+.Os BSD 4.2
+.Sh NAME
+.Nm rshd
+.Nd remote shell server
+.Sh SYNOPSIS
+.Nm rshd
+.Op Fl alnL
+.Sh DESCRIPTION
+The
+.Nm rshd
+server
+is the server for the 
+.Xr rcmd 3
+routine and, consequently, for the
+.Xr rsh 1
+program.  The server provides remote execution facilities
+with authentication based on privileged port numbers from trusted hosts.
+.Pp
+The
+.Nm rshd
+server
+listens for service requests at the port indicated in
+the ``cmd'' service specification; see
+.Xr services 5 .
+When a service request is received the following protocol
+is initiated:
+.Bl -enum
+.It
+The server checks the client's source port.
+If the port is not in the range 512-1023, the server
+aborts the connection.
+.It
+The server reads characters from the socket up
+to a null (`\e0') byte.  The resultant string is
+interpreted as an
+.Tn ASCII
+number, base 10.
+.It
+If the number received in step 2 is non-zero,
+it is interpreted as the port number of a secondary
+stream to be used for the 
+.Em stderr .
+A second connection is then created to the specified
+port on the client's machine.  The source port of this
+second connection is also in the range 512-1023.
+.It
+The server checks the client's source address
+and requests the corresponding host name (see
+.Xr gethostbyaddr 3 ,
+.Xr hosts 5
+and
+.Xr named 8 ) .
+If the hostname cannot be determined,
+the dot-notation representation of the host address is used.
+If the hostname is in the same domain as the server (according to
+the last two components of the domain name),
+or if the
+.Fl a
+option is given,
+the addresses for the hostname are requested,
+verifying that the name and address correspond.
+If address verification fails, the connection is aborted
+with the message, ``Host address mismatch.''
+.It
+A null terminated user name of at most 16 characters
+is retrieved on the initial socket.  This user name
+is interpreted as the user identity on the
+.Em client Ns 's
+machine.
+.It
+A null terminated user name of at most 16 characters
+is retrieved on the initial socket.  This user name
+is interpreted as a user identity to use on the
+.Sy server Ns 's
+machine.
+.It
+A null terminated command to be passed to a
+shell is retrieved on the initial socket.  The length of
+the command is limited by the upper bound on the size of
+the system's argument list.  
+.It
+.Nm Rshd
+then validates the user using
+.Xr ruserok 3 ,
+which uses the file
+.Pa /etc/hosts.equiv
+and the
+.Pa .rhosts
+file found in the user's home directory.  The
+.Fl l
+option prevents
+.Xr ruserok 3
+from doing any validation based on the user's ``.rhosts'' file,
+unless the user is the superuser.
+.It
+If the file 
+.Pa /etc/nologin
+exists and the user is not the superuser,
+the connection is closed.
+.It
+A null byte is returned on the initial socket
+and the command line is passed to the normal login
+shell of the user.  The
+shell inherits the network connections established
+by
+.Nm rshd .
+.El
+.Pp
+Transport-level keepalive messages are enabled unless the
+.Fl n
+option is present.
+The use of keepalive messages allows sessions to be timed out
+if the client crashes or becomes unreachable.
+.Pp
+The
+.Fl L
+option causes all successful accesses to be logged to
+.Xr syslogd 8
+as
+.Li auth.info
+messages.
+.Sh DIAGNOSTICS
+Except for the last one listed below,
+all diagnostic messages
+are returned on the initial socket,
+after which any network connections are closed.
+An error is indicated by a leading byte with a value of
+1 (0 is returned in step 10 above upon successful completion
+of all the steps prior to the execution of the login shell).
+.Bl -tag -width indent
+.It Sy Locuser too long.
+The name of the user on the client's machine is
+longer than 16 characters.
+.It Sy Ruser too long.
+The name of the user on the remote machine is
+longer than 16 characters.
+.It Sy Command too long  .
+The command line passed exceeds the size of the argument
+list (as configured into the system).
+.It Sy Login incorrect.
+No password file entry for the user name existed.
+.It Sy Remote directory.
+The 
+.Xr chdir
+command to the home directory failed.
+.It Sy Permission denied.
+The authentication procedure described above failed.
+.It Sy Can't make pipe.
+The pipe needed for the 
+.Em stderr ,
+wasn't created.
+.It Sy Can't fork; try again. 
+A
+.Xr fork
+by the server failed.
+.It Sy <shellname>: ...
+The user's login shell could not be started.  This message is returned
+on the connection associated with the
+.Em stderr ,
+and is not preceded by a flag byte.
+.El
+.Sh SEE ALSO
+.Xr rsh 1 ,
+.Xr rcmd 3 ,
+.Xr ruserok 3
+.Sh BUGS
+The authentication procedure used here assumes the integrity
+of each client machine and the connecting medium.  This is
+insecure, but is useful in an ``open'' environment.
+.Pp
+A facility to allow all data exchanges to be encrypted should be
+present.
+.Pp
+A more extensible protocol (such as Telnet) should be used.
diff --git a/rshd.tproj/rshd.c b/rshd.tproj/rshd.c
new file mode 100644
index 0000000..7e8d10c
--- /dev/null
+++ b/rshd.tproj/rshd.c
@@ -0,0 +1,809 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1988, 1989, 1992, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1989, 1992, 1993, 1994\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)rshd.c	8.2 (Berkeley) 4/6/94";
+#endif /* not lint */
+
+/*
+ * remote shell server:
+ *	[port]\0
+ *	remuser\0
+ *	locuser\0
+ *	command\0
+ *	data
+ */
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+int	keepalive = 1;
+int	check_all;
+int	log_success;		/* If TRUE, log all successful accesses */
+int	sent_null;
+
+void	 doit __P((struct sockaddr_in *));
+void	 error __P((const char *, ...));
+void	 getstr __P((char *, int, char *));
+int	 local_domain __P((char *));
+char	*topdomain __P((char *));
+void	 usage __P((void));
+
+#ifdef	KERBEROS
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#define	VERSION_SIZE	9
+#define SECURE_MESSAGE  "This rsh session is using DES encryption for all transmissions.\r\n"
+#define	OPTIONS		"alnkvxL"
+char	authbuf[sizeof(AUTH_DAT)];
+char	tickbuf[sizeof(KTEXT_ST)];
+int	doencrypt, use_kerberos, vacuous;
+Key_schedule	schedule;
+#else
+#define	OPTIONS	"alnL"
+#endif
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	extern int __check_rhosts_file;
+	struct linger linger;
+	int ch, on = 1, fromlen;
+	struct sockaddr_in from;
+
+	openlog("rshd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
+
+	opterr = 0;
+	while ((ch = getopt(argc, argv, OPTIONS)) != EOF)
+		switch (ch) {
+		case 'a':
+			check_all = 1;
+			break;
+		case 'l':
+			__check_rhosts_file = 0;
+			break;
+		case 'n':
+			keepalive = 0;
+			break;
+#ifdef	KERBEROS
+		case 'k':
+			use_kerberos = 1;
+			break;
+
+		case 'v':
+			vacuous = 1;
+			break;
+
+#ifdef CRYPT
+		case 'x':
+			doencrypt = 1;
+			break;
+#endif
+#endif
+		case 'L':
+			log_success = 1;
+			break;
+		case '?':
+		default:
+			usage();
+			break;
+		}
+
+	argc -= optind;
+	argv += optind;
+
+#ifdef	KERBEROS
+	if (use_kerberos && vacuous) {
+		syslog(LOG_ERR, "only one of -k and -v allowed");
+		exit(2);
+	}
+#ifdef CRYPT
+	if (doencrypt && !use_kerberos) {
+		syslog(LOG_ERR, "-k is required for -x");
+		exit(2);
+	}
+#endif
+#endif
+
+	fromlen = sizeof (from);
+	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
+		syslog(LOG_ERR, "getpeername: %m");
+		_exit(1);
+	}
+	if (keepalive &&
+	    setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
+	    sizeof(on)) < 0)
+		syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
+	linger.l_onoff = 1;
+	linger.l_linger = 60;			/* XXX */
+	if (setsockopt(0, SOL_SOCKET, SO_LINGER, (char *)&linger,
+	    sizeof (linger)) < 0)
+		syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m");
+	doit(&from);
+	/* NOTREACHED */
+}
+
+char	username[20] = "USER=";
+char	homedir[64] = "HOME=";
+char	shell[64] = "SHELL=";
+char	path[100] = "PATH=";
+char	*envinit[] =
+	    {homedir, shell, path, username, 0};
+#ifdef __APPLE__
+extern
+#endif
+char	**environ;
+
+void
+doit(fromp)
+	struct sockaddr_in *fromp;
+{
+	extern char *__rcmd_errstr;	/* syslog hook from libc/net/rcmd.c. */
+	struct hostent *hp;
+	struct passwd *pwd;
+	u_short port;
+	fd_set ready, readfrom;
+	int cc, nfd, pv[2], pid, s;
+	int one = 1;
+	char *hostname, *errorstr, *errorhost;
+	char *cp, sig, buf[BUFSIZ];
+	char cmdbuf[NCARGS+1], locuser[16], remuser[16];
+	char remotehost[2 * MAXHOSTNAMELEN + 1];
+
+#ifdef	KERBEROS
+	AUTH_DAT	*kdata = (AUTH_DAT *) NULL;
+	KTEXT		ticket = (KTEXT) NULL;
+	char		instance[INST_SZ], version[VERSION_SIZE];
+	struct		sockaddr_in	fromaddr;
+	int		rc;
+	long		authopts;
+	int		pv1[2], pv2[2];
+	fd_set		wready, writeto;
+
+	fromaddr = *fromp;
+#endif
+
+	(void) signal(SIGINT, SIG_DFL);
+	(void) signal(SIGQUIT, SIG_DFL);
+	(void) signal(SIGTERM, SIG_DFL);
+#ifdef DEBUG
+	{ int t = open(_PATH_TTY, 2);
+	  if (t >= 0) {
+		ioctl(t, TIOCNOTTY, (char *)0);
+		(void) close(t);
+	  }
+	}
+#endif
+	fromp->sin_port = ntohs((u_short)fromp->sin_port);
+	if (fromp->sin_family != AF_INET) {
+		syslog(LOG_ERR, "malformed \"from\" address (af %d)",
+		    fromp->sin_family);
+		exit(1);
+	}
+#ifdef IP_OPTIONS
+      {
+	u_char optbuf[BUFSIZ/3], *cp;
+	char lbuf[BUFSIZ], *lp;
+	int optsize = sizeof(optbuf), ipproto;
+	struct protoent *ip;
+
+	if ((ip = getprotobyname("ip")) != NULL)
+		ipproto = ip->p_proto;
+	else
+		ipproto = IPPROTO_IP;
+	if (!getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, &optsize) &&
+	    optsize != 0) {
+		lp = lbuf;
+		for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
+			sprintf(lp, " %2.2x", *cp);
+		syslog(LOG_NOTICE,
+		    "Connection received from %s using IP options (ignored):%s",
+		    inet_ntoa(fromp->sin_addr), lbuf);
+		if (setsockopt(0, ipproto, IP_OPTIONS,
+		    (char *)NULL, optsize) != 0) {
+			syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
+			exit(1);
+		}
+	}
+      }
+#endif
+
+#ifdef	KERBEROS
+	if (!use_kerberos)
+#endif
+		if (fromp->sin_port >= IPPORT_RESERVED ||
+		    fromp->sin_port < IPPORT_RESERVED/2) {
+			syslog(LOG_NOTICE|LOG_AUTH,
+			    "Connection from %s on illegal port %u",
+			    inet_ntoa(fromp->sin_addr),
+			    fromp->sin_port);
+			exit(1);
+		}
+
+	(void) alarm(60);
+	port = 0;
+	for (;;) {
+		char c;
+		if ((cc = read(STDIN_FILENO, &c, 1)) != 1) {
+			if (cc < 0)
+				syslog(LOG_NOTICE, "read: %m");
+			shutdown(0, 1+1);
+			exit(1);
+		}
+		if (c== 0)
+			break;
+		port = port * 10 + c - '0';
+	}
+
+	(void) alarm(0);
+	if (port != 0) {
+		int lport = IPPORT_RESERVED - 1;
+		s = rresvport(&lport);
+		if (s < 0) {
+			syslog(LOG_ERR, "can't get stderr port: %m");
+			exit(1);
+		}
+#ifdef	KERBEROS
+		if (!use_kerberos)
+#endif
+			if (port >= IPPORT_RESERVED) {
+				syslog(LOG_ERR, "2nd port not reserved");
+				exit(1);
+			}
+		fromp->sin_port = htons(port);
+		if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) {
+			syslog(LOG_INFO, "connect second port %d: %m", port);
+			exit(1);
+		}
+	}
+
+#ifdef	KERBEROS
+	if (vacuous) {
+		error("rshd: remote host requires Kerberos authentication\n");
+		exit(1);
+	}
+#endif
+
+#ifdef notdef
+	/* from inetd, socket is already on 0, 1, 2 */
+	dup2(f, 0);
+	dup2(f, 1);
+	dup2(f, 2);
+#endif
+	errorstr = NULL;
+	hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof (struct in_addr),
+		fromp->sin_family);
+	if (hp) {
+		/*
+		 * If name returned by gethostbyaddr is in our domain,
+		 * attempt to verify that we haven't been fooled by someone
+		 * in a remote net; look up the name and check that this
+		 * address corresponds to the name.
+		 */
+		hostname = hp->h_name;
+#ifdef	KERBEROS
+		if (!use_kerberos)
+#endif
+		if (check_all || local_domain(hp->h_name)) {
+			strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1);
+			remotehost[sizeof(remotehost) - 1] = 0;
+			errorhost = remotehost;
+			hp = gethostbyname(remotehost);
+			if (hp == NULL) {
+				syslog(LOG_INFO,
+				    "Couldn't look up address for %s",
+				    remotehost);
+				errorstr =
+				"Couldn't look up address for your host (%s)\n";
+				hostname = inet_ntoa(fromp->sin_addr);
+			} else for (; ; hp->h_addr_list++) {
+				if (hp->h_addr_list[0] == NULL) {
+					syslog(LOG_NOTICE,
+					  "Host addr %s not listed for host %s",
+					    inet_ntoa(fromp->sin_addr),
+					    hp->h_name);
+					errorstr =
+					    "Host address mismatch for %s\n";
+					hostname = inet_ntoa(fromp->sin_addr);
+					break;
+				}
+				if (!bcmp(hp->h_addr_list[0],
+				    (caddr_t)&fromp->sin_addr,
+				    sizeof(fromp->sin_addr))) {
+					hostname = hp->h_name;
+					break;
+				}
+			}
+		}
+	} else
+		errorhost = hostname = inet_ntoa(fromp->sin_addr);
+
+#ifdef	KERBEROS
+	if (use_kerberos) {
+		kdata = (AUTH_DAT *) authbuf;
+		ticket = (KTEXT) tickbuf;
+		authopts = 0L;
+		strcpy(instance, "*");
+		version[VERSION_SIZE - 1] = '\0';
+#ifdef CRYPT
+		if (doencrypt) {
+			struct sockaddr_in local_addr;
+			rc = sizeof(local_addr);
+			if (getsockname(0, (struct sockaddr *)&local_addr,
+			    &rc) < 0) {
+				syslog(LOG_ERR, "getsockname: %m");
+				error("rshd: getsockname: %m");
+				exit(1);
+			}
+			authopts = KOPT_DO_MUTUAL;
+			rc = krb_recvauth(authopts, 0, ticket,
+				"rcmd", instance, &fromaddr,
+				&local_addr, kdata, "", schedule,
+				version);
+			des_set_key(kdata->session, schedule);
+		} else
+#endif
+			rc = krb_recvauth(authopts, 0, ticket, "rcmd",
+				instance, &fromaddr,
+				(struct sockaddr_in *) 0,
+				kdata, "", (bit_64 *) 0, version);
+		if (rc != KSUCCESS) {
+			error("Kerberos authentication failure: %s\n",
+				  krb_err_txt[rc]);
+			exit(1);
+		}
+	} else
+#endif
+		getstr(remuser, sizeof(remuser), "remuser");
+
+	getstr(locuser, sizeof(locuser), "locuser");
+	getstr(cmdbuf, sizeof(cmdbuf), "command");
+	setpwent();
+	pwd = getpwnam(locuser);
+	if (pwd == NULL) {
+		syslog(LOG_INFO|LOG_AUTH,
+		    "%s@%s as %s: unknown login. cmd='%.80s'",
+		    remuser, hostname, locuser, cmdbuf);
+		if (errorstr == NULL)
+			errorstr = "Login incorrect.\n";
+		goto fail;
+	}
+	if (chdir(pwd->pw_dir) < 0) {
+		(void) chdir("/");
+#ifdef notdef
+		syslog(LOG_INFO|LOG_AUTH,
+		    "%s@%s as %s: no home directory. cmd='%.80s'",
+		    remuser, hostname, locuser, cmdbuf);
+		error("No remote directory.\n");
+		exit(1);
+#endif
+	}
+
+#ifdef	KERBEROS
+	if (use_kerberos) {
+		if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0') {
+			if (kuserok(kdata, locuser) != 0) {
+				syslog(LOG_INFO|LOG_AUTH,
+				    "Kerberos rsh denied to %s.%s@%s",
+				    kdata->pname, kdata->pinst, kdata->prealm);
+				error("Permission denied.\n");
+				exit(1);
+			}
+		}
+	} else
+#endif
+
+		if (errorstr ||
+		    pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&
+		    iruserok(fromp->sin_addr.s_addr, pwd->pw_uid == 0,
+		    remuser, locuser) < 0) {
+			if (__rcmd_errstr)
+				syslog(LOG_INFO|LOG_AUTH,
+			    "%s@%s as %s: permission denied (%s). cmd='%.80s'",
+				    remuser, hostname, locuser, __rcmd_errstr,
+				    cmdbuf);
+			else
+				syslog(LOG_INFO|LOG_AUTH,
+			    "%s@%s as %s: permission denied. cmd='%.80s'",
+				    remuser, hostname, locuser, cmdbuf);
+fail:
+			if (errorstr == NULL)
+				errorstr = "Permission denied.\n";
+			error(errorstr, errorhost);
+			exit(1);
+		}
+
+	if (pwd->pw_uid && !access(_PATH_NOLOGIN, F_OK)) {
+		error("Logins currently disabled.\n");
+		exit(1);
+	}
+
+	(void) write(STDERR_FILENO, "\0", 1);
+	sent_null = 1;
+
+	if (port) {
+		if (pipe(pv) < 0) {
+			error("Can't make pipe.\n");
+			exit(1);
+		}
+#ifdef CRYPT
+#ifdef KERBEROS
+		if (doencrypt) {
+			if (pipe(pv1) < 0) {
+				error("Can't make 2nd pipe.\n");
+				exit(1);
+			}
+			if (pipe(pv2) < 0) {
+				error("Can't make 3rd pipe.\n");
+				exit(1);
+			}
+		}
+#endif
+#endif
+		pid = fork();
+		if (pid == -1)  {
+			error("Can't fork; try again.\n");
+			exit(1);
+		}
+		if (pid) {
+#ifdef CRYPT
+#ifdef KERBEROS
+			if (doencrypt) {
+				static char msg[] = SECURE_MESSAGE;
+				(void) close(pv1[1]);
+				(void) close(pv2[1]);
+				des_write(s, msg, sizeof(msg) - 1);
+
+			} else
+#endif
+#endif
+			{
+				(void) close(0);
+				(void) close(1);
+			}
+			(void) close(2);
+			(void) close(pv[1]);
+
+			FD_ZERO(&readfrom);
+			FD_SET(s, &readfrom);
+			FD_SET(pv[0], &readfrom);
+			if (pv[0] > s)
+				nfd = pv[0];
+			else
+				nfd = s;
+#ifdef CRYPT
+#ifdef KERBEROS
+			if (doencrypt) {
+				FD_ZERO(&writeto);
+				FD_SET(pv2[0], &writeto);
+				FD_SET(pv1[0], &readfrom);
+
+				nfd = MAX(nfd, pv2[0]);
+				nfd = MAX(nfd, pv1[0]);
+			} else
+#endif
+#endif
+				ioctl(pv[0], FIONBIO, (char *)&one);
+
+			/* should set s nbio! */
+			nfd++;
+			do {
+				ready = readfrom;
+#ifdef CRYPT
+#ifdef KERBEROS
+				if (doencrypt) {
+					wready = writeto;
+					if (select(nfd, &ready,
+					    &wready, (fd_set *) 0,
+					    (struct timeval *) 0) < 0)
+						break;
+				} else
+#endif
+#endif
+					if (select(nfd, &ready, (fd_set *)0,
+					  (fd_set *)0, (struct timeval *)0) < 0)
+						break;
+				if (FD_ISSET(s, &ready)) {
+					int	ret;
+#ifdef CRYPT
+#ifdef KERBEROS
+					if (doencrypt)
+						ret = des_read(s, &sig, 1);
+					else
+#endif
+#endif
+						ret = read(s, &sig, 1);
+					if (ret <= 0)
+						FD_CLR(s, &readfrom);
+					else
+						killpg(pid, sig);
+				}
+				if (FD_ISSET(pv[0], &ready)) {
+					errno = 0;
+					cc = read(pv[0], buf, sizeof(buf));
+					if (cc <= 0) {
+						shutdown(s, 1+1);
+						FD_CLR(pv[0], &readfrom);
+					} else {
+#ifdef CRYPT
+#ifdef KERBEROS
+						if (doencrypt)
+							(void)
+							  des_write(s, buf, cc);
+						else
+#endif
+#endif
+							(void)
+							  write(s, buf, cc);
+					}
+				}
+#ifdef CRYPT
+#ifdef KERBEROS
+				if (doencrypt && FD_ISSET(pv1[0], &ready)) {
+					errno = 0;
+					cc = read(pv1[0], buf, sizeof(buf));
+					if (cc <= 0) {
+						shutdown(pv1[0], 1+1);
+						FD_CLR(pv1[0], &readfrom);
+					} else
+						(void) des_write(STDOUT_FILENO,
+						    buf, cc);
+				}
+
+				if (doencrypt && FD_ISSET(pv2[0], &wready)) {
+					errno = 0;
+					cc = des_read(STDIN_FILENO,
+					    buf, sizeof(buf));
+					if (cc <= 0) {
+						shutdown(pv2[0], 1+1);
+						FD_CLR(pv2[0], &writeto);
+					} else
+						(void) write(pv2[0], buf, cc);
+				}
+#endif
+#endif
+
+			} while (FD_ISSET(s, &readfrom) ||
+#ifdef CRYPT
+#ifdef KERBEROS
+			    (doencrypt && FD_ISSET(pv1[0], &readfrom)) ||
+#endif
+#endif
+			    FD_ISSET(pv[0], &readfrom));
+			exit(0);
+		}
+		setpgrp(0, getpid());
+		(void) close(s);
+		(void) close(pv[0]);
+#ifdef CRYPT
+#ifdef KERBEROS
+		if (doencrypt) {
+			close(pv1[0]); close(pv2[0]);
+			dup2(pv1[1], 1);
+			dup2(pv2[1], 0);
+			close(pv1[1]);
+			close(pv2[1]);
+		}
+#endif
+#endif
+		dup2(pv[1], 2);
+		close(pv[1]);
+	}
+	if (*pwd->pw_shell == '\0')
+		pwd->pw_shell = _PATH_BSHELL;
+#if	BSD > 43
+	if (setlogin(pwd->pw_name) < 0)
+		syslog(LOG_ERR, "setlogin() failed: %m");
+#endif
+	(void) setgid((gid_t)pwd->pw_gid);
+	initgroups(pwd->pw_name, pwd->pw_gid);
+	(void) setuid((uid_t)pwd->pw_uid);
+	environ = envinit;
+	strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
+	strcat(path, _PATH_DEFPATH);
+	strncat(shell, pwd->pw_shell, sizeof(shell)-7);
+	strncat(username, pwd->pw_name, sizeof(username)-6);
+	cp = strrchr(pwd->pw_shell, '/');
+	if (cp)
+		cp++;
+	else
+		cp = pwd->pw_shell;
+	endpwent();
+	if (log_success || pwd->pw_uid == 0) {
+#ifdef	KERBEROS
+		if (use_kerberos)
+		    syslog(LOG_INFO|LOG_AUTH,
+			"Kerberos shell from %s.%s@%s on %s as %s, cmd='%.80s'",
+			kdata->pname, kdata->pinst, kdata->prealm,
+			hostname, locuser, cmdbuf);
+		else
+#endif
+		    syslog(LOG_INFO|LOG_AUTH, "%s@%s as %s: cmd='%.80s'",
+			remuser, hostname, locuser, cmdbuf);
+	}
+	execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
+	perror(pwd->pw_shell);
+	exit(1);
+}
+
+/*
+ * Report error to client.  Note: can't be used until second socket has
+ * connected to client, or older clients will hang waiting for that
+ * connection first.
+ */
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+error(const char *fmt, ...)
+#else
+error(fmt, va_alist)
+	char *fmt;
+        va_dcl
+#endif
+{
+	va_list ap;
+	int len;
+	char *bp, buf[BUFSIZ];
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	bp = buf;
+	if (sent_null == 0) {
+		*bp++ = 1;
+		len = 1;
+	} else
+		len = 0;
+	(void)vsnprintf(bp, sizeof(buf) - 1, fmt, ap);
+	(void)write(STDERR_FILENO, buf, len + strlen(bp));
+}
+
+void
+getstr(buf, cnt, err)
+	char *buf, *err;
+	int cnt;
+{
+	char c;
+
+	do {
+		if (read(STDIN_FILENO, &c, 1) != 1)
+			exit(1);
+		*buf++ = c;
+		if (--cnt == 0) {
+			error("%s too long\n", err);
+			exit(1);
+		}
+	} while (c != 0);
+}
+
+/*
+ * Check whether host h is in our local domain,
+ * defined as sharing the last two components of the domain part,
+ * or the entire domain part if the local domain has only one component.
+ * If either name is unqualified (contains no '.'),
+ * assume that the host is local, as it will be
+ * interpreted as such.
+ */
+int
+local_domain(h)
+	char *h;
+{
+	char localhost[MAXHOSTNAMELEN];
+	char *p1, *p2;
+
+	localhost[0] = 0;
+	(void) gethostname(localhost, sizeof(localhost));
+	p1 = topdomain(localhost);
+	p2 = topdomain(h);
+	if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2))
+		return (1);
+	return (0);
+}
+
+char *
+topdomain(h)
+	char *h;
+{
+	char *p, *maybe = NULL;
+	int dots = 0;
+
+	for (p = h + strlen(h); p >= h; p--) {
+		if (*p == '.') {
+			if (++dots == 2)
+				return (p);
+			maybe = p;
+		}
+	}
+	return (maybe);
+}
+
+void
+usage()
+{
+
+	syslog(LOG_ERR, "usage: rshd [-%s]", OPTIONS);
+	exit(2);
+}
diff --git a/ruptime.tproj/Makefile b/ruptime.tproj/Makefile
new file mode 100644
index 0000000..09c2040
--- /dev/null
+++ b/ruptime.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ruptime
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = ruptime.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
+            h.template ruptime.1 Makefile.dist
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ruptime.tproj/Makefile.dist b/ruptime.tproj/Makefile.dist
new file mode 100644
index 0000000..57f1e15
--- /dev/null
+++ b/ruptime.tproj/Makefile.dist
@@ -0,0 +1,5 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/6/93
+
+PROG=	ruptime
+
+.include <bsd.prog.mk>
diff --git a/ruptime.tproj/Makefile.postamble b/ruptime.tproj/Makefile.postamble
new file mode 100644
index 0000000..7823726
--- /dev/null
+++ b/ruptime.tproj/Makefile.postamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
diff --git a/ruptime.tproj/Makefile.preamble b/ruptime.tproj/Makefile.preamble
new file mode 100644
index 0000000..74ce95a
--- /dev/null
+++ b/ruptime.tproj/Makefile.preamble
@@ -0,0 +1,130 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES =
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
diff --git a/ruptime.tproj/PB.project b/ruptime.tproj/PB.project
new file mode 100644
index 0000000..f086f24
--- /dev/null
+++ b/ruptime.tproj/PB.project
@@ -0,0 +1,35 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_LINKED = (ruptime.c); 
+        OTHER_SOURCES = (
+            Makefile.preamble, 
+            Makefile, 
+            Makefile.postamble, 
+            m.template, 
+            h.template, 
+            ruptime.1, 
+            Makefile.dist
+        ); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ruptime; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ruptime.tproj/h.template b/ruptime.tproj/h.template
new file mode 100644
index 0000000..f3c1b04
--- /dev/null
+++ b/ruptime.tproj/h.template
@@ -0,0 +1,11 @@
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+#import <Foundation/Foundation.h>
+
+@interface $FILENAMESANSEXTENSION$ : NSObject
+{
+
+}
+
+@end
diff --git a/ruptime.tproj/m.template b/ruptime.tproj/m.template
new file mode 100644
index 0000000..1216fe5
--- /dev/null
+++ b/ruptime.tproj/m.template
@@ -0,0 +1,18 @@
+$$ Lines starting with $$ are not inserted into newly created files
+$$ The following substitutions are made:
+$$
+$$ $FILENAME$                e.g. foo.m
+$$ $FILENAMESANSEXTENSION$   e.g. foo
+$$ $DIRECTORY$               e.g. /tmp/MyNewApp
+$$ $PROJECTNAME$             e.g. MyNewApp
+$$ $SUBPROJECTNAME$          e.g. TheGoodPart.subproj
+$$ $USERNAME$                e.g. mwagner
+$$ $DATE$                    e.g. Jan-1-1994
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+#import "$FILENAMESANSEXTENSION$.h"
+
+@implementation $FILENAMESANSEXTENSION$
+
+@end
diff --git a/ruptime.tproj/ruptime.1 b/ruptime.tproj/ruptime.1
new file mode 100644
index 0000000..b3b0af8
--- /dev/null
+++ b/ruptime.tproj/ruptime.1
@@ -0,0 +1,81 @@
+.\" Copyright (c) 1983, 1990, 1993, 1994
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)ruptime.1	8.2 (Berkeley) 4/5/94
+.\"
+.Dd April 5, 1994
+.Dt RUPTIME 1
+.Os BSD 4.2
+.Sh NAME
+.Nm ruptime
+.Nd show host status of local machines
+.Sh SYNOPSIS
+.Nm ruptime
+.Op Fl alrtu
+.Sh DESCRIPTION
+.Nm Ruptime
+gives a status line like
+.Ar uptime
+for each machine on the local network; these are formed from packets
+broadcast by each host on the network once a minute.
+.Pp
+Machines for which no status report has been received for 11
+minutes are shown as being down.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl a
+Users idle an hour or more are not counted unless the
+.Fl a
+flag is given.
+.It Fl l
+Sort by load average.
+.It Fl r
+Reverses the sort order.
+.It Fl t
+Sort by uptime.
+.It Fl u
+Sort by number of users.
+.El
+.Pp
+The default listing is sorted by host name.
+.Sh FILES
+.Bl -tag -width /var/rwho/whod.* -compact
+.It Pa /var/rwho/whod.*
+data files
+.El
+.Sh SEE ALSO
+.Xr rwho 1
+.Xr uptime 1
+.Sh HISTORY
+.Nm Ruptime
+appeared in
+.Bx 4.2 .
diff --git a/ruptime.tproj/ruptime.c b/ruptime.tproj/ruptime.c
new file mode 100644
index 0000000..e6cb457
--- /dev/null
+++ b/ruptime.tproj/ruptime.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993, 1994\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#include <sys/param.h>
+
+#include <protocols/rwhod.h>
+
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <tzfile.h>
+#include <unistd.h>
+
+struct hs {
+	struct	whod *hs_wd;
+	int	hs_nusers;
+} *hs;
+struct	whod awhod;
+
+#define	ISDOWN(h)		(now - (h)->hs_wd->wd_recvtime > 11 * 60)
+#define	WHDRSIZE	(sizeof (awhod) - sizeof (awhod.wd_we))
+
+size_t nhosts;
+time_t now;
+int rflg = 1;
+
+int	 hscmp __P((const void *, const void *));
+char	*interval __P((time_t, char *));
+int	 lcmp __P((const void *, const void *));
+void	 morehosts __P((void));
+int	 tcmp __P((const void *, const void *));
+int	 ucmp __P((const void *, const void *));
+void	 usage __P((void));
+
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	extern int optind;
+	struct dirent *dp;
+	struct hs *hsp;
+	struct whod *wd;
+	struct whoent *we;
+	DIR *dirp;
+	size_t hspace;
+	int aflg, cc, ch, fd, i, maxloadav;
+	char buf[sizeof(struct whod)];
+	int (*cmp) __P((const void *, const void *));
+
+	aflg = 0;
+	cmp = hscmp;
+	while ((ch = getopt(argc, argv, "alrut")) != EOF)
+		switch (ch) {
+		case 'a':
+			aflg = 1;
+			break;
+		case 'l':
+			cmp = lcmp;
+			break;
+		case 'r':
+			rflg = -1;
+			break;
+		case 't':
+			cmp = tcmp;
+			break;
+		case 'u':
+			cmp = ucmp;
+			break;
+		default: 
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 0)
+		usage();
+
+	if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL)
+		err(1, "%s", _PATH_RWHODIR);
+
+	maxloadav = -1;
+	for (nhosts = hspace = 0; (dp = readdir(dirp)) != NULL;) {
+		if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
+			continue;
+		if ((fd = open(dp->d_name, O_RDONLY, 0)) < 0) {
+			warn("%s", dp->d_name);
+			continue;
+		}
+		cc = read(fd, buf, sizeof(struct whod));
+		(void)close(fd);
+
+		if (cc < WHDRSIZE)
+			continue;
+		if (nhosts == hspace) {
+			if ((hs =
+			    realloc(hs, (hspace += 40) * sizeof(*hs))) == NULL)
+				err(1, NULL);
+			hsp = hs + nhosts;
+		}
+
+		if ((hsp->hs_wd = malloc((size_t)WHDRSIZE)) == NULL)
+			err(1, NULL);
+		memmove(hsp->hs_wd, buf, (size_t)WHDRSIZE);
+
+		for (wd = (struct whod *)buf, i = 0; i < 2; ++i)
+			if (wd->wd_loadav[i] > maxloadav)
+				maxloadav = wd->wd_loadav[i];
+
+		for (hsp->hs_nusers = 0,
+		    we = (struct whoent *)(buf + cc); --we >= wd->wd_we;)
+			if (aflg || we->we_idle < 3600)
+				++hsp->hs_nusers;
+		++hsp;
+		++nhosts;
+	}
+	if (nhosts == 0)
+		errx(0, "no hosts in %s.", _PATH_RWHODIR);
+
+	(void)time(&now);
+	qsort(hs, nhosts, sizeof(hs[0]), cmp);
+	for (i = 0; i < nhosts; i++) {
+		hsp = &hs[i];
+		if (ISDOWN(hsp)) {
+			(void)printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname,
+			    interval(now - hsp->hs_wd->wd_recvtime, "down"));
+			continue;
+		}
+		(void)printf(
+		    "%-12.12s%s,  %4d user%s  load %*.2f, %*.2f, %*.2f\n",
+		    hsp->hs_wd->wd_hostname,
+		    interval((time_t)hsp->hs_wd->wd_sendtime -
+			(time_t)hsp->hs_wd->wd_boottime, "  up"),
+		    hsp->hs_nusers,
+		    hsp->hs_nusers == 1 ? ", " : "s,",
+		    maxloadav >= 1000 ? 5 : 4,
+			hsp->hs_wd->wd_loadav[0] / 100.0,
+		    maxloadav >= 1000 ? 5 : 4,
+		        hsp->hs_wd->wd_loadav[1] / 100.0,
+		    maxloadav >= 1000 ? 5 : 4,
+		        hsp->hs_wd->wd_loadav[2] / 100.0);
+	}
+	exit(0);
+}
+
+char *
+interval(tval, updown)
+	time_t tval;
+	char *updown;
+{
+	static char resbuf[32];
+	int days, hours, minutes;
+
+	if (tval < 0 || tval > DAYSPERNYEAR * SECSPERDAY) {
+		(void)snprintf(resbuf, sizeof(resbuf), "   %s ??:??", updown);
+		return (resbuf);
+	}
+						/* round to minutes. */
+	minutes = (tval + (SECSPERMIN - 1)) / SECSPERMIN;
+	hours = minutes / MINSPERHOUR;
+	minutes %= MINSPERHOUR;
+	days = hours / HOURSPERDAY;
+	hours %= HOURSPERDAY;
+	if (days)
+		(void)snprintf(resbuf, sizeof(resbuf),
+		    "%s %2d+%02d:%02d", updown, days, hours, minutes);
+	else
+		(void)snprintf(resbuf, sizeof(resbuf),
+		    "%s    %2d:%02d", updown, hours, minutes);
+	return (resbuf);
+}
+
+#define	HS(a)	((struct hs *)(a))
+
+/* Alphabetical comparison. */
+int
+hscmp(a1, a2)
+	const void *a1, *a2;
+{
+	return (rflg *
+	    strcmp(HS(a1)->hs_wd->wd_hostname, HS(a2)->hs_wd->wd_hostname));
+}
+
+/* Load average comparison. */
+int
+lcmp(a1, a2)
+	const void *a1, *a2;
+{
+	if (ISDOWN(HS(a1)))
+		if (ISDOWN(HS(a2)))
+			return (tcmp(a1, a2));
+		else
+			return (rflg);
+	else if (ISDOWN(HS(a2)))
+		return (-rflg);
+	else
+		return (rflg *
+		   (HS(a2)->hs_wd->wd_loadav[0] - HS(a1)->hs_wd->wd_loadav[0]));
+}
+
+/* Number of users comparison. */
+int
+ucmp(a1, a2)
+	const void *a1, *a2;
+{
+	if (ISDOWN(HS(a1)))
+		if (ISDOWN(HS(a2)))
+			return (tcmp(a1, a2));
+		else
+			return (rflg);
+	else if (ISDOWN(HS(a2)))
+		return (-rflg);
+	else
+		return (rflg * (HS(a2)->hs_nusers - HS(a1)->hs_nusers));
+}
+
+/* Uptime comparison. */
+int
+tcmp(a1, a2)
+	const void *a1, *a2;
+{
+	return (rflg * (
+		(ISDOWN(HS(a2)) ? HS(a2)->hs_wd->wd_recvtime - now
+		    : HS(a2)->hs_wd->wd_sendtime - HS(a2)->hs_wd->wd_boottime)
+		-
+		(ISDOWN(HS(a1)) ? HS(a1)->hs_wd->wd_recvtime - now
+		    : HS(a1)->hs_wd->wd_sendtime - HS(a1)->hs_wd->wd_boottime)
+	));
+}
+
+void
+usage()
+{
+	(void)fprintf(stderr, "usage: ruptime [-alrut]\n");
+	exit(1);
+}
diff --git a/rwho.tproj/Makefile b/rwho.tproj/Makefile
new file mode 100644
index 0000000..ac0d8cb
--- /dev/null
+++ b/rwho.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rwho
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = rwho.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble rwho.1\
+            Makefile.dist
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rwho.tproj/Makefile.dist b/rwho.tproj/Makefile.dist
new file mode 100644
index 0000000..328aa38
--- /dev/null
+++ b/rwho.tproj/Makefile.dist
@@ -0,0 +1,5 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/6/93
+
+PROG=	rwho
+
+.include <bsd.prog.mk>
diff --git a/rwho.tproj/Makefile.postamble b/rwho.tproj/Makefile.postamble
new file mode 100644
index 0000000..7823726
--- /dev/null
+++ b/rwho.tproj/Makefile.postamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
diff --git a/rwho.tproj/Makefile.preamble b/rwho.tproj/Makefile.preamble
new file mode 100644
index 0000000..74ce95a
--- /dev/null
+++ b/rwho.tproj/Makefile.preamble
@@ -0,0 +1,130 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES =
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
diff --git a/rwho.tproj/PB.project b/rwho.tproj/PB.project
new file mode 100644
index 0000000..8a18feb
--- /dev/null
+++ b/rwho.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_LINKED = (rwho.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, rwho.1, Makefile.dist); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rwho; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rwho.tproj/rwho.1 b/rwho.tproj/rwho.1
new file mode 100644
index 0000000..f039b01
--- /dev/null
+++ b/rwho.tproj/rwho.1
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1983, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)rwho.1	8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt RWHO 1
+.Os BSD 4.2
+.Sh NAME
+.Nm rwho
+.Nd who is logged in on local machines
+.Sh SYNOPSIS
+.Nm rwho
+.Op Fl a
+.Sh DESCRIPTION
+The
+.Nm rwho
+command produces output similar to
+.Xr who ,
+but for all machines on the local network.
+If no report has been
+received from a machine for 5 minutes then
+.Nm rwho
+assumes the machine is down, and does not report users last known
+to be logged into that machine.
+.Pp
+If a users hasn't typed to the system for a minute or more, then
+.Nm rwho
+reports this idle time.  If a user hasn't typed to the system for
+an hour or more, then
+the user will be omitted from the output of
+.Nm rwho
+unless the
+.Fl a
+flag is given.
+.Sh FILES
+.Bl -tag -width /var/rwho/rhowd.* -compact
+.It Pa /var/rwho/whod.*
+information about other machines
+.El
+.Sh SEE ALSO
+.Xr ruptime 1 ,
+.Xr rwhod 8
+.Sh HISTORY
+The
+.Nm rwho
+command
+appeared in
+.Bx 4.3 .
+.Sh BUGS
+This is unwieldy when the number of machines
+on the local net is large.
diff --git a/rwho.tproj/rwho.c b/rwho.tproj/rwho.c
new file mode 100644
index 0000000..815f13a
--- /dev/null
+++ b/rwho.tproj/rwho.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/file.h>
+#include <protocols/rwhod.h>
+#include <stdio.h>
+
+DIR	*dirp;
+
+struct	whod wd;
+int	utmpcmp();
+#define	NUSERS	1000
+struct	myutmp {
+	char	myhost[MAXHOSTNAMELEN];
+	int	myidle;
+	struct	outmp myutmp;
+} myutmp[NUSERS];
+int	nusers;
+
+#define	WHDRSIZE	(sizeof (wd) - sizeof (wd.wd_we))
+/* 
+ * this macro should be shared with ruptime.
+ */
+#define	down(w,now)	((now) - (w)->wd_recvtime > 11 * 60)
+
+char	*ctime(), *strcpy();
+time_t	now;
+int	aflg;
+
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	extern char *optarg;
+	extern int optind;
+	int ch;
+	struct direct *dp;
+	int cc, width;
+	register struct whod *w = &wd;
+	register struct whoent *we;
+	register struct myutmp *mp;
+	int f, n, i;
+	time_t time();
+
+	while ((ch = getopt(argc, argv, "a")) != EOF)
+		switch((char)ch) {
+		case 'a':
+			aflg = 1;
+			break;
+		case '?':
+		default:
+			fprintf(stderr, "usage: rwho [-a]\n");
+			exit(1);
+		}
+	if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) {
+		perror(_PATH_RWHODIR);
+		exit(1);
+	}
+	mp = myutmp;
+	(void)time(&now);
+	while (dp = readdir(dirp)) {
+		if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
+			continue;
+		f = open(dp->d_name, O_RDONLY);
+		if (f < 0)
+			continue;
+		cc = read(f, (char *)&wd, sizeof (struct whod));
+		if (cc < WHDRSIZE) {
+			(void) close(f);
+			continue;
+		}
+		if (down(w,now)) {
+			(void) close(f);
+			continue;
+		}
+		cc -= WHDRSIZE;
+		we = w->wd_we;
+		for (n = cc / sizeof (struct whoent); n > 0; n--) {
+			if (aflg == 0 && we->we_idle >= 60*60) {
+				we++;
+				continue;
+			}
+			if (nusers >= NUSERS) {
+				printf("too many users\n");
+				exit(1);
+			}
+			mp->myutmp = we->we_utmp; mp->myidle = we->we_idle;
+			(void) strcpy(mp->myhost, w->wd_hostname);
+			nusers++; we++; mp++;
+		}
+		(void) close(f);
+	}
+	qsort((char *)myutmp, nusers, sizeof (struct myutmp), utmpcmp);
+	mp = myutmp;
+	width = 0;
+	for (i = 0; i < nusers; i++) {
+		int j = strlen(mp->myhost) + 1 + strlen(mp->myutmp.out_line);
+		if (j > width)
+			width = j;
+		mp++;
+	}
+	mp = myutmp;
+	for (i = 0; i < nusers; i++) {
+		char buf[BUFSIZ];
+		(void)sprintf(buf, "%s:%s", mp->myhost, mp->myutmp.out_line);
+		printf("%-8.8s %-*s %.12s",
+		   mp->myutmp.out_name,
+		   width,
+		   buf,
+		   ctime((time_t *)&mp->myutmp.out_time)+4);
+		mp->myidle /= 60;
+		if (mp->myidle) {
+			if (aflg) {
+				if (mp->myidle >= 100*60)
+					mp->myidle = 100*60 - 1;
+				if (mp->myidle >= 60)
+					printf(" %2d", mp->myidle / 60);
+				else
+					printf("   ");
+			} else
+				printf(" ");
+			printf(":%02d", mp->myidle % 60);
+		}
+		printf("\n");
+		mp++;
+	}
+	exit(0);
+}
+
+utmpcmp(u1, u2)
+	struct myutmp *u1, *u2;
+{
+	int rc;
+
+	rc = strncmp(u1->myutmp.out_name, u2->myutmp.out_name, 8);
+	if (rc)
+		return (rc);
+	rc = strncmp(u1->myhost, u2->myhost, 8);
+	if (rc)
+		return (rc);
+	return (strncmp(u1->myutmp.out_line, u2->myutmp.out_line, 8));
+}
diff --git a/rwhod.tproj/Makefile b/rwhod.tproj/Makefile
new file mode 100644
index 0000000..fc4f54b
--- /dev/null
+++ b/rwhod.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rwhod
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = rwhod.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble rwhod.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rwhod.tproj/Makefile.postamble b/rwhod.tproj/Makefile.postamble
new file mode 100644
index 0000000..f5c79e2
--- /dev/null
+++ b/rwhod.tproj/Makefile.postamble
@@ -0,0 +1,110 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app)
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+
+
+# Change defaults assumed by the standard app makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if
+# you would like changes to them to invalidate previous builds.  The project
+# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build.
+#MAKEFILES = Makefile 
+
+# Optimization flag passed to compiler:
+#OPTIMIZATION_CFLAG = -O
+
+# Flags always passed to compiler:
+#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall  
+
+# Flags passed to compiler in normal 'app' compiles:
+#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG)
+
+# Flags passed to compiler in 'debug' compiles:
+#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG
+
+# Flags passed to compiler in 'profile' compiles
+#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User to chown app to
+#INSTALL_AS_GROUP = wheel      # Group to chgrp app to 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for bundles, apps with bundles, and apps without bundles, 
+# respectively.
+#RELOCATABLE_STRIP_OPTS = -x -u
+#DYLD_APP_STRIP_OPTS = -A -n
+#APP_STRIP_OPTS = 
+#TOOL_STRIP_OPTS = 
+#LIBRARY_STRIP_OPTS = -x -S   # Note: -S strips debugging symbols
+# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but
+#  developers doing their own dynamic loading should set this to 
+#  $(DYLD_APP_STRIP_OPTS)).
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Typical 
+# user-defined rules are before_install and after_install (please don't 
+# redefine things like install or app, as they are owned by the top-level 
+# Makefile API), which are rules that get invoked before and after the install 
+# target runs.  Such rules should be specified with the '::' syntax rather than 
+# a single colon.
diff --git a/rwhod.tproj/Makefile.preamble b/rwhod.tproj/Makefile.preamble
new file mode 100644
index 0000000..2c9003c
--- /dev/null
+++ b/rwhod.tproj/Makefile.preamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags here.  To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+
+BUNDLELDFLAGS =            # use iff project is a bundle
+PALETTELDFLAGS =           # use iff project is a palette
+
+## Specify which headers in this project should be published to the outside 
+## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be 
+## prepended by DSTROOT, below.  Any subset of these public headers can be
+## precompiled automatically after installation, with extra user-defined flags.
+PUBLIC_HEADER_DIR = 
+PUBLIC_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+## Configure what is linked in at each level here.  Libraries are only used in
+## the final 'app' linking step.  Final 'app' linking is only done via the
+## 'app', 'debug', and 'profile' targets when they are invoked for
+## the top-level app.
+
+# Additional relocatables to be linked in at this level
+OTHER_OFILES = 
+# Additional libs to link apps against ('app' target)
+#OTHER_LIBS = 
+# Additional libs to link apps against ('debug' target)
+OTHER_DEBUG_LIBS = 
+# Additional libs to link apps against ('profile' target)
+OTHER_PROF_LIBS = 
+
+# More 'app' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# More 'debug' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_DEBUG_LIBS = 
+# More 'profile' libs when $(JAPANESE) = "YES"
+OTHER_JAPANESE_PROF_LIBS = 
+
+# If this is a bundle, and you *know* the enclosing application will not
+# be linking with a library which you require in your bundle code, then
+# mention it here so that it gets linked into the bundle.  Note that this
+# is wasteful but sometimes necessary.
+BUNDLE_LIBS = 
+
+## Configure how things get built here.  Additional dependencies, sourcefiles, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+# Precompiled headers to be built before any compilation occurs (e.g., draw.p)
+PRECOMPS = 
+
+# Targets to be built before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# Set the following to "YES" if you want the old behavior of recursively
+# cleaning all nested subprojects during 'make clean'.
+CLEAN_ALL_SUBPROJECTS =
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+# To include a version string, project source must exist in a directory named
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/rwhod.tproj/PB.project b/rwhod.tproj/PB.project
new file mode 100644
index 0000000..9329dd8
--- /dev/null
+++ b/rwhod.tproj/PB.project
@@ -0,0 +1,41 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (rwhod.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, rwhod.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rwhod; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rwhod.tproj/rwhod.8 b/rwhod.tproj/rwhod.8
new file mode 100644
index 0000000..4b8492e
--- /dev/null
+++ b/rwhod.tproj/rwhod.8
@@ -0,0 +1,146 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)rwhod.8	8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt RWHOD 8
+.Os BSD 4.2
+.Sh NAME
+.Nm rwhod
+.Nd system status server
+.Sh SYNOPSIS
+.Nm rwhod
+.Sh DESCRIPTION
+.Nm Rwhod
+is the server which maintains the database used by the
+.Xr rwho 1
+and
+.Xr ruptime 1
+programs.  Its operation is predicated on the ability to
+.Em broadcast
+messages on a network.
+.Pp
+.Nm Rwhod
+operates as both a producer and consumer of status information.
+As a producer of information it periodically
+queries the state of the system and constructs
+status messages which are broadcast on a network.
+As a consumer of information, it listens for other
+.Nm rwhod
+servers' status messages, validating them, then recording
+them in a collection of files located in the directory
+.Pa /var/rwho .
+.Pp
+The server transmits and receives messages at the port indicated
+in the ``rwho'' service specification; see 
+.Xr services 5 .
+The messages sent and received, are of the form:
+.Bd -literal -offset indent
+struct	outmp {
+	char	out_line[8];		/* tty name */
+	char	out_name[8];		/* user id */
+	long	out_time;		/* time on */
+};
+
+struct	whod {
+	char	wd_vers;
+	char	wd_type;
+	char	wd_fill[2];
+	int	wd_sendtime;
+	int	wd_recvtime;
+	char	wd_hostname[32];
+	int	wd_loadav[3];
+	int	wd_boottime;
+	struct	whoent {
+		struct	outmp we_utmp;
+		int	we_idle;
+	} wd_we[1024 / sizeof (struct whoent)];
+};
+.Ed
+.Pp
+All fields are converted to network byte order prior to
+transmission.  The load averages are as calculated by the
+.Xr w 1
+program, and represent load averages over the 5, 10, and 15 minute 
+intervals prior to a server's transmission; they are multiplied by 100
+for representation in an integer.  The host name
+included is that returned by the
+.Xr gethostname 2
+system call, with any trailing domain name omitted.
+The array at the end of the message contains information about
+the users logged in to the sending machine.  This information 
+includes the contents of the 
+.Xr utmp 5
+entry for each non-idle terminal line and a value indicating the
+time in seconds since a character was last received on the terminal line.
+.Pp
+Messages received by the
+.Xr rwho
+server are discarded unless they originated at an
+.Xr rwho
+server's port.  In addition, if the host's name, as specified
+in the message, contains any unprintable
+.Tn ASCII
+characters, the
+message is discarded.  Valid messages received by
+.Nm rwhod
+are placed in files named
+.Pa whod.hostname
+in the directory
+.Pa /var/rwho .
+These files contain only the most recent message, in the
+format described above.
+.Pp
+Status messages are generated approximately once every
+3 minutes.
+.Nm Rwhod
+performs an
+.Xr nlist 3
+on
+.Pa /vmunix
+every 30 minutes to guard against
+the possibility that this file is not the system
+image currently operating.
+.Sh SEE ALSO
+.Xr rwho 1 ,
+.Xr ruptime 1
+.Sh BUGS
+There should be a way to relay status information between networks. 
+Status information should be sent only upon request rather than continuously.
+People often interpret the server dying
+or network communication failures
+as a machine going down.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/rwhod.tproj/rwhod.c b/rwhod.tproj/rwhod.c
new file mode 100644
index 0000000..6094340
--- /dev/null
+++ b/rwhod.tproj/rwhod.c
@@ -0,0 +1,562 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)rwhod.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/signal.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <protocols/rwhod.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <utmp.h>
+
+/*
+ * Alarm interval. Don't forget to change the down time check in ruptime
+ * if this is changed.
+ */
+#define AL_INTERVAL (3 * 60)
+
+char	myname[MAXHOSTNAMELEN];
+
+/*
+ * We communicate with each neighbor in a list constructed at the time we're
+ * started up.  Neighbors are currently directly connected via a hardware
+ * interface.
+ */
+struct	neighbor {
+	struct	neighbor *n_next;
+	char	*n_name;		/* interface name */
+	struct	sockaddr *n_addr;		/* who to send to */
+	int	n_addrlen;		/* size of address */
+	int	n_flags;		/* should forward?, interface flags */
+};
+
+struct	neighbor *neighbors;
+struct	whod mywd;
+struct	servent *sp;
+int	s, utmpf;
+
+#define	WHDRSIZE	(sizeof(mywd) - sizeof(mywd.wd_we))
+
+int	 configure __P((int));
+void	 getboottime __P((int));
+void	 onalrm __P((int));
+void	 quit __P((char *));
+void	 rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
+int	 verify __P((char *));
+#ifdef DEBUG
+char	*interval __P((int, char *));
+void	 Sendto __P((int, char *, int, int, char *, int));
+#define	 sendto Sendto
+#endif
+
+int
+main(argc, argv)
+	int argc;
+	char argv[];
+{
+	struct sockaddr_in from;
+	struct stat st;
+	char path[64];
+	int on = 1;
+	char *cp;
+	struct sockaddr_in sin;
+
+	if (getuid()) {
+		fprintf(stderr, "rwhod: not super user\n");
+		exit(1);
+	}
+	sp = getservbyname("who", "udp");
+	if (sp == NULL) {
+		fprintf(stderr, "rwhod: udp/who: unknown service\n");
+		exit(1);
+	}
+#ifndef DEBUG
+	daemon(1, 0);
+#endif
+	if (chdir(_PATH_RWHODIR) < 0) {
+		(void)fprintf(stderr, "rwhod: %s: %s\n",
+		    _PATH_RWHODIR, strerror(errno));
+		exit(1);
+	}
+	(void) signal(SIGHUP, getboottime);
+	openlog("rwhod", LOG_PID, LOG_DAEMON);
+	/*
+	 * Establish host name as returned by system.
+	 */
+	if (gethostname(myname, sizeof(myname) - 1) < 0) {
+		syslog(LOG_ERR, "gethostname: %m");
+		exit(1);
+	}
+	if ((cp = index(myname, '.')) != NULL)
+		*cp = '\0';
+	strncpy(mywd.wd_hostname, myname, sizeof(myname) - 1);
+	utmpf = open(_PATH_UTMP, O_RDONLY|O_CREAT, 0644);
+	if (utmpf < 0) {
+		syslog(LOG_ERR, "%s: %m", _PATH_UTMP);
+		exit(1);
+	}
+	getboottime(0);
+	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+		syslog(LOG_ERR, "socket: %m");
+		exit(1);
+	}
+	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
+		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
+		exit(1);
+	}
+	memset(&sin, 0, sizeof(sin));
+	sin.sin_family = AF_INET;
+	sin.sin_port = sp->s_port;
+	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+		syslog(LOG_ERR, "bind: %m");
+		exit(1);
+	}
+	if (!configure(s))
+		exit(1);
+	signal(SIGALRM, onalrm);
+	onalrm(0);
+	for (;;) {
+		struct whod wd;
+		int cc, whod, len = sizeof(from);
+
+		cc = recvfrom(s, (char *)&wd, sizeof(struct whod), 0,
+			(struct sockaddr *)&from, &len);
+		if (cc <= 0) {
+			if (cc < 0 && errno != EINTR)
+				syslog(LOG_WARNING, "recv: %m");
+			continue;
+		}
+		if (from.sin_port != sp->s_port) {
+			syslog(LOG_WARNING, "%d: bad from port",
+				ntohs(from.sin_port));
+			continue;
+		}
+		if (wd.wd_vers != WHODVERSION)
+			continue;
+		if (wd.wd_type != WHODTYPE_STATUS)
+			continue;
+		if (!verify(wd.wd_hostname)) {
+			syslog(LOG_WARNING, "malformed host name from %x",
+				from.sin_addr);
+			continue;
+		}
+		(void) sprintf(path, "whod.%s", wd.wd_hostname);
+		/*
+		 * Rather than truncating and growing the file each time,
+		 * use ftruncate if size is less than previous size.
+		 */
+		whod = open(path, O_WRONLY | O_CREAT, 0644);
+		if (whod < 0) {
+			syslog(LOG_WARNING, "%s: %m", path);
+			continue;
+		}
+#if ENDIAN != BIG_ENDIAN
+		{
+			int i, n = (cc - WHDRSIZE)/sizeof(struct whoent);
+			struct whoent *we;
+
+			/* undo header byte swapping before writing to file */
+			wd.wd_sendtime = ntohl(wd.wd_sendtime);
+			for (i = 0; i < 3; i++)
+				wd.wd_loadav[i] = ntohl(wd.wd_loadav[i]);
+			wd.wd_boottime = ntohl(wd.wd_boottime);
+			we = wd.wd_we;
+			for (i = 0; i < n; i++) {
+				we->we_idle = ntohl(we->we_idle);
+				we->we_utmp.out_time =
+				    ntohl(we->we_utmp.out_time);
+				we++;
+			}
+		}
+#endif
+		(void) time((time_t *)&wd.wd_recvtime);
+		(void) write(whod, (char *)&wd, cc);
+		if (fstat(whod, &st) < 0 || st.st_size > cc)
+			ftruncate(whod, cc);
+		(void) close(whod);
+	}
+}
+
+/*
+ * Check out host name for unprintables
+ * and other funnies before allowing a file
+ * to be created.  Sorry, but blanks aren't allowed.
+ */
+int
+verify(name)
+	register char *name;
+{
+	register int size = 0;
+
+	while (*name) {
+		if (!isascii(*name) || !(isalnum(*name) || ispunct(*name)))
+			return (0);
+		name++, size++;
+	}
+	return (size > 0);
+}
+
+int	utmptime;
+int	utmpent;
+int	utmpsize = 0;
+struct	utmp *utmp;
+int	alarmcount;
+
+void
+onalrm(signo)
+	int signo;
+{
+	register struct neighbor *np;
+	register struct whoent *we = mywd.wd_we, *wlast;
+	register int i;
+	struct stat stb;
+	double avenrun[3];
+	time_t now;
+	int cc;
+
+	now = time(NULL);
+	if (alarmcount % 10 == 0)
+		getboottime(0);
+	alarmcount++;
+	(void) fstat(utmpf, &stb);
+	if ((stb.st_mtime != utmptime) || (stb.st_size > utmpsize)) {
+		utmptime = stb.st_mtime;
+		if (stb.st_size > utmpsize) {
+			utmpsize = stb.st_size + 10 * sizeof(struct utmp);
+			if (utmp)
+				utmp = (struct utmp *)realloc(utmp, utmpsize);
+			else
+				utmp = (struct utmp *)malloc(utmpsize);
+			if (! utmp) {
+				fprintf(stderr, "rwhod: malloc failed\n");
+				utmpsize = 0;
+				goto done;
+			}
+		}
+		(void) lseek(utmpf, (off_t)0, L_SET);
+		cc = read(utmpf, (char *)utmp, stb.st_size);
+		if (cc < 0) {
+			fprintf(stderr, "rwhod: %s: %s\n",
+			    _PATH_UTMP, strerror(errno));
+			goto done;
+		}
+		wlast = &mywd.wd_we[1024 / sizeof(struct whoent) - 1];
+		utmpent = cc / sizeof(struct utmp);
+		for (i = 0; i < utmpent; i++)
+			if (utmp[i].ut_name[0]) {
+				memcpy(we->we_utmp.out_line, utmp[i].ut_line,
+				   sizeof(utmp[i].ut_line));
+				memcpy(we->we_utmp.out_name, utmp[i].ut_name,
+				   sizeof(utmp[i].ut_name));
+				we->we_utmp.out_time = htonl(utmp[i].ut_time);
+				if (we >= wlast)
+					break;
+				we++;
+			}
+		utmpent = we - mywd.wd_we;
+	}
+
+	/*
+	 * The test on utmpent looks silly---after all, if no one is
+	 * logged on, why worry about efficiency?---but is useful on
+	 * (e.g.) compute servers.
+	 */
+	if (utmpent && chdir(_PATH_DEV)) {
+		syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV);
+		exit(1);
+	}
+	we = mywd.wd_we;
+	for (i = 0; i < utmpent; i++) {
+		if (stat(we->we_utmp.out_line, &stb) >= 0)
+			we->we_idle = htonl(now - stb.st_atime);
+		we++;
+	}
+	(void)getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0]));
+	for (i = 0; i < 3; i++)
+		mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100));
+	cc = (char *)we - (char *)&mywd;
+	mywd.wd_sendtime = htonl(time(0));
+	mywd.wd_vers = WHODVERSION;
+	mywd.wd_type = WHODTYPE_STATUS;
+	for (np = neighbors; np != NULL; np = np->n_next)
+		(void)sendto(s, (char *)&mywd, cc, 0,
+				np->n_addr, np->n_addrlen);
+	if (utmpent && chdir(_PATH_RWHODIR)) {
+		syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR);
+		exit(1);
+	}
+done:
+	(void) alarm(AL_INTERVAL);
+}
+
+void
+getboottime(signo)
+	int signo;
+{
+	int mib[2];
+	size_t size;
+	struct timeval tm;
+
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_BOOTTIME;
+	size = sizeof(tm);
+	if (sysctl(mib, 2, &tm, &size, NULL, 0) == -1) {
+		syslog(LOG_ERR, "cannot get boottime: %m");
+		exit(1);
+	}
+	mywd.wd_boottime = htonl(tm.tv_sec);
+}
+
+void
+quit(msg)
+	char *msg;
+{
+	syslog(LOG_ERR, msg);
+	exit(1);
+}
+
+#define ROUNDUP(a) \
+	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+void
+rt_xaddrs(cp, cplim, rtinfo)
+	register caddr_t cp, cplim;
+	register struct rt_addrinfo *rtinfo;
+{
+	register struct sockaddr *sa;
+	register int i;
+
+	memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
+	for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
+		if ((rtinfo->rti_addrs & (1 << i)) == 0)
+			continue;
+		rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
+		ADVANCE(cp, sa);
+	}
+}
+
+/*
+ * Figure out device configuration and select
+ * networks which deserve status information.
+ */
+int
+configure(s)
+	int s;
+{
+	register struct neighbor *np;
+	register struct if_msghdr *ifm;
+	register struct ifa_msghdr *ifam;
+	struct sockaddr_dl *sdl;
+	size_t needed;
+	int mib[6], flags = 0, len;
+	char *buf, *lim, *next;
+	struct rt_addrinfo info;
+
+	mib[0] = CTL_NET;
+	mib[1] = PF_ROUTE;
+	mib[2] = 0;
+	mib[3] = AF_INET;
+	mib[4] = NET_RT_IFLIST;
+	mib[5] = 0;
+	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+		quit("route-sysctl-estimate");
+	if ((buf = malloc(needed)) == NULL)
+		quit("malloc");
+	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+		quit("actual retrieval of interface table");
+	lim = buf + needed;
+
+	sdl = NULL;		/* XXX just to keep gcc -Wall happy */
+	for (next = buf; next < lim; next += ifm->ifm_msglen) {
+		ifm = (struct if_msghdr *)next;
+		if (ifm->ifm_type == RTM_IFINFO) {
+			sdl = (struct sockaddr_dl *)(ifm + 1);
+			flags = ifm->ifm_flags;
+			continue;
+		}
+		if ((flags & IFF_UP) == 0 ||
+		    (flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0)
+			continue;
+		if (ifm->ifm_type != RTM_NEWADDR)
+			quit("out of sync parsing NET_RT_IFLIST");
+		ifam = (struct ifa_msghdr *)ifm;
+		info.rti_addrs = ifam->ifam_addrs;
+		rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam,
+			&info);
+		/* gag, wish we could get rid of Internet dependencies */
+#define dstaddr	info.rti_info[RTAX_BRD]
+#define IPADDR_SA(x) ((struct sockaddr_in *)(x))->sin_addr.s_addr
+#define PORT_SA(x) ((struct sockaddr_in *)(x))->sin_port
+		if (dstaddr == 0 || dstaddr->sa_family != AF_INET)
+			continue;
+		PORT_SA(dstaddr) = sp->s_port;
+		for (np = neighbors; np != NULL; np = np->n_next)
+			if (memcmp(sdl->sdl_data, np->n_name,
+				   sdl->sdl_nlen) == 0 &&
+			    IPADDR_SA(np->n_addr) == IPADDR_SA(dstaddr))
+				break;
+		if (np != NULL)
+			continue;
+		len = sizeof(*np) + dstaddr->sa_len + sdl->sdl_nlen + 1;
+		np = (struct neighbor *)malloc(len);
+		if (np == NULL)
+			quit("malloc of neighbor structure");
+		memset(np, 0, len);
+		np->n_flags = flags;
+		np->n_addr = (struct sockaddr *)(np + 1);
+		np->n_addrlen = dstaddr->sa_len;
+		np->n_name = np->n_addrlen + (char *)np->n_addr;
+		np->n_next = neighbors;
+		neighbors = np;
+		memcpy((char *)np->n_addr, (char *)dstaddr, np->n_addrlen);
+		memcpy(np->n_name, sdl->sdl_data, sdl->sdl_nlen);
+	}
+	free(buf);
+	return (1);
+}
+
+#ifdef DEBUG
+void
+Sendto(s, buf, cc, flags, to, tolen)
+	int s;
+	char *buf;
+	int cc, flags;
+	char *to;
+	int tolen;
+{
+	register struct whod *w = (struct whod *)buf;
+	register struct whoent *we;
+	struct sockaddr_in *sin = (struct sockaddr_in *)to;
+
+	printf("sendto %x.%d\n", ntohl(sin->sin_addr), ntohs(sin->sin_port));
+	printf("hostname %s %s\n", w->wd_hostname,
+	   interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), "  up"));
+	printf("load %4.2f, %4.2f, %4.2f\n",
+	    ntohl(w->wd_loadav[0]) / 100.0, ntohl(w->wd_loadav[1]) / 100.0,
+	    ntohl(w->wd_loadav[2]) / 100.0);
+	cc -= WHDRSIZE;
+	for (we = w->wd_we, cc /= sizeof(struct whoent); cc > 0; cc--, we++) {
+		time_t t = ntohl(we->we_utmp.out_time);
+		printf("%-8.8s %s:%s %.12s",
+			we->we_utmp.out_name,
+			w->wd_hostname, we->we_utmp.out_line,
+			ctime(&t)+4);
+		we->we_idle = ntohl(we->we_idle) / 60;
+		if (we->we_idle) {
+			if (we->we_idle >= 100*60)
+				we->we_idle = 100*60 - 1;
+			if (we->we_idle >= 60)
+				printf(" %2d", we->we_idle / 60);
+			else
+				printf("   ");
+			printf(":%02d", we->we_idle % 60);
+		}
+		printf("\n");
+	}
+}
+
+char *
+interval(time, updown)
+	int time;
+	char *updown;
+{
+	static char resbuf[32];
+	int days, hours, minutes;
+
+	if (time < 0 || time > 3*30*24*60*60) {
+		(void) sprintf(resbuf, "   %s ??:??", updown);
+		return (resbuf);
+	}
+	minutes = (time + 59) / 60;		/* round to minutes */
+	hours = minutes / 60; minutes %= 60;
+	days = hours / 24; hours %= 24;
+	if (days)
+		(void) sprintf(resbuf, "%s %2d+%02d:%02d",
+		    updown, days, hours, minutes);
+	else
+		(void) sprintf(resbuf, "%s    %2d:%02d",
+		    updown, hours, minutes);
+	return (resbuf);
+}
+#endif
diff --git a/slattach.tproj/Makefile b/slattach.tproj/Makefile
new file mode 100644
index 0000000..1f2fd2d
--- /dev/null
+++ b/slattach.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = slattach
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = slattach.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.dist slattach.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /sbin
+WINDOWS_INSTALLDIR = /sbin
+PDO_UNIX_INSTALLDIR = /sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/slattach.tproj/Makefile.dist b/slattach.tproj/Makefile.dist
new file mode 100644
index 0000000..0a1e759
--- /dev/null
+++ b/slattach.tproj/Makefile.dist
@@ -0,0 +1,7 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/5/93
+
+PROG=	slattach
+MAN8=	slattach.0
+MLINKS=	slattach.8 slip.8
+
+.include <bsd.prog.mk>
diff --git a/slattach.tproj/Makefile.preamble b/slattach.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/slattach.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/slattach.tproj/PB.project b/slattach.tproj/PB.project
new file mode 100644
index 0000000..df7d482
--- /dev/null
+++ b/slattach.tproj/PB.project
@@ -0,0 +1,32 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (slattach.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.dist, slattach.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_INSTALLDIR = /sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = slattach; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_INSTALLDIR = /sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_MAINNIB = slattach; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = slattach; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_INSTALLDIR = /sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_MAINNIB = slattach; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/slattach.tproj/slattach.8 b/slattach.tproj/slattach.8
new file mode 100644
index 0000000..217c481
--- /dev/null
+++ b/slattach.tproj/slattach.8
@@ -0,0 +1,90 @@
+.\" Copyright (c) 1986, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)slattach.8	8.2 (Berkeley) 4/1/94
+.\"
+.Dd April 1, 1994
+.Dt SLATTACH 8
+.Os BSD 4.3
+.Sh NAME
+.Nm slattach
+.Nd attach serial lines as network interfaces
+.Sh SYNOPSIS
+.Nm Slattach
+.Ar ttyname Op Ar baudrate
+.Sh DESCRIPTION
+.Nm Slattach
+is used to assign a tty line to a network interface,
+and to define the network source and destination addresses.
+The following operands are supported by
+.Nm slattach :
+.Bl -tag -width Ar
+.It Ar ttyname
+Specifies the name of the tty device.
+.Ar Ttyname
+should be a string of the form
+.Ql ttyXX ,
+or
+.Ql /dev/ttyXX .
+.It Ar baudrate
+Specifies the speed of the connection. If not specified, the
+default of 9600 is used.
+.El
+.Pp
+Only the super-user may attach a network interface.
+.Pp
+To detach the interface, use
+.Dq Li ifconfig interface-name down
+after killing off the
+.Nm slattach
+process.
+.Ar Interface-name
+is the name that is shown by
+.Xr netstat 1
+.Sh EXAMPLES
+.Bd -literal -offset indent -compact
+slattach ttyh8
+slattach /dev/tty01 4800
+.Ed
+.Sh DIAGNOSTICS
+Messages indicating the specified interface does not exit, the
+requested address is unknown, the user is not privileged and
+tried to alter an interface's configuration.
+.Sh SEE ALSO
+.Xr netstat 1 ,
+.Xr netintro 4 ,
+.Xr ifconfig 8 ,
+.Xr rc 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 .
diff --git a/slattach.tproj/slattach.c b/slattach.tproj/slattach.c
new file mode 100644
index 0000000..580da18
--- /dev/null
+++ b/slattach.tproj/slattach.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Adams.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sgtty.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <paths.h>
+
+#define DEFAULT_BAUD	9600
+int	slipdisc = SLIPDISC;
+
+__private_extern__
+char	devname[32] = { '\0' };
+char	hostname[MAXHOSTNAMELEN];
+
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register int fd;
+	register char *dev = argv[1];
+	struct sgttyb sgtty;
+	int	speed;
+
+	if (argc < 2 || argc > 3) {
+		fprintf(stderr, "usage: %s ttyname [baudrate]\n", argv[0]);
+		exit(1);
+	}
+	speed = argc == 3 ? findspeed(atoi(argv[2])) : findspeed(DEFAULT_BAUD);
+	if (speed == 0) {
+		fprintf(stderr, "unknown speed %s", argv[2]);
+		exit(1);
+	}
+	if (strncmp(_PATH_DEV, dev, sizeof(_PATH_DEV) - 1)) {
+		(void)snprintf(devname, sizeof(devname),
+		    "%s%s", _PATH_DEV, dev);
+		dev = devname;
+	}
+	if ((fd = open(dev, O_RDWR | O_NDELAY)) < 0) {
+		perror(dev);
+		exit(1);
+	}
+	sgtty.sg_flags = RAW | ANYP;
+	sgtty.sg_ispeed = sgtty.sg_ospeed = speed;
+	if (ioctl(fd, TIOCSETP, &sgtty) < 0) {
+		perror("ioctl(TIOCSETP)");
+		exit(1);
+	}
+	if (ioctl(fd, TIOCSETD, &slipdisc) < 0) {
+		perror("ioctl(TIOCSETD)");
+		exit(1);
+	}
+
+	if (fork() > 0)
+		exit(0);
+	for (;;)
+		sigpause(0L);
+}
+
+struct sg_spds {
+	int sp_val, sp_name;
+}       spds[] = {
+#ifdef B50
+	{ 50, B50 },
+#endif
+#ifdef B75
+	{ 75, B75 },
+#endif
+#ifdef B110
+	{ 110, B110 },
+#endif
+#ifdef B150
+	{ 150, B150 },
+#endif
+#ifdef B200
+	{ 200, B200 },
+#endif
+#ifdef B300
+	{ 300, B300 },
+#endif
+#ifdef B600
+	{ 600, B600 },
+#endif
+#ifdef B1200
+	{ 1200, B1200 },
+#endif
+#ifdef B1800
+	{ 1800, B1800 },
+#endif
+#ifdef B2000
+	{ 2000, B2000 },
+#endif
+#ifdef B2400
+	{ 2400, B2400 },
+#endif
+#ifdef B3600
+	{ 3600, B3600 },
+#endif
+#ifdef B4800
+	{ 4800, B4800 },
+#endif
+#ifdef B7200
+	{ 7200, B7200 },
+#endif
+#ifdef B9600
+	{ 9600, B9600 },
+#endif
+#ifdef EXTA
+	{ 19200, EXTA },
+#endif
+#ifdef EXTB
+	{ 38400, EXTB },
+#endif
+	{ 0, 0 }
+};
+
+findspeed(speed)
+	register int speed;
+{
+	register struct sg_spds *sp;
+
+	sp = spds;
+	while (sp->sp_val && sp->sp_val != speed)
+		sp++;
+	return (sp->sp_name);
+}
diff --git a/sliplogin.tproj/Makefile b/sliplogin.tproj/Makefile
new file mode 100644
index 0000000..b106e74
--- /dev/null
+++ b/sliplogin.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = sliplogin
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = pathnames.h
+
+CFILES = sliplogin.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble sliplogin.8\
+            slip.hosts slip.login
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/sliplogin.tproj/Makefile.postamble b/sliplogin.tproj/Makefile.postamble
new file mode 100644
index 0000000..de54c24
--- /dev/null
+++ b/sliplogin.tproj/Makefile.postamble
@@ -0,0 +1,110 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app)
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+
+
+# Change defaults assumed by the standard app makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if
+# you would like changes to them to invalidate previous builds.  The project
+# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build.
+#MAKEFILES = Makefile 
+
+# Optimization flag passed to compiler:
+#OPTIMIZATION_CFLAG = -O
+
+# Flags always passed to compiler:
+#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall  
+
+# Flags passed to compiler in normal 'app' compiles:
+#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG)
+
+# Flags passed to compiler in 'debug' compiles:
+#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG
+
+# Flags passed to compiler in 'profile' compiles
+#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Ownership and permissions of files installed by 'install' target
+INSTALL_AS_USER = root        # User to chown app to
+#INSTALL_AS_GROUP = wheel      # Group to chgrp app to 
+INSTALL_PERMISSIONS = 4555        # If set, 'install' chmod's executable to this
+
+# Options to strip for bundles, apps with bundles, and apps without bundles, 
+# respectively.
+#RELOCATABLE_STRIP_OPTS = -x -u
+#DYLD_APP_STRIP_OPTS = -A -n
+#APP_STRIP_OPTS = 
+#TOOL_STRIP_OPTS = 
+#LIBRARY_STRIP_OPTS = -x -S   # Note: -S strips debugging symbols
+# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but
+#  developers doing their own dynamic loading should set this to 
+#  $(DYLD_APP_STRIP_OPTS)).
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Typical 
+# user-defined rules are before_install and after_install (please don't 
+# redefine things like install or app, as they are owned by the top-level 
+# Makefile API), which are rules that get invoked before and after the install 
+# target runs.  Such rules should be specified with the '::' syntax rather than 
+# a single colon.
diff --git a/sliplogin.tproj/Makefile.preamble b/sliplogin.tproj/Makefile.preamble
new file mode 100644
index 0000000..2c9003c
--- /dev/null
+++ b/sliplogin.tproj/Makefile.preamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags here.  To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+
+BUNDLELDFLAGS =            # use iff project is a bundle
+PALETTELDFLAGS =           # use iff project is a palette
+
+## Specify which headers in this project should be published to the outside 
+## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be 
+## prepended by DSTROOT, below.  Any subset of these public headers can be
+## precompiled automatically after installation, with extra user-defined flags.
+PUBLIC_HEADER_DIR = 
+PUBLIC_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+## Configure what is linked in at each level here.  Libraries are only used in
+## the final 'app' linking step.  Final 'app' linking is only done via the
+## 'app', 'debug', and 'profile' targets when they are invoked for
+## the top-level app.
+
+# Additional relocatables to be linked in at this level
+OTHER_OFILES = 
+# Additional libs to link apps against ('app' target)
+#OTHER_LIBS = 
+# Additional libs to link apps against ('debug' target)
+OTHER_DEBUG_LIBS = 
+# Additional libs to link apps against ('profile' target)
+OTHER_PROF_LIBS = 
+
+# More 'app' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# More 'debug' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_DEBUG_LIBS = 
+# More 'profile' libs when $(JAPANESE) = "YES"
+OTHER_JAPANESE_PROF_LIBS = 
+
+# If this is a bundle, and you *know* the enclosing application will not
+# be linking with a library which you require in your bundle code, then
+# mention it here so that it gets linked into the bundle.  Note that this
+# is wasteful but sometimes necessary.
+BUNDLE_LIBS = 
+
+## Configure how things get built here.  Additional dependencies, sourcefiles, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+# Precompiled headers to be built before any compilation occurs (e.g., draw.p)
+PRECOMPS = 
+
+# Targets to be built before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# Set the following to "YES" if you want the old behavior of recursively
+# cleaning all nested subprojects during 'make clean'.
+CLEAN_ALL_SUBPROJECTS =
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+# To include a version string, project source must exist in a directory named
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/sliplogin.tproj/PB.project b/sliplogin.tproj/PB.project
new file mode 100644
index 0000000..04d7107
--- /dev/null
+++ b/sliplogin.tproj/PB.project
@@ -0,0 +1,48 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (pathnames.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (sliplogin.c); 
+        OTHER_SOURCES = (
+            Makefile.preamble, 
+            Makefile, 
+            Makefile.postamble, 
+            sliplogin.8, 
+            slip.hosts, 
+            slip.login
+        ); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = sliplogin; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/sliplogin.tproj/pathnames.h b/sliplogin.tproj/pathnames.h
new file mode 100644
index 0000000..3060035
--- /dev/null
+++ b/sliplogin.tproj/pathnames.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/6/93
+ */
+
+#ifndef COMPAT
+#include <paths.h>
+#else
+#define	_PATH_DEVNULL	"/dev/null"
+#endif
+
+#define	_PATH_ACCESS	"/etc/sliphome/slip.hosts"
+#define	_PATH_LOGIN	"/etc/sliphome/slip.login"
+#define	_PATH_LOGOUT	"/etc/sliphome/slip.logout"
+#define	_PATH_DEBUG	"/tmp/sliplogin.XXXXXX"
+
diff --git a/sliplogin.tproj/slip.hosts b/sliplogin.tproj/slip.hosts
new file mode 100644
index 0000000..f6ebf40
--- /dev/null
+++ b/sliplogin.tproj/slip.hosts
@@ -0,0 +1,11 @@
+#	@(#)slip.hosts	8.1 (Berkeley) 6/6/93
+#
+# login		local-addr	remote-addr	mask		opt1	opt2
+#						(normal,compress,noicmp)
+#
+Schez		vangogh		chez		0xffffff00	compress
+Sjun		vangogh		128.32.130.36	0xffffff00	normal
+Sleconte	vangogh		leconte		0xffffff00	compress
+Sleeb		vangogh		leeb		0xffffff00	compress
+Smjk		vangogh		pissaro-sl	0xffffff00	compress
+Soxford		vangogh		oxford		0xffffff00	compress
diff --git a/sliplogin.tproj/slip.login b/sliplogin.tproj/slip.login
new file mode 100644
index 0000000..3c70095
--- /dev/null
+++ b/sliplogin.tproj/slip.login
@@ -0,0 +1,12 @@
+#!/bin/sh -
+#
+#	@(#)slip.login	8.1 (Berkeley) 6/6/93
+
+#
+# generic login file for a slip line.  sliplogin invokes this with
+# the parameters:
+#      1        2         3        4          5         6     7-n
+#   slipunit ttyspeed loginname local-addr remote-addr mask opt-args
+#
+/sbin/ifconfig sl$1 inet $4 $5 netmask $6 
+exit
diff --git a/sliplogin.tproj/sliplogin.8 b/sliplogin.tproj/sliplogin.8
new file mode 100644
index 0000000..1c71988
--- /dev/null
+++ b/sliplogin.tproj/sliplogin.8
@@ -0,0 +1,220 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)sliplogin.8	8.2 (Berkeley) 1/5/94
+.\"
+.Dd January 5, 1994
+.Dt SLIPLOGIN 8
+.Os
+.Sh NAME
+.Nm sliplogin
+.Nd attach a serial line network interface
+.Sh SYNOPSIS
+.Nm sliplogin
+.Op Ar loginname
+.Sh DESCRIPTION
+.Nm Sliplogin
+is used to turn the terminal line on standard input into
+a Serial Line IP
+.Pq Tn SLIP
+link to a remote host.  To do this, the program
+searches the file
+.Pa /etc/sliphome/slip.hosts
+for an entry matching
+.Ar loginname
+(which defaults to the current login name if omitted).
+If a matching entry is found, the line is configured appropriately
+for slip (8-bit transparent i/o) and converted to
+.Tn SLIP
+line
+discipline.  Then a shell script is invoked to initialize the slip
+interface with the appropriate local and remote
+.Tn IP
+address,
+netmask, etc.
+.Pp
+The usual initialization script is
+.Pa /etc/sliphome/slip.login
+but, if particular hosts need special initialization, the file
+.Pa /etc/sliphome/slip.login. Ns Ar loginname
+will be executed instead if it exists.
+The script is invoked with the parameters
+.Bl -tag -width slipunit
+.It Em slipunit
+The unit number of the slip interface assigned to this line.  E.g.,
+.Sy 0
+for
+.Sy sl0 .
+.It Em speed
+The speed of the line.
+.It Em args
+The arguments from the
+.Pa /etc/sliphome/slip.hosts
+entry, in order starting with
+.Ar loginname .
+.El
+.Pp
+Only the super-user may attach a network interface.  The interface is
+automatically detached when the other end hangs up or the
+.Nm sliplogin
+process dies.  If the kernel slip
+module has been configured for it, all routes through that interface will
+also disappear at the same time.  If there is other processing a site
+would like done on hangup, the file
+.Pa /etc/sliphome/slip.logout
+or
+.Pa /etc/sliphome/slip.logout. Ns Ar loginname
+is executed if it exists.  It is given the same arguments as the login script.
+.Ss Format of /etc/sliphome/slip.hosts
+Comments (lines starting with a `#') and blank lines are ignored.
+Other lines must start with a
+.Ar loginname
+but the remaining arguments can be whatever is appropriate for the
+.Pa  slip.login
+file that will be executed for that name.
+Arguments are separated by white space and follow normal
+.Xr sh 1
+quoting conventions (however,
+.Ar loginname
+cannot be quoted).
+Usually, lines have the form
+.Bd -literal -offset indent
+loginname local-address remote-address netmask opt-args
+.Ed
+.Pp
+where
+.Em local-address
+and
+.Em remote-address
+are the IP host names or addresses of the local and remote ends of the
+slip line and
+.Em netmask
+is the appropriate IP netmask.  These arguments are passed
+directly to
+.Xr ifconfig 8 .
+.Em Opt-args
+are optional arguments used to configure the line.
+.Sh EXAMPLE
+The normal use of
+.Nm sliplogin
+is to create a
+.Pa /etc/passwd
+entry for each legal, remote slip site with
+.Nm sliplogin
+as the shell for that entry.  E.g.,
+.Bd -literal
+Sfoo:ikhuy6:2010:1:slip line to foo:/tmp:/usr/sbin/sliplogin
+.Ed
+.Pp
+(Our convention is to name the account used by remote host
+.Ar hostname
+as
+.Em Shostname . )
+Then an entry is added to
+.Pa slip.hosts
+that looks like:
+.Pp
+.Bd -literal -offset indent -compact
+Sfoo	`hostname`	foo	netmask
+.Ed
+.Pp
+where
+.Em `hostname`
+will be evaluated by
+.Xr sh
+to the local host name and
+.Em netmask
+is the local host IP netmask.
+.Pp
+Note that
+.Nm sliplogin
+must be setuid to root and, while not a security hole, moral defectives
+can use it to place terminal lines in an unusable state and/or deny
+access to legitimate users of a remote slip line.  To prevent this,
+a site can create a group, say
+.Em slip ,
+that only the slip login accounts are put in then make sure that
+.Pa /usr/sbin/sliplogin
+is in group
+.Em slip
+and mode 4550 (setuid root, only group
+.Em slip
+can execute binary).
+.Sh DIAGNOSTICS
+.Nm Sliplogin
+logs various information to the system log daemon,
+.Xr syslogd 8 ,
+with a facility code of
+.Em daemon .
+The messages are listed here, grouped by severity level.
+.Pp
+.Sy Error Severity
+.Bl -tag -width Ds -compact
+.It Sy ioctl (TCGETS): Em reason
+A
+.Dv TCGETS
+.Fn ioctl
+to get the line parameters failed.
+.Pp
+.It Sy ioctl (TCSETS): Em reason
+A
+.Dv TCSETS
+.Fn ioctl
+to set the line parameters failed.
+.Pp
+.It Sy /etc/sliphome/slip.hosts: Em reason
+The
+.Pa /etc/sliphome/slip.hosts
+file could not be opened.
+.Pp
+.It Sy access denied for Em user
+No entry for
+.Em user
+was found in
+.Pa /etc/sliphome/slip.hosts .
+.El
+.Pp
+.Sy Notice Severity
+.Bl -tag -width Ds -compact
+.It Sy "attaching slip unit" Em unit Sy for Ar loginname
+.Tn SLIP
+unit
+.Em unit
+was successfully attached.
+.El
+.Sh SEE ALSO
+.Xr slattach 8 ,
+.Xr syslogd 8
+.Sh HISTORY
+The
+.Nm
+command
+.Bt
diff --git a/sliplogin.tproj/sliplogin.c b/sliplogin.tproj/sliplogin.c
new file mode 100644
index 0000000..d1cdcab
--- /dev/null
+++ b/sliplogin.tproj/sliplogin.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)sliplogin.c	8.2 (Berkeley) 2/1/94";
+#endif /* not lint */
+
+/*
+ * sliplogin.c
+ * [MUST BE RUN SUID, SLOPEN DOES A SUSER()!]
+ *
+ * This program initializes its own tty port to be an async TCP/IP interface.
+ * It sets the line discipline to slip, invokes a shell script to initialize
+ * the network interface, then pauses forever waiting for hangup.
+ *
+ * It is a remote descendant of several similar programs with incestuous ties:
+ * - Kirk Smith's slipconf, modified by Richard Johnsson @ DEC WRL.
+ * - slattach, probably by Rick Adams but touched by countless hordes.
+ * - the original sliplogin for 4.2bsd, Doug Kingston the mover behind it.
+ *
+ * There are two forms of usage:
+ *
+ * "sliplogin"
+ * Invoked simply as "sliplogin", the program looks up the username
+ * in the file /etc/slip.hosts.
+ * If an entry is found, the line on fd0 is configured for SLIP operation
+ * as specified in the file.
+ *
+ * "sliplogin IPhostlogin </dev/ttyb"
+ * Invoked by root with a username, the name is looked up in the
+ * /etc/slip.hosts file and if found fd0 is configured as in case 1.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/signal.h>
+#include <sys/file.h>
+#include <sys/syslog.h>
+#include <netdb.h>
+
+#if BSD >= 199006
+#define POSIX
+#endif
+#ifdef POSIX
+#include <sys/termios.h>
+#include <sys/ioctl.h>
+#include <ttyent.h>
+#else
+#include <sgtty.h>
+#endif
+#include <net/slip.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include "pathnames.h"
+
+int	unit;
+int	speed;
+int	uid;
+char	loginargs[BUFSIZ];
+char	loginfile[MAXPATHLEN];
+char	loginname[BUFSIZ];
+
+void
+findid(name)
+	char *name;
+{
+	FILE *fp;
+	static char slopt[5][16];
+	static char laddr[16];
+	static char raddr[16];
+	static char mask[16];
+	char user[16];
+	int i, j, n;
+
+	(void)strcpy(loginname, name);
+	if ((fp = fopen(_PATH_ACCESS, "r")) == NULL) {
+		(void)fprintf(stderr, "sliplogin: %s: %s\n",
+		    _PATH_ACCESS, strerror(errno));
+		syslog(LOG_ERR, "%s: %m\n", _PATH_ACCESS);
+		exit(1);
+	}
+	while (fgets(loginargs, sizeof(loginargs) - 1, fp)) {
+		if (ferror(fp))
+			break;
+		n = sscanf(loginargs, "%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s\n",
+                        user, laddr, raddr, mask, slopt[0], slopt[1], 
+			slopt[2], slopt[3], slopt[4]);
+		if (user[0] == '#' || isspace(user[0]))
+			continue;
+		if (strcmp(user, name) != 0)
+			continue;
+
+		/*
+		 * we've found the guy we're looking for -- see if
+		 * there's a login file we can use.  First check for
+		 * one specific to this host.  If none found, try for
+		 * a generic one.
+		 */
+		(void)sprintf(loginfile, "%s.%s", _PATH_LOGIN, name);
+		if (access(loginfile, R_OK|X_OK) != 0) {
+			(void)strcpy(loginfile, _PATH_LOGIN);
+			if (access(loginfile, R_OK|X_OK)) {
+				fputs("access denied - no login file\n",
+				      stderr);
+				syslog(LOG_ERR,
+				       "access denied for %s - no %s\n",
+				       name, _PATH_LOGIN);
+				exit(5);
+			}
+		}
+
+		(void) fclose(fp);
+		return;
+	}
+	(void)fprintf(stderr, "SLIP access denied for %s\n", name);
+	syslog(LOG_ERR, "SLIP access denied for %s\n", name);
+	exit(4);
+	/* NOTREACHED */
+}
+
+char *
+sigstr(s)
+	int s;
+{
+	static char buf[32];
+
+	switch (s) {
+	case SIGHUP:	return("HUP");
+	case SIGINT:	return("INT");
+	case SIGQUIT:	return("QUIT");
+	case SIGILL:	return("ILL");
+	case SIGTRAP:	return("TRAP");
+	case SIGIOT:	return("IOT");
+	case SIGEMT:	return("EMT");
+	case SIGFPE:	return("FPE");
+	case SIGKILL:	return("KILL");
+	case SIGBUS:	return("BUS");
+	case SIGSEGV:	return("SEGV");
+	case SIGSYS:	return("SYS");
+	case SIGPIPE:	return("PIPE");
+	case SIGALRM:	return("ALRM");
+	case SIGTERM:	return("TERM");
+	case SIGURG:	return("URG");
+	case SIGSTOP:	return("STOP");
+	case SIGTSTP:	return("TSTP");
+	case SIGCONT:	return("CONT");
+	case SIGCHLD:	return("CHLD");
+	case SIGTTIN:	return("TTIN");
+	case SIGTTOU:	return("TTOU");
+	case SIGIO:	return("IO");
+	case SIGXCPU:	return("XCPU");
+	case SIGXFSZ:	return("XFSZ");
+	case SIGVTALRM:	return("VTALRM");
+	case SIGPROF:	return("PROF");
+	case SIGWINCH:	return("WINCH");
+#ifdef SIGLOST
+	case SIGLOST:	return("LOST");
+#endif
+	case SIGUSR1:	return("USR1");
+	case SIGUSR2:	return("USR2");
+	}
+	(void)sprintf(buf, "sig %d", s);
+	return(buf);
+}
+
+void
+hup_handler(s)
+	int s;
+{
+	char logoutfile[MAXPATHLEN];
+
+	(void)sprintf(logoutfile, "%s.%s", _PATH_LOGOUT, loginname);
+	if (access(logoutfile, R_OK|X_OK) != 0)
+		(void)strcpy(logoutfile, _PATH_LOGOUT);
+	if (access(logoutfile, R_OK|X_OK) == 0) {
+		char logincmd[2*MAXPATHLEN+32];
+
+		(void) sprintf(logincmd, "%s %d %d %s", logoutfile, unit, speed,
+			      loginargs);
+		(void) system(logincmd);
+	}
+	(void) close(0);
+	syslog(LOG_INFO, "closed %s slip unit %d (%s)\n", loginname, unit,
+	       sigstr(s));
+	exit(1);
+	/* NOTREACHED */
+}
+
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int fd, s, ldisc, odisc;
+	char *name;
+#ifdef POSIX
+	struct termios tios, otios;
+#else
+	struct sgttyb tty, otty;
+#endif
+	char logincmd[2*BUFSIZ+32];
+	extern uid_t getuid();
+
+	if ((name = strrchr(argv[0], '/')) == NULL)
+		name = argv[0];
+	s = getdtablesize();
+	for (fd = 3 ; fd < s ; fd++)
+		(void) close(fd);
+	openlog(name, LOG_PID, LOG_DAEMON);
+	uid = getuid();
+	if (argc > 1) {
+		findid(argv[1]);
+
+		/*
+		 * Disassociate from current controlling terminal, if any,
+		 * and ensure that the slip line is our controlling terminal.
+		 */
+#ifdef POSIX
+		if (fork() > 0)
+			exit(0);
+		if (setsid() != 0)
+			perror("setsid");
+#else
+		if ((fd = open("/dev/tty", O_RDONLY, 0)) >= 0) {
+			extern char *ttyname();
+
+			(void) ioctl(fd, TIOCNOTTY, (caddr_t)0);
+			(void) close(fd);
+			/* open slip tty again to acquire as controlling tty? */
+			fd = open(ttyname(0), O_RDWR, 0);
+			if (fd >= 0)
+				(void) close(fd);
+		}
+		(void) setpgrp(0, getpid());
+#endif
+		if (argc > 2) {
+			if ((fd = open(argv[2], O_RDWR)) == -1) {
+				perror(argv[2]);
+				exit(2);
+			}
+			(void) dup2(fd, 0);
+			if (fd > 2)
+				close(fd);
+		}
+#ifdef TIOCSCTTY
+		if (ioctl(0, TIOCSCTTY, (caddr_t)0) != 0)
+			perror("ioctl (TIOCSCTTY)");
+#endif
+	} else {
+		extern char *getlogin();
+
+		if ((name = getlogin()) == NULL) {
+			(void) fprintf(stderr, "access denied - no username\n");
+			syslog(LOG_ERR, "access denied - getlogin returned 0\n");
+			exit(1);
+		}
+		findid(name);
+	}
+	(void) fchmod(0, 0600);
+	(void) fprintf(stderr, "starting slip login for %s\n", loginname);
+#ifdef POSIX
+	/* set up the line parameters */
+	if (tcgetattr(0, &tios) < 0) {
+		syslog(LOG_ERR, "tcgetattr: %m");
+		exit(1);
+	}
+	otios = tios;
+	cfmakeraw(&tios);
+	tios.c_iflag &= ~IMAXBEL;
+	if (tcsetattr(0, TCSAFLUSH, &tios) < 0) {
+		syslog(LOG_ERR, "tcsetattr: %m");
+		exit(1);
+	}
+	speed = cfgetispeed(&tios);
+#else
+	/* set up the line parameters */
+	if (ioctl(0, TIOCGETP, (caddr_t)&tty) < 0) {
+		syslog(LOG_ERR, "ioctl (TIOCGETP): %m");
+		exit(1);
+	}
+	otty = tty;
+	speed = tty.sg_ispeed;
+	tty.sg_flags = RAW | ANYP;
+	if (ioctl(0, TIOCSETP, (caddr_t)&tty) < 0) {
+		syslog(LOG_ERR, "ioctl (TIOCSETP): %m");
+		exit(1);
+	}
+#endif
+	/* find out what ldisc we started with */
+	if (ioctl(0, TIOCGETD, (caddr_t)&odisc) < 0) {
+		syslog(LOG_ERR, "ioctl(TIOCGETD) (1): %m");
+		exit(1);
+	}
+	ldisc = SLIPDISC;
+	if (ioctl(0, TIOCSETD, (caddr_t)&ldisc) < 0) {
+		syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
+		exit(1);
+	}
+	/* find out what unit number we were assigned */
+	if (ioctl(0, SLIOCGUNIT, (caddr_t)&unit) < 0) {
+		syslog(LOG_ERR, "ioctl (SLIOCGUNIT): %m");
+		exit(1);
+	}
+	(void) signal(SIGHUP, hup_handler);
+	(void) signal(SIGTERM, hup_handler);
+
+	syslog(LOG_INFO, "attaching slip unit %d for %s\n", unit, loginname);
+	(void)sprintf(logincmd, "%s %d %d %s", loginfile, unit, speed,
+		      loginargs);
+	/*
+	 * aim stdout and errout at /dev/null so logincmd output won't
+	 * babble into the slip tty line.
+	 */
+	(void) close(1);
+	if ((fd = open(_PATH_DEVNULL, O_WRONLY)) != 1) {
+		if (fd < 0) {
+			syslog(LOG_ERR, "open /dev/null: %m");
+			exit(1);
+		}
+		(void) dup2(fd, 1);
+		(void) close(fd);
+	}
+	(void) dup2(1, 2);
+
+	/*
+	 * Run login and logout scripts as root (real and effective);
+	 * current route(8) is setuid root, and checks the real uid
+	 * to see whether changes are allowed (or just "route get").
+	 */
+	(void) setuid(0);
+	if (s = system(logincmd)) {
+		syslog(LOG_ERR, "%s login failed: exit status %d from %s",
+		       loginname, s, loginfile);
+		(void) ioctl(0, TIOCSETD, (caddr_t)&odisc);
+		exit(6);
+	}
+
+	/* twiddle thumbs until we get a signal */
+	while (1)
+		sigpause(0);
+
+	/* NOTREACHED */
+}
diff --git a/spray.tproj/Makefile b/spray.tproj/Makefile
new file mode 100644
index 0000000..ad3c8d3
--- /dev/null
+++ b/spray.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = spray
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = spray.c
+
+OTHERSRCS = Makefile Makefile.dist Makefile.postamble Makefile.preamble\
+            spray.x
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/spray.tproj/Makefile.dist b/spray.tproj/Makefile.dist
new file mode 100644
index 0000000..87c00aa
--- /dev/null
+++ b/spray.tproj/Makefile.dist
@@ -0,0 +1,7 @@
+#	$Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:58:27 wsanchez Exp $
+
+PROG=	spray
+NOMAN=
+LDADD=	-lrpcsvc
+
+.include <bsd.prog.mk>
diff --git a/spray.tproj/Makefile.postamble b/spray.tproj/Makefile.postamble
new file mode 100644
index 0000000..6e5046f
--- /dev/null
+++ b/spray.tproj/Makefile.postamble
@@ -0,0 +1,126 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
+
+%_xdr.c: %.x
+	$(RPCGEN) $(ALL_RPCFLAGS) -c -o $(SYM_DIR)/$*_xdr.c $*.x
+
diff --git a/spray.tproj/Makefile.preamble b/spray.tproj/Makefile.preamble
new file mode 100644
index 0000000..31db359
--- /dev/null
+++ b/spray.tproj/Makefile.preamble
@@ -0,0 +1,4 @@
+OTHER_OFILES = spray_xdr.o 
+OTHER_INITIAL_TARGETS = spray.h
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/spray.tproj/PB.project b/spray.tproj/PB.project
new file mode 100644
index 0000000..72b61e4
--- /dev/null
+++ b/spray.tproj/PB.project
@@ -0,0 +1,37 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (spray.c); 
+        OTHER_SOURCES = (Makefile, Makefile.dist, Makefile.postamble, Makefile.preamble, spray.x); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = spray; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/spray.tproj/spray.c b/spray.tproj/spray.c
new file mode 100644
index 0000000..72d9c3e
--- /dev/null
+++ b/spray.tproj/spray.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *	$Id: spray.c,v 1.1.1.1 1999/05/02 03:58:27 wsanchez Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <rpc/rpc.h>
+#include <rpcsvc/spray.h>
+
+#ifndef SPRAYOVERHEAD
+#define SPRAYOVERHEAD	86
+#endif
+
+void usage ();
+void print_xferstats ();
+
+/* spray buffer */
+char spray_buffer[SPRAYMAX];
+
+/* RPC timeouts */
+struct timeval NO_DEFAULT = { -1, -1 };
+struct timeval ONE_WAY = { 0, 0 };
+struct timeval TIMEOUT = { 25, 0 };
+
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	char *progname;
+	spraycumul	host_stats;
+	sprayarr	host_array;
+	CLIENT *cl;
+	int c;
+	int i;
+	int count = 0;
+	int delay = 0;
+	int length = 0;
+	double xmit_time;			/* time to receive data */
+
+	progname = *argv;
+	while ((c = getopt(argc, argv, "c:d:l:")) != -1) {
+		switch (c) {
+		case 'c':
+			count = atoi(optarg);
+			break;
+		case 'd':
+			delay = atoi(optarg);
+			break;
+		case 'l':
+			length = atoi(optarg);
+			break;
+		default:
+			usage();
+			/* NOTREACHED */
+		}
+	}
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 1) {
+		usage();
+		/* NOTREACHED */
+	}
+
+
+	/* Correct packet length. */
+	if (length > SPRAYMAX) {
+		length = SPRAYMAX;
+	} else if (length < SPRAYOVERHEAD) {
+		length = SPRAYOVERHEAD;
+	} else {
+		/* The RPC portion of the packet is a multiple of 32 bits. */
+		length -= SPRAYOVERHEAD - 3;
+		length &= ~3;
+		length += SPRAYOVERHEAD;
+	}
+
+
+	/*
+	 * The default value of count is the number of packets required
+	 * to make the total stream size 100000 bytes.
+	 */
+	if (!count) {
+		count = 100000 / length;
+	}
+
+	/* Initialize spray argument */
+	host_array.sprayarr_len = length - SPRAYOVERHEAD;
+	host_array.sprayarr_val = spray_buffer;
+	
+
+	/* create connection with server */
+	cl = clnt_create(*argv, SPRAYPROG, SPRAYVERS, "udp");
+	if (cl == NULL) {
+		clnt_pcreateerror(progname);
+		exit(1);
+	}
+
+
+	/*
+	 * For some strange reason, RPC 4.0 sets the default timeout, 
+	 * thus timeouts specified in clnt_call() are always ignored.  
+	 *
+	 * The following (undocumented) hack resets the internal state
+	 * of the client handle.
+	 */
+	clnt_control(cl, CLSET_TIMEOUT, &NO_DEFAULT);
+
+
+	/* Clear server statistics */
+	if (clnt_call(cl, SPRAYPROC_CLEAR, xdr_void, NULL, xdr_void, NULL, TIMEOUT) != RPC_SUCCESS) {
+		clnt_perror(cl, progname);
+		exit(1);
+	}
+
+
+	/* Spray server with packets */
+	printf ("sending %d packets of lnth %d to %s ...", count, length, *argv);
+	fflush (stdout);
+
+	for (i = 0; i < count; i++) {
+		clnt_call(cl, SPRAYPROC_SPRAY, xdr_sprayarr, &host_array, xdr_void, NULL, ONE_WAY);
+
+		if (delay) {
+			usleep(delay);
+		}
+	}
+
+
+	/* Collect statistics from server */
+	if (clnt_call(cl, SPRAYPROC_GET, xdr_void, NULL, xdr_spraycumul, &host_stats, TIMEOUT) != RPC_SUCCESS) {
+		clnt_perror(cl, progname);
+		exit(1);
+	}
+
+	xmit_time = host_stats.clock.sec +
+			(host_stats.clock.usec / 1000000.0);
+
+	printf ("\n\tin %.2f seconds elapsed time\n", xmit_time);
+
+
+	/* report dropped packets */
+	if (host_stats.counter != count) {
+		int packets_dropped = count - host_stats.counter;
+
+		printf("\t%d packets (%.2f%%) dropped\n",
+			packets_dropped,
+			100.0 * packets_dropped / count );
+	} else {
+		printf("\tno packets dropped\n");
+	}
+
+	printf("Sent:");
+	print_xferstats(count, length, xmit_time);
+
+	printf("Rcvd:");
+	print_xferstats(host_stats.counter, length, xmit_time);
+	
+	exit (0);
+}
+
+
+void
+print_xferstats(packets, packetlen, xfertime)
+	int packets;
+	int packetlen;
+	double xfertime;
+{
+	int datalen;
+	double pps;		/* packets per second */
+	double bps;		/* bytes per second */
+
+	datalen = packets * packetlen;
+	pps = packets / xfertime;
+	bps = datalen / xfertime;
+
+	printf("\t%.0f packets/sec, ", pps);
+
+	if (bps >= 1024) 
+		printf ("%.1fK ", bps / 1024);
+	else
+		printf ("%.0f ", bps);
+	
+	printf("bytes/sec\n");
+}
+
+
+void
+usage ()
+{
+	fprintf(stderr, "usage: spray [-c count] [-l length] [-d delay] host\n");
+	exit(1);
+}
diff --git a/spray.tproj/spray.x b/spray.tproj/spray.x
new file mode 100644
index 0000000..5d2f883
--- /dev/null
+++ b/spray.tproj/spray.x
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include <rpcsvc/spray.x>
diff --git a/startslip.tproj/Makefile b/startslip.tproj/Makefile
new file mode 100644
index 0000000..968b995
--- /dev/null
+++ b/startslip.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = startslip
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = startslip.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.dist startslip.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /sbin
+WINDOWS_INSTALLDIR = /sbin
+PDO_UNIX_INSTALLDIR = /sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/startslip.tproj/Makefile.dist b/startslip.tproj/Makefile.dist
new file mode 100644
index 0000000..14c72bc
--- /dev/null
+++ b/startslip.tproj/Makefile.dist
@@ -0,0 +1,6 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/5/93
+
+PROG=	startslip
+MAN8=	startslip.0
+
+.include <bsd.prog.mk>
diff --git a/startslip.tproj/Makefile.preamble b/startslip.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/startslip.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/startslip.tproj/PB.project b/startslip.tproj/PB.project
new file mode 100644
index 0000000..1ba4a2b
--- /dev/null
+++ b/startslip.tproj/PB.project
@@ -0,0 +1,32 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (startslip.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.dist, startslip.1); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_INSTALLDIR = /sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = startslip; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_INSTALLDIR = /sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_MAINNIB = startslip; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = startslip; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_INSTALLDIR = /sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_MAINNIB = startslip; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/startslip.tproj/startslip.1 b/startslip.tproj/startslip.1
new file mode 100644
index 0000000..f12feab
--- /dev/null
+++ b/startslip.tproj/startslip.1
@@ -0,0 +1,105 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)startslip.1	8.1 (Berkeley) 6/5/93
+.\"
+.Dd June 5, 1993
+.Dt STARTSLIP 1
+.Os BSD 4.4
+.Sh NAME
+.Nm startslip
+.Nd dial up and login to a slip server
+.Sh SYNOPSIS
+.Nm startslip
+.Op Fl d
+.Op Fl s Ar string
+.Op Fl A Ar annexname
+.Op Fl F Ar flowcontrol
+.Ar device user passwd
+.Sh DESCRIPTION
+.Nm Startslip
+opens the specified
+.Ar device .
+.Pp
+Once carrier is asserted
+.Nm startslip
+attempts to login as the specified
+.Ar user
+with the given
+.Ar password .
+If successful, it puts the device into the slip line discipline.
+If carrier drops and a
+.Dv SIGHUP
+is sent to
+.Nm startslip ,
+it closes the device and attempts to repeat the dialup and login sequence.
+.Pp
+Available options:
+.Bl -tag -width Ar
+.It Fl d
+.Nm Startslip
+prints out debugging information about what it is trying to do.
+.It Fl s Ar string
+The optional
+.Ar string
+is written to
+.Ar device .
+For a dialup modem,
+the string is used to specify a dial sequence.
+.It Fl A Ar annexname
+.Nm Startslip
+assumes it is connecting to a Xylogics Annex box and engages in an
+appropriate dialog using the
+.Ar user
+and
+.Ar passwd
+arguments.
+The
+.Ar annexname
+argument is a string that is used to match against the Annex prompt
+to determine when a connection has been established.
+.It Fl F Ar flowcontrol
+Determines the type of flow control used on
+.Ar device .
+Choices for
+.Ar flowcontrol
+are
+``none'' for no flow control (the default),
+``hw'' for hardware RTS/CTS flow control and
+``sw'' for software XON/XOFF flow control.
+.El
+.Sh SEE ALSO
+.Xr sliplogin 8
+.Sh HISTORY
+The
+.Nm startslip
+appeared in
+.Bx 4.4 .
diff --git a/startslip.tproj/startslip.c b/startslip.tproj/startslip.c
new file mode 100644
index 0000000..f424137
--- /dev/null
+++ b/startslip.tproj/startslip.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#if BSD >= 199006
+#define POSIX
+#endif
+#ifdef POSIX
+#include <sys/termios.h>
+#include <sys/ioctl.h>
+#else
+#include <sgtty.h>
+#endif
+#include <sys/socket.h>
+#include <sys/syslog.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <net/if_slvar.h>
+#include <netdb.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+
+#define DEFAULT_BAUD    B9600
+int     speed = DEFAULT_BAUD;
+#define	FC_NONE		0	/* flow control: none */
+#define	FC_SW		1	/* flow control: software (XON/XOFF) */
+#define	FC_HW		2	/* flow control: hardware (RTS/CTS) */
+int	flowcontrol = FC_NONE;
+char	*annex;
+int	hup;
+int	logged_in;
+int	wait_time = 60;		/* then back off */
+#define	MAXTRIES	6	/* w/60 sec and doubling, takes an hour */
+#define	PIDFILE		"/var/run/startslip.pid"
+
+#ifdef DEBUG
+int	debug = 1;
+#undef LOG_ERR
+#undef LOG_INFO
+#define syslog fprintf
+#define LOG_ERR stderr
+#define LOG_INFO stderr
+#else
+int	debug = 0;
+#endif
+#define	printd	if (debug) printf
+
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	extern char *optarg;
+	extern int optind;
+	char *cp, **ap;
+	int ch, disc;
+	int fd = -1;
+	void sighup();
+	FILE *wfd = NULL, *pfd;
+	char *dialerstring = 0, buf[BUFSIZ];
+	int first = 1, tries = 0;
+	int pausefirst = 0;
+	int pid;
+#ifdef POSIX
+	struct termios t;
+#else
+	struct sgttyb sgtty;
+#endif
+
+	while ((ch = getopt(argc, argv, "db:s:p:A:F:")) != EOF)
+		switch (ch) {
+		case 'd':
+			debug = 1;
+			break;
+#ifdef POSIX
+		case 'b':
+			speed = atoi(optarg);
+			break;
+#endif
+		case 'p':
+			pausefirst = atoi(optarg);
+			break;
+		case 's':
+			dialerstring = optarg;
+			break;
+		case 'A':
+			annex = optarg;
+			break;
+		case 'F':
+#ifdef POSIX
+			if (strcmp(optarg, "none") == 0)
+				flowcontrol = FC_NONE;
+			else if (strcmp(optarg, "sw") == 0)
+				flowcontrol = FC_SW;
+			else if (strcmp(optarg, "hw") == 0)
+				flowcontrol = FC_HW;
+			else {
+				(void)fprintf(stderr,
+					"flow control: none, sw, hw\n");
+				exit(1);
+			}
+			break;
+#else
+			(void)fprintf(stderr, "flow control not supported\n");
+			exit(1);
+#endif
+		case '?':
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 3)
+		usage();
+
+	openlog("startslip", LOG_PID, LOG_DAEMON);
+
+#if BSD <= 43
+	if (debug == 0 && (fd = open("/dev/tty", 0)) >= 0) {
+		ioctl(fd, TIOCNOTTY, 0);
+		close(fd);
+		fd = -1;
+	}
+#endif
+
+	if (debug)
+		setbuf(stdout, NULL);
+	
+	if (pfd = fopen(PIDFILE, "r")) {
+		pid = 0;
+		fscanf(pfd, "%d", &pid);
+		if (pid > 0)
+			kill(pid, SIGUSR1);
+		fclose(pfd);
+	}
+restart:
+	logged_in = 0;
+	if (++tries > MAXTRIES) {
+		syslog(LOG_ERR, "exiting after %d tries\n", tries);
+		/* ???
+		if (first)
+		*/
+			exit(1);
+	}
+
+	/*
+	 * We may get a HUP below, when the parent (session leader/
+	 * controlling process) exits; ignore HUP until into new session.
+	 */
+	signal(SIGHUP, SIG_IGN);
+	hup = 0;
+	if (fork() > 0) {
+		if (pausefirst)
+			sleep(pausefirst);
+		if (first)
+			printd("parent exit\n");
+		exit(0);
+	}
+	pausefirst = 0;
+#ifdef POSIX
+	if (setsid() == -1)
+		perror("setsid");
+#endif
+	pid = getpid();
+	printd("restart: pid %d: ", pid);
+	if (pfd = fopen(PIDFILE, "w")) {
+		fprintf(pfd, "%d\n", pid);
+		fclose(pfd);
+	}
+	if (wfd) {
+		printd("fclose, ");
+		fclose(wfd);
+		wfd == NULL;
+	}
+	if (fd >= 0) {
+		printd("close, ");
+		close(fd);
+		sleep(5);
+	}
+	printd("open");
+	if ((fd = open(argv[0], O_RDWR)) < 0) {
+		perror(argv[0]);
+		syslog(LOG_ERR, "open %s: %m\n", argv[0]);
+		if (first)
+			exit(1);
+		else {
+			sleep(wait_time * tries);
+			goto restart;
+		}
+	}
+	printd(" %d", fd);
+#ifdef TIOCSCTTY
+	if (ioctl(fd, TIOCSCTTY, 0) < 0)
+		perror("ioctl (TIOCSCTTY)");
+#endif
+	signal(SIGHUP, sighup);
+	if (debug) {
+		if (ioctl(fd, TIOCGETD, &disc) < 0)
+			perror("ioctl(TIOCSETD)");
+		printf(" (disc was %d)", disc);
+	}
+	disc = TTYDISC;
+	if (ioctl(fd, TIOCSETD, &disc) < 0) {
+	        perror("ioctl(TIOCSETD)");
+		syslog(LOG_ERR, "%s: ioctl (TIOCSETD 0): %m\n",
+		    argv[0]);
+	}
+	printd(", ioctl");
+#ifdef POSIX
+	if (tcgetattr(fd, &t) < 0) {
+		perror("tcgetattr");
+		syslog(LOG_ERR, "%s: tcgetattr: %m\n", argv[0]);
+	        exit(2);
+	}
+	cfmakeraw(&t);
+	t.c_iflag &= ~IMAXBEL;
+	switch (flowcontrol) {
+	case FC_HW:
+		t.c_cflag |= (CRTS_IFLOW|CCTS_OFLOW);
+		break;
+	case FC_SW:
+		t.c_iflag |= (IXON|IXOFF);
+		break;
+	case FC_NONE:
+		t.c_cflag &= ~(CRTS_IFLOW|CCTS_OFLOW);
+		t.c_iflag &= ~(IXON|IXOFF);
+		break;
+	}
+	cfsetspeed(&t, speed);
+	if (tcsetattr(fd, TCSAFLUSH, &t) < 0) {
+		perror("tcsetattr");
+		syslog(LOG_ERR, "%s: tcsetattr: %m\n", argv[0]);
+	        if (first) 
+			exit(2);
+		else {
+			sleep(wait_time * tries);
+			goto restart;
+		}
+	}
+#else
+	if (ioctl(fd, TIOCGETP, &sgtty) < 0) {
+	        perror("ioctl (TIOCGETP)");
+		syslog(LOG_ERR, "%s: ioctl (TIOCGETP): %m\n",
+		    argv[0]);
+	        exit(2);
+	}
+	sgtty.sg_flags = RAW | ANYP;
+	sgtty.sg_erase = sgtty.sg_kill = 0377;
+	sgtty.sg_ispeed = sgtty.sg_ospeed = speed;
+	if (ioctl(fd, TIOCSETP, &sgtty) < 0) {
+	        perror("ioctl (TIOCSETP)");
+		syslog(LOG_ERR, "%s: ioctl (TIOCSETP): %m\n",
+		    argv[0]);
+	        if (first) 
+			exit(2);
+		else {
+			sleep(wait_time * tries);
+			goto restart;
+		}
+	}
+#endif
+	sleep(2);		/* wait for flakey line to settle */
+	if (hup)
+		goto restart;
+
+	wfd = fdopen(fd, "w+");
+	if (wfd == NULL) {
+		syslog(LOG_ERR, "can't fdopen slip line\n");
+		exit(10);
+	}
+	setbuf(wfd, (char *)0);
+	if (dialerstring) {
+		printd(", send dialstring");
+		fprintf(wfd, "%s\r", dialerstring);
+	} else
+		putc('\r', wfd);
+	printd("\n");
+
+	/*
+	 * Log in
+	 */
+	printd("look for login: ");
+	for (;;) {
+		if (getline(buf, BUFSIZ, fd) == 0 || hup) {
+			sleep(wait_time * tries);
+			goto restart;
+		}
+		if (annex) {
+			if (bcmp(buf, annex, strlen(annex)) == 0) {
+				fprintf(wfd, "slip\r");
+				printd("Sent \"slip\"\n");
+				continue;
+			}
+			if (bcmp(&buf[1], "sername:", 8) == 0) {
+				fprintf(wfd, "%s\r", argv[1]);
+				printd("Sent login: %s\n", argv[1]);
+				continue;
+			}
+			if (bcmp(&buf[1], "assword:", 8) == 0) {
+				fprintf(wfd, "%s\r", argv[2]);
+				printd("Sent password: %s\n", argv[2]);
+				break;
+			}
+		} else {
+			if (bcmp(&buf[1], "ogin:", 5) == 0) {
+				fprintf(wfd, "%s\r", argv[1]);
+				printd("Sent login: %s\n", argv[1]);
+				continue;
+			}
+			if (bcmp(&buf[1], "assword:", 8) == 0) {
+				fprintf(wfd, "%s\r", argv[2]);
+				printd("Sent password: %s\n", argv[2]);
+				break;
+			}
+		}
+	}
+	
+	/*
+	 * Security hack.  Do not want private information such as the
+	 * password and possible phone number to be left around.
+	 * So we clobber the arguments.
+	 */
+	for (ap = argv - optind + 1; ap < argv + 3; ap++)
+		for (cp = *ap; *cp != 0; cp++)
+			*cp = '\0';
+
+	/*
+	 * Attach
+	 */
+	printd("setd");
+	disc = SLIPDISC;
+	if (ioctl(fd, TIOCSETD, &disc) < 0) {
+	        perror("ioctl(TIOCSETD)");
+		syslog(LOG_ERR, "%s: ioctl (TIOCSETD SLIP): %m\n",
+		    argv[0]);
+	        exit(1);
+	}
+	if (first && debug == 0) {
+		close(0);
+		close(1);
+		close(2);
+		(void) open("/dev/null", O_RDWR);
+		(void) dup2(0, 1);
+		(void) dup2(0, 2);
+	}
+	(void) system("ifconfig sl0 up");
+	printd(", ready\n");
+	if (!first)
+		syslog(LOG_INFO, "reconnected (%d tries).\n", tries);
+	first = 0;
+	tries = 0;
+	logged_in = 1;
+	while (hup == 0) {
+		sigpause(0L);
+		printd("sigpause return\n");
+	}
+	goto restart;
+}
+
+void
+sighup()
+{
+
+	printd("hup\n");
+	if (hup == 0 && logged_in)
+		syslog(LOG_INFO, "hangup signal\n");
+	hup = 1;
+}
+
+getline(buf, size, fd)
+	char *buf;
+	int size, fd;
+{
+	register int i;
+	int ret;
+
+	size--;
+	for (i = 0; i < size; i++) {
+		if (hup)
+			return (0);
+	        if ((ret = read(fd, &buf[i], 1)) == 1) {
+	                buf[i] &= 0177;
+	                if (buf[i] == '\r' || buf[i] == '\0')
+	                        buf[i] = '\n';
+	                if (buf[i] != '\n' && buf[i] != ':')
+	                        continue;
+	                buf[i + 1] = '\0';
+			printd("Got %d: \"%s\"\n", i + 1, buf);
+	                return (i+1);
+	        }
+		if (ret <= 0) {
+			if (ret < 0)
+				perror("getline: read");
+			else
+				fprintf(stderr, "read returned 0\n");
+			buf[i] = '\0';
+			printd("returning 0 after %d: \"%s\"\n", i, buf);
+			return (0);
+		}
+	}
+	return (0);
+}
+
+usage()
+{
+	(void)fprintf(stderr,
+	    "usage: startslip [-d] [-b speed] [-s string] [-A annexname] [-F flowcontrol] dev user passwd\n");
+	exit(1);
+}
diff --git a/stdethers.tproj/Makefile b/stdethers.tproj/Makefile
new file mode 100644
index 0000000..3ee9c9a
--- /dev/null
+++ b/stdethers.tproj/Makefile
@@ -0,0 +1,46 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = stdethers
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = stdethers.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble stdethers.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/stdethers.tproj/Makefile.postamble b/stdethers.tproj/Makefile.postamble
new file mode 100644
index 0000000..509e7f5
--- /dev/null
+++ b/stdethers.tproj/Makefile.postamble
@@ -0,0 +1,101 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGE: langage in which the project is written (default "English")
+#  LOCAL_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/stdethers.tproj/Makefile.preamble b/stdethers.tproj/Makefile.preamble
new file mode 100644
index 0000000..83f25c7
--- /dev/null
+++ b/stdethers.tproj/Makefile.preamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. <<default?>>
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSION: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
diff --git a/stdethers.tproj/PB.project b/stdethers.tproj/PB.project
new file mode 100644
index 0000000..6379be0
--- /dev/null
+++ b/stdethers.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (stdethers.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, stdethers.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = stdethers; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/stdethers.tproj/stdethers.8 b/stdethers.tproj/stdethers.8
new file mode 100644
index 0000000..3740af7
--- /dev/null
+++ b/stdethers.tproj/stdethers.8
@@ -0,0 +1,55 @@
+.\"	$OpenBSD: stdethers.8,v 1.3 1996/05/30 09:53:11 deraadt Exp $
+.\" Copyright (c) 1995 Mats O Jansson <moj@stacken.kth.se>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"      This product includes software developed by Mats O Jansson
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd December 2, 1995
+.Dt STDETHERS 8
+.Os
+.Sh NAME
+.Nm stdethers
+.Nd a YP filter program
+.Sh SYNOPSIS
+.Nm stdethers
+.Op Ar file
+.Sh DESCRIPTION
+.Nm Stdethers
+is used to get ride of some unwanted information in file or stdin. This
+program is used by YP when creating some YP maps.
+.Pp
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Ar file
+Use this file as input instead of stdin.
+.El
+.Sh SEE ALSO
+.Xr yp 8 ,
+.Xr ypserv 8 
+.Sh AUTHOR
+Mats O Jansson <moj@stacken.kth.se>
diff --git a/stdethers.tproj/stdethers.c b/stdethers.tproj/stdethers.c
new file mode 100644
index 0000000..f9ef339
--- /dev/null
+++ b/stdethers.tproj/stdethers.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: stdethers.c,v 1.3 1997/09/11 19:47:33 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1995 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: stdethers.c,v 1.3 1997/09/11 19:47:33 deraadt Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+char *ProgramName = "stdethers";
+
+extern int   ether_line(char *, struct ether_addr *, char *);
+extern char *ether_ntoa(struct ether_addr *);
+
+#ifndef NTOA_FIX
+#define	NTOA(x) (char *)ether_ntoa(x)
+#else
+#define NTOA(x) (char *) working_ntoa((u_char *) x)
+
+/* As of 1995-12-02 NetBSD and OpenBSD has an SunOS 4 incompatible ether_ntoa.
+   The code in usr/lib/libc/net/ethers seems to do the correct thing
+   when asking YP but not when returning string from ether_ntoa.
+ */
+
+char *
+working_ntoa(e)
+	u_char	*e;
+{
+	static char a[] = "xx:xx:xx:xx:xx:xx";
+
+	sprintf(a, "%x:%x:%x:%x:%x:%x",
+		e[0], e[1], e[2], e[3], e[4], e[5]);
+	return a;
+}
+#endif
+
+static int read_line(fp, buf, size)
+FILE *fp;
+char *buf;
+int size;
+{
+	int done = 0;
+
+	do {
+		while (fgets(buf, size, fp)) {
+			int len = strlen(buf);
+			done += len;
+			if (len > 1 && buf[len-2] == '\\' &&
+					buf[len-1] == '\n') {
+				int ch;
+				buf += len - 2;
+				size -= len - 2;
+				*buf = '\n'; buf[1] = '\0';
+				/*
+				 * Skip leading white space on next line
+				 */
+				while ((ch = getc(fp)) != EOF &&
+					isascii(ch) && isspace(ch))
+						;
+				(void) ungetc(ch, fp);
+			} else {
+				return done;
+			}
+		}
+	} while (size > 0 && !feof(fp));
+
+	return done;
+}
+
+int
+main (argc,argv)
+int argc;
+char *argv[];
+{
+	FILE	*data_file;
+	char	 data_line[1024];
+	int	 usage = 0;
+	int	 line_no = 0;
+	int	 len;
+	char	*p,*k,*v;
+	struct ether_addr eth_addr;
+	char	 hostname[256];
+	
+	if (argc > 2) {
+		usage++;
+	}
+	
+	if (usage) {
+		fprintf(stderr,
+			"usage: %s [file]\n",
+			ProgramName);
+		exit(1);
+	}
+	
+	if (argc == 2) {
+		data_file = fopen(argv[1], "r");
+		if (data_file == NULL) {
+			fprintf(stderr,
+				"%s: can't open %s\n",
+				ProgramName,
+				argv[1]);
+			exit(1);
+		}
+	} else {
+		data_file = stdin;
+	}
+	
+	while (read_line(data_file,data_line,sizeof(data_line))) {
+		
+		line_no++;
+		len = strlen(data_line);
+		
+		if (len > 0) {
+			if (data_line[0] == '#')
+				continue;
+		}
+		
+		/*
+		 * Check if we have the whole line
+		 */ 
+		
+		if (data_line[len-1] != '\n') {
+			if (argc == 2) {
+				fprintf(stderr,
+					"line %d in \"%s\" is too long",
+					line_no, argv[1]);
+			} else {
+				fprintf(stderr,
+					"line %d in \"stdin\" is too long",
+					line_no);
+			}
+		} else {
+			data_line[len-1] = '\0';
+		}
+		
+		p = (char *) &data_line;
+		
+		k  = p;				/* save start of key */
+		while (!isspace(*p)) { p++; };	/* find first "space" */
+		while (isspace(*p)) { p++; };	/* move over "space" */
+		
+		v = p;				/* save start of value */
+		while(*p != '\0') { p++; };	/* find end of string */
+		
+		if (ether_line(data_line, &eth_addr, hostname) == 0) {
+			fprintf(stdout, "%s\t%s\n",
+				NTOA(&eth_addr),
+				hostname);
+		} else {
+			fprintf(stderr,
+				"%s: ignoring line %d: \"%s\"\n",
+				ProgramName,
+				line_no,
+				data_line);
+		}
+	}
+	
+	return(0);
+	
+}
diff --git a/stdhosts.tproj/Makefile b/stdhosts.tproj/Makefile
new file mode 100644
index 0000000..600fddf
--- /dev/null
+++ b/stdhosts.tproj/Makefile
@@ -0,0 +1,46 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = stdhosts
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = stdhosts.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble stdhosts.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/stdhosts.tproj/Makefile.postamble b/stdhosts.tproj/Makefile.postamble
new file mode 100644
index 0000000..509e7f5
--- /dev/null
+++ b/stdhosts.tproj/Makefile.postamble
@@ -0,0 +1,101 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGE: langage in which the project is written (default "English")
+#  LOCAL_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/stdhosts.tproj/Makefile.preamble b/stdhosts.tproj/Makefile.preamble
new file mode 100644
index 0000000..83f25c7
--- /dev/null
+++ b/stdhosts.tproj/Makefile.preamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. <<default?>>
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSION: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
diff --git a/stdhosts.tproj/PB.project b/stdhosts.tproj/PB.project
new file mode 100644
index 0000000..ba79c4b
--- /dev/null
+++ b/stdhosts.tproj/PB.project
@@ -0,0 +1,26 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_LINKED = (stdhosts.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, stdhosts.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = stdhosts; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/stdhosts.tproj/stdhosts.8 b/stdhosts.tproj/stdhosts.8
new file mode 100644
index 0000000..6cd5540
--- /dev/null
+++ b/stdhosts.tproj/stdhosts.8
@@ -0,0 +1,55 @@
+.\"	$OpenBSD: stdhosts.8,v 1.4 1996/06/26 21:26:36 maja Exp $
+.\" Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by Mats O Jansson
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd August 25, 1994
+.Dt STDHOSTS 8
+.Os
+.Sh NAME
+.Nm stdhosts
+.Nd a YP filter program
+.Sh SYNOPSIS
+.Nm stdhosts
+.Op Ar file
+.Sh DESCRIPTION
+.Nm Stdhosts
+is used to get ride of some unwanted information in file or stdin. This
+program is used by YP when creating some YP maps.
+.Pp
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Ar file
+Use this file as input instead of stdin.
+.El
+.Sh SEE ALSO
+.Xr yp 8 ,
+.Xr ypserv 8 
+.Sh AUTHOR
+Mats O Jansson <moj@stacken.kth.se>
diff --git a/stdhosts.tproj/stdhosts.c b/stdhosts.tproj/stdhosts.c
new file mode 100644
index 0000000..3406558
--- /dev/null
+++ b/stdhosts.tproj/stdhosts.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: stdhosts.c,v 1.4 1997/09/11 19:47:35 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: stdhosts.c,v 1.4 1997/09/11 19:47:35 deraadt Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+static int read_line(fp, buf, size)
+FILE *fp;
+char *buf;
+int size;
+{
+	int done = 0;
+
+	do {
+		while (fgets(buf, size, fp)) {
+			int len = strlen(buf);
+			done += len;
+			if (len > 1 && buf[len-2] == '\\' &&
+					buf[len-1] == '\n') {
+				int ch;
+				buf += len - 2;
+				size -= len - 2;
+				*buf = '\n'; buf[1] = '\0';
+				/*
+				 * Skip leading white space on next line
+				 */
+				while ((ch = getc(fp)) != EOF &&
+					isascii(ch) && isspace(ch))
+						;
+				(void) ungetc(ch, fp);
+			} else {
+				return done;
+			}
+		}
+	} while (size > 0 && !feof(fp));
+
+	return done;
+}
+
+int
+main (argc,argv)
+int argc;
+char *argv[];
+{
+  FILE	*data_file;
+  char	 data_line[1024];
+  int	 usage = 0;
+  int	 line_no = 0;
+  int	 len;
+  char	*p,*k,*v;
+  struct in_addr host_addr;
+
+  if (argc > 2) {
+    usage++;
+  }
+
+  if (usage) {
+    fprintf(stderr,
+	    "%s",
+	    "usage: stdhosts [file]\n");
+    exit(1);
+  }
+
+  if (argc == 2) {
+    data_file = fopen(argv[argc-1], "r");
+  } else {
+    data_file = stdin;
+  }
+  
+  while (read_line(data_file,data_line,sizeof(data_line))) {
+    
+    line_no++;
+    len = strlen(data_line);
+    
+    if (len > 0) {
+      if (data_line[0] == '#')
+	continue;
+    }
+
+    /*
+     * Check if we have the whole line
+     */ 
+
+    if (data_line[len-1] != '\n') {
+      if (argc == 2) {
+	fprintf(stderr, "line %d in \"%s\" is too long", line_no, argv[1]);
+      } else {
+	fprintf(stderr, "line %d in \"stdin\" is too long", line_no);
+      }
+    } else {
+      data_line[len-1] = '\0';
+    }
+
+    p = (char *) &data_line;
+
+    k  = p;					/* save start of key */
+    while (!isspace(*p)) { p++; };		/* find first "space" */
+    while (isspace(*p)) { *p = '\0'; p++; };	/* replace space with <NUL> */
+    
+    v = p;					/* save start of value */
+    while(*p != '\0') { p++; };			/* find end of string */
+
+    (void)inet_aton(k,&host_addr);
+    printf("%s %s\n",inet_ntoa(host_addr),v);
+
+  }
+
+  return(0);
+  
+}
diff --git a/syslogd.tproj/Makefile b/syslogd.tproj/Makefile
new file mode 100644
index 0000000..9eae816
--- /dev/null
+++ b/syslogd.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = syslogd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = pathnames.h
+
+CFILES = syslogd.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble syslogd.8\
+            syslog.conf.5
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/syslogd.tproj/Makefile.postamble b/syslogd.tproj/Makefile.postamble
new file mode 100644
index 0000000..60da20d
--- /dev/null
+++ b/syslogd.tproj/Makefile.postamble
@@ -0,0 +1,111 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app)
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+
+
+# Change defaults assumed by the standard app makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if
+# you would like changes to them to invalidate previous builds.  The project
+# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build.
+#MAKEFILES = Makefile 
+
+# Optimization flag passed to compiler:
+#OPTIMIZATION_CFLAG = -O
+
+# Flags always passed to compiler:
+#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall  
+
+# Flags passed to compiler in normal 'app' compiles:
+#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG)
+
+# Flags passed to compiler in 'debug' compiles:
+#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG
+
+# Flags passed to compiler in 'profile' compiles
+#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User to chown app to
+#INSTALL_AS_GROUP = wheel      # Group to chgrp app to 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for bundles, apps with bundles, and apps without bundles, 
+# respectively.
+#RELOCATABLE_STRIP_OPTS = -x -u
+#DYLD_APP_STRIP_OPTS = -A -n
+#APP_STRIP_OPTS = 
+#TOOL_STRIP_OPTS = 
+#LIBRARY_STRIP_OPTS = -x -S   # Note: -S strips debugging symbols
+# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but
+#  developers doing their own dynamic loading should set this to 
+#  $(DYLD_APP_STRIP_OPTS)).
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Typical 
+# user-defined rules are before_install and after_install (please don't 
+# redefine things like install or app, as they are owned by the top-level 
+# Makefile API), which are rules that get invoked before and after the install 
+# target runs.  Such rules should be specified with the '::' syntax rather than 
+# a single colon.
+VPATH += :../wall.tproj
diff --git a/syslogd.tproj/Makefile.preamble b/syslogd.tproj/Makefile.preamble
new file mode 100644
index 0000000..d2e854c
--- /dev/null
+++ b/syslogd.tproj/Makefile.preamble
@@ -0,0 +1,115 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags here.  To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =
+
+BUNDLELDFLAGS =            # use iff project is a bundle
+PALETTELDFLAGS =           # use iff project is a palette
+
+## Specify which headers in this project should be published to the outside 
+## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be 
+## prepended by DSTROOT, below.  Any subset of these public headers can be
+## precompiled automatically after installation, with extra user-defined flags.
+PUBLIC_HEADER_DIR = 
+PUBLIC_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+## Configure what is linked in at each level here.  Libraries are only used in
+## the final 'app' linking step.  Final 'app' linking is only done via the
+## 'app', 'debug', and 'profile' targets when they are invoked for
+## the top-level app.
+
+# Additional libs to link apps against ('app' target)
+#OTHER_LIBS = 
+# Additional libs to link apps against ('debug' target)
+OTHER_DEBUG_LIBS = 
+# Additional libs to link apps against ('profile' target)
+OTHER_PROF_LIBS = 
+
+# More 'app' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# More 'debug' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_DEBUG_LIBS = 
+# More 'profile' libs when $(JAPANESE) = "YES"
+OTHER_JAPANESE_PROF_LIBS = 
+
+# If this is a bundle, and you *know* the enclosing application will not
+# be linking with a library which you require in your bundle code, then
+# mention it here so that it gets linked into the bundle.  Note that this
+# is wasteful but sometimes necessary.
+BUNDLE_LIBS = 
+
+## Configure how things get built here.  Additional dependencies, sourcefiles, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+# Precompiled headers to be built before any compilation occurs (e.g., draw.p)
+PRECOMPS = 
+
+# Targets to be built before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# Set the following to "YES" if you want the old behavior of recursively
+# cleaning all nested subprojects during 'make clean'.
+CLEAN_ALL_SUBPROJECTS =
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+# To include a version string, project source must exist in a directory named
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+OTHER_OFILES = ttymsg.o
+
+-include ../Makefile.include
diff --git a/syslogd.tproj/PB.project b/syslogd.tproj/PB.project
new file mode 100644
index 0000000..45a56f3
--- /dev/null
+++ b/syslogd.tproj/PB.project
@@ -0,0 +1,41 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (pathnames.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (syslogd.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, syslogd.8, syslog.conf.5); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = syslogd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/syslogd.tproj/pathnames.h b/syslogd.tproj/pathnames.h
new file mode 100644
index 0000000..b03e65d
--- /dev/null
+++ b/syslogd.tproj/pathnames.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/6/93
+ */
+
+#include <paths.h>
+
+#define	_PATH_KLOG	"/dev/klog"
+#define	_PATH_LOGCONF	"/etc/syslog.conf"
+#define	_PATH_LOGPID	"/var/run/syslog.pid"
diff --git a/syslogd.tproj/syslog.conf.5 b/syslogd.tproj/syslog.conf.5
new file mode 100644
index 0000000..b19e75d
--- /dev/null
+++ b/syslogd.tproj/syslog.conf.5
@@ -0,0 +1,224 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)syslog.conf.5	8.1 (Berkeley) 6/9/93
+.\"
+.Dd June 9, 1993
+.Dt SYSLOG.CONF 5
+.Os
+.Sh NAME
+.Nm syslog.conf
+.Nd
+.Xr syslogd 8
+configuration file
+.Sh DESCRIPTION
+The
+.Nm syslog.conf
+file is the configuration file for the
+.Xr syslogd 8
+program.
+It consists of lines with two fields: the
+.Em selector
+field which specifies the types of messages and priorities to which the
+line applies, and an
+.Em action
+field which specifies the action to be taken if a message
+.Xr syslogd
+receives matches the selection criteria.
+The
+.Em selector
+field is separated from the
+.Em action
+field by one or more tab characters.
+.Pp
+The
+.Em Selectors
+function
+are encoded as a
+.Em facility ,
+a period (``.''), and a
+.Em level ,
+with no intervening white-space.
+Both the
+.Em facility
+and the
+.Em level
+are case insensitive.
+.Pp
+The
+.Em facility
+describes the part of the system generating the message, and is one of
+the following keywords: auth, authpriv, cron, daemon, kern, lpr, mail,
+mark, news, syslog, user, uucp and local0 through local7.
+These keywords (with the exception of mark) correspond to the
+similar
+.Dq Dv LOG_
+values specified to the
+.Xr openlog 3
+and
+.Xr syslog 3
+library routines.
+.Pp
+The
+.Em level
+describes the severity of the message, and is a keyword from the
+following ordered list (higher to lower): emerg, alert, crit, err,
+warning, notice and debug.
+These keywords correspond to the
+similar
+.Pq Dv LOG_
+values specified to the
+.Xr syslog
+library routine.
+.Pp
+See
+.Xr syslog 3
+for a further descriptions of both the
+.Em facility
+and
+.Em level
+keywords and their significance.
+.Pp
+If a received message matches the specified
+.Em facility
+and is of the specified
+.Em level
+.Em (or a higher level) ,
+the action specified in the
+.Em action
+field will be taken.
+.Pp
+Multiple
+.Em selectors
+may be specified for a single
+.Em action
+by separating them with semicolon (``;'') characters.
+It is important to note, however, that each
+.Em selector
+can modify the ones preceding it.
+.Pp
+Multiple
+.Em facilities
+may be specified for a single
+.Em level
+by separating them with comma (``,'') characters.
+.Pp
+An asterisk (``*'') can be used to specify all
+.Em facilities
+or all
+.Em levels .
+.Pp
+The special
+.Em facility
+``mark'' receives a message at priority ``info'' every 20 minutes
+(see
+.Xr syslogd 8 ) .
+This is not enabled by a
+.Em facility
+field containing an asterisk.
+.Pp
+The special
+.Em level
+``none'' disables a particular
+.Em facility .
+.Pp
+The
+.Em action
+field of each line specifies the action to be taken when the
+.Em selector
+field selects a message.
+There are four forms:
+.Bl -bullet
+.It
+A pathname (beginning with a leading slash).
+Selected messages are appended to the file.
+.It
+A hostname (preceded by an at (``@'') sign).
+Selected messages are forwarded to the
+.Xr syslogd
+program on the named host.
+.It
+A comma separated list of users.
+Selected messages are written to those users
+if they are logged in.
+.It
+An asterisk.
+Selected messages are written to all logged-in users.
+.El
+.Pp
+Blank lines and lines whose first non-blank character is a hash (``#'')
+character are ignored.
+.Sh EXAMPLES
+.Pp
+A configuration file might appear as follows:
+.Bd -literal
+# Log all kernel messages, authentication messages of
+# level notice or higher and anything of level err or
+# higher to the console.
+# Don't log private authentication messages!
+*.err;kern.*;auth.notice;authpriv.none	/dev/console
+
+# Log anything (except mail) of level info or higher.
+# Don't log private authentication messages!
+*.info;mail.none;authpriv.none		/var/log/messages
+
+# The authpriv file has restricted access.
+authpriv.*						/var/log/secure
+
+# Log all the mail messages in one place.
+mail.*							/var/log/maillog
+
+# Everybody gets emergency messages, plus log them on another
+# machine.
+*.emerg							*
+*.emerg							@arpa.berkeley.edu
+
+# Root and Eric get alert and higher messages.
+*.alert							root,eric
+
+# Save mail and news errors of level err and higher in a
+# special file.
+uucp,news.crit						/var/log/spoolerr
+.Ed
+.Sh FILES
+.Bl -tag -width /etc/syslog.conf -compact
+.It Pa /etc/syslog.conf
+The
+.Xr syslogd 8
+configuration file.
+.El
+.Sh BUGS
+The effects of multiple selectors are sometimes not intuitive.
+For example ``mail.crit,*.err'' will select ``mail'' facility messages at
+the level of ``err'' or higher, not at the level of ``crit'' or higher.
+.Sh SEE ALSO
+.Xr syslog 3 ,
+.Xr syslogd 8
diff --git a/syslogd.tproj/syslogd.8 b/syslogd.tproj/syslogd.8
new file mode 100644
index 0000000..f16297b
--- /dev/null
+++ b/syslogd.tproj/syslogd.8
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1983, 1986, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)syslogd.8	8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt SYSLOGD 8
+.Os BSD 4.2
+.Sh NAME
+.Nm syslogd
+.Nd log systems messages
+.Sh SYNOPSIS
+.Nm syslogd
+.Op Fl f Ar config_file
+.Op Fl m Ar mark_interval
+.Op Fl p Ar log_socket
+.Sh DESCRIPTION
+.Nm Syslogd
+reads and logs messages to the system console, log files, other
+machines and/or users as specified by its configuration file.
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl f
+Specify the pathname of an alternate configuration file;
+the default is
+.Pa /etc/syslog.conf .
+.It Fl m
+Select the number of minutes between ``mark'' messages;
+the default is 20 minutes.
+.It Fl p
+Specify the pathname of an alternate log socket;
+the default is
+.Pa /var/run/syslog .
+.El
+.Pp
+.Nm Syslogd
+reads its configuration file when it starts up and whenever it
+receives a hangup signal.
+For information on the format of the configuration file,
+see
+.Xr syslog.conf 5 .
+.Pp
+.Nm Syslogd
+reads messages from the
+.Tn UNIX
+domain socket
+.Pa /var/run/syslog ,
+from an Internet domain socket specified in
+.Pa /etc/services ,
+and from the special device
+.Pa /dev/klog
+(to read kernel messages).
+.Pp
+.Nm Syslogd
+creates the file
+.Pa /var/run/syslog.pid ,
+and stores its process
+id there.
+This can be used to kill or reconfigure
+.Nm syslogd .
+.Pp
+The message sent to
+.Nm syslogd
+should consist of a single line.
+The message can contain a priority code, which should be a preceding
+decimal number in angle braces, for example,
+.Sq Aq 5.
+This priority code should map into the priorities defined in the
+include file
+.Aq Pa sys/syslog.h .
+.Sh FILES
+.Bl -tag -width /var/run/syslog.pid -compact
+.It Pa /etc/syslog.conf
+The configuration file.
+.It Pa /var/run/syslog.pid
+The process id of current
+.Nm syslogd .
+.It Pa /var/run/syslog
+Name of the
+.Tn UNIX
+domain datagram log socket.
+.It Pa /dev/klog
+The kernel log device.
+.El
+.Sh SEE ALSO
+.Xr logger 1 ,
+.Xr syslog 3 ,
+.Xr services 5 ,
+.Xr syslog.conf 5
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 .
diff --git a/syslogd.tproj/syslogd.c b/syslogd.tproj/syslogd.c
new file mode 100644
index 0000000..27cb99b
--- /dev/null
+++ b/syslogd.tproj/syslogd.c
@@ -0,0 +1,1162 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1988, 1993, 1994\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)syslogd.c	8.3 (Berkeley) 4/4/94";
+#endif /* not lint */
+
+/*
+ *  syslogd -- log system messages
+ *
+ * This program implements a system log. It takes a series of lines.
+ * Each line may have a priority, signified as "<n>" as
+ * the first characters of the line.  If this is
+ * not present, a default priority is used.
+ *
+ * To kill syslogd, send a signal 15 (terminate).  A signal 1 (hup) will
+ * cause it to reread its configuration file.
+ *
+ * Defined Constants:
+ *
+ * MAXLINE -- the maximimum line length that can be handled.
+ * DEFUPRI -- the default priority for user messages
+ * DEFSPRI -- the default priority for kernel messages
+ *
+ * Author: Eric Allman
+ * extensive changes by Ralph Campbell
+ * more extensive changes by Eric Allman (again)
+ */
+
+#define	MAXLINE		1024		/* maximum line length */
+#define	MAXSVLINE	120		/* maximum saved line length */
+#define DEFUPRI		(LOG_USER|LOG_NOTICE)
+#define DEFSPRI		(LOG_KERN|LOG_CRIT)
+#define TIMERINTVL	30		/* interval for checking flush, mark */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/msgbuf.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <utmp.h>
+#include "pathnames.h"
+
+#define SYSLOG_NAMES
+#include <sys/syslog.h>
+
+char	*LogName = _PATH_LOG;
+char	*ConfFile = _PATH_LOGCONF;
+char	*PidFile = _PATH_LOGPID;
+char	ctty[] = _PATH_CONSOLE;
+
+#define FDMASK(fd)	(1 << (fd))
+
+#define	dprintf		if (Debug) printf
+
+#define MAXUNAMES	20	/* maximum number of user names */
+
+/*
+ * Flags to logmsg().
+ */
+
+#define IGN_CONS	0x001	/* don't print on console */
+#define SYNC_FILE	0x002	/* do fsync on file after printing */
+#define ADDDATE		0x004	/* add a date to the message */
+#define MARK		0x008	/* this message is a mark */
+
+/*
+ * This structure represents the files that will have log
+ * copies printed.
+ */
+
+struct filed {
+	struct	filed *f_next;		/* next in linked list */
+	short	f_type;			/* entry type, see below */
+	short	f_file;			/* file descriptor */
+	time_t	f_time;			/* time this was last written */
+	u_char	f_pmask[LOG_NFACILITIES+1];	/* priority mask */
+	union {
+		char	f_uname[MAXUNAMES][UT_NAMESIZE+1];
+		struct {
+			char	f_hname[MAXHOSTNAMELEN+1];
+			struct sockaddr_in	f_addr;
+		} f_forw;		/* forwarding address */
+		char	f_fname[MAXPATHLEN];
+	} f_un;
+	char	f_prevline[MAXSVLINE];		/* last message logged */
+	char	f_lasttime[16];			/* time of last occurrence */
+	char	f_prevhost[MAXHOSTNAMELEN+1];	/* host from which recd. */
+	int	f_prevpri;			/* pri of f_prevline */
+	int	f_prevlen;			/* length of f_prevline */
+	int	f_prevcount;			/* repetition cnt of prevline */
+	int	f_repeatcount;			/* number of "repeated" msgs */
+};
+
+/*
+ * Intervals at which we flush out "message repeated" messages,
+ * in seconds after previous message is logged.  After each flush,
+ * we move to the next interval until we reach the largest.
+ */
+int	repeatinterval[] = { 30, 120, 600 };	/* # of secs before flush */
+#define	MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1)
+#define	REPEATTIME(f)	((f)->f_time + repeatinterval[(f)->f_repeatcount])
+#define	BACKOFF(f)	{ if (++(f)->f_repeatcount > MAXREPEAT) \
+				 (f)->f_repeatcount = MAXREPEAT; \
+			}
+
+/* values for f_type */
+#define F_UNUSED	0		/* unused entry */
+#define F_FILE		1		/* regular file */
+#define F_TTY		2		/* terminal */
+#define F_CONSOLE	3		/* console terminal */
+#define F_FORW		4		/* remote machine */
+#define F_USERS		5		/* list of users */
+#define F_WALL		6		/* everyone logged on */
+
+char	*TypeNames[7] = {
+	"UNUSED",	"FILE",		"TTY",		"CONSOLE",
+	"FORW",		"USERS",	"WALL"
+};
+
+struct	filed *Files;
+struct	filed consfile;
+
+int	Debug = 0;		/* debug flag */
+int	Insecure = 0;		/* insecure flag */
+char	LocalHostName[MAXHOSTNAMELEN+1];	/* our hostname */
+char	*LocalDomain;		/* our local domain name */
+int	InetInuse = 0;		/* non-zero if INET sockets are being used */
+int	finet;			/* Internet datagram socket */
+int	LogPort;		/* port number for INET connections */
+int	Initialized = 0;	/* set when we have initialized ourselves */
+int	MarkInterval = 20 * 60;	/* interval between marks in seconds */
+int	MarkSeq = 0;		/* mark sequence number */
+
+void	cfline __P((char *, struct filed *));
+char   *cvthname __P((struct sockaddr_in *));
+int	decode __P((const char *, CODE *));
+void	die __P((int));
+void	domark __P((int));
+void	fprintlog __P((struct filed *, int, char *));
+void	init __P((int));
+void	logerror __P((char *));
+void	logmsg __P((int, char *, char *, int));
+void	printline __P((char *, char *));
+void	printsys __P((char *));
+void	reapchild __P((int));
+char   *ttymsg __P((struct iovec *, int, char *, int));
+void	usage __P((void));
+void	wallmsg __P((struct filed *, struct iovec *));
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int ch, funix, i, inetm, fklog, klogm, len;
+	struct sockaddr_un sunx, fromunix;
+	struct sockaddr_in sin, frominet;
+	FILE *fp;
+	char *p, line[MSG_BSIZE + 1];
+
+	while ((ch = getopt(argc, argv, "duf:m:p:")) != EOF)
+		switch(ch) {
+		case 'd':		/* debug */
+			Debug++;
+			break;
+		case 'u':		/* insecure */
+			Insecure++;
+			break;
+		case 'f':		/* configuration file */
+			ConfFile = optarg;
+			break;
+		case 'm':		/* mark interval */
+			MarkInterval = atoi(optarg) * 60;
+			break;
+		case 'p':		/* path */
+			LogName = optarg;
+			break;
+		case '?':
+		default:
+			usage();
+		}
+	if ((argc -= optind) != 0)
+		usage();
+
+	if (!Debug)
+		(void)daemon(0, 0);
+	else
+		setlinebuf(stdout);
+
+	consfile.f_type = F_CONSOLE;
+	(void)strcpy(consfile.f_un.f_fname, ctty);
+	(void)gethostname(LocalHostName, sizeof(LocalHostName));
+	if ((p = strchr(LocalHostName, '.')) != NULL) {
+		*p++ = '\0';
+		LocalDomain = p;
+	} else
+		LocalDomain = "";
+	(void)signal(SIGTERM, die);
+	(void)signal(SIGINT, Debug ? die : SIG_IGN);
+	(void)signal(SIGQUIT, Debug ? die : SIG_IGN);
+	(void)signal(SIGCHLD, reapchild);
+	(void)signal(SIGALRM, domark);
+	(void)alarm(TIMERINTVL);
+	(void)unlink(LogName);
+
+#ifndef SUN_LEN
+#define SUN_LEN(unp) (strlen((unp)->sun_path) + 2)
+#endif
+	memset(&sunx, 0, sizeof(sunx));
+	sunx.sun_family = AF_UNIX;
+	(void)strncpy(sunx.sun_path, LogName, sizeof(sunx.sun_path));
+	funix = socket(AF_UNIX, SOCK_DGRAM, 0);
+	if (funix < 0 ||
+	    bind(funix, (struct sockaddr *)&sunx, SUN_LEN(&sunx)) < 0 ||
+	    chmod(LogName, 0666) < 0) {
+		(void) snprintf(line, sizeof line, "cannot create %s", LogName);
+		logerror(line);
+		dprintf("cannot create %s (%d)\n", LogName, errno);
+		die(0);
+	}
+	finet = socket(AF_INET, SOCK_DGRAM, 0);
+	inetm = 0;
+	if (finet >= 0) {
+		struct servent *sp;
+
+		sp = getservbyname("syslog", "udp");
+		if (sp == NULL) {
+			errno = 0;
+			logerror("syslog/udp: unknown service");
+			die(0);
+		}
+		memset(&sin, 0, sizeof(sin));
+		sin.sin_family = AF_INET;
+		sin.sin_port = LogPort = sp->s_port;
+		if (bind(finet, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+			logerror("bind");
+			if (!Debug)
+				die(0);
+		} else {
+			inetm = FDMASK(finet);
+			InetInuse = 1;
+		}
+	}
+	if ((fklog = open(_PATH_KLOG, O_RDONLY, 0)) >= 0)
+		klogm = FDMASK(fklog);
+	else {
+		dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
+		klogm = 0;
+	}
+
+	/* tuck my process id away */
+	fp = fopen(PidFile, "w");
+	if (fp != NULL) {
+		fprintf(fp, "%d\n", getpid());
+		(void) fclose(fp);
+	}
+
+	dprintf("off & running....\n");
+
+	init(0);
+	(void)signal(SIGHUP, init);
+
+	for (;;) {
+		int nfds, readfds = FDMASK(funix) | inetm | klogm;
+
+		dprintf("readfds = %#x\n", readfds);
+		nfds = select(20, (fd_set *)&readfds, (fd_set *)NULL,
+		    (fd_set *)NULL, (struct timeval *)NULL);
+		if (nfds == 0)
+			continue;
+		if (nfds < 0) {
+			if (errno != EINTR)
+				logerror("select");
+			continue;
+		}
+		dprintf("got a message (%d, %#x)\n", nfds, readfds);
+		if (readfds & klogm) {
+			i = read(fklog, line, sizeof(line) - 1);
+			if (i > 0) {
+				line[i] = '\0';
+				printsys(line);
+			} else if (i < 0 && errno != EINTR) {
+				logerror("klog");
+				fklog = -1;
+				klogm = 0;
+			}
+		}
+		if (readfds & FDMASK(funix)) {
+			len = sizeof(fromunix);
+			i = recvfrom(funix, line, MAXLINE, 0,
+			    (struct sockaddr *)&fromunix, &len);
+			if (i > 0) {
+				line[i] = '\0';
+				printline(LocalHostName, line);
+			} else if (i < 0 && errno != EINTR)
+				logerror("recvfrom unix");
+		}
+		if (readfds & inetm) {
+			len = sizeof(frominet);
+			i = recvfrom(finet, line, MAXLINE, 0,
+			    (struct sockaddr *)&frominet, &len);
+			if (Insecure) {
+				if (i > 0) {
+					line[i] = '\0';
+					printline(cvthname(&frominet), line);
+				} else if (i < 0 && errno != EINTR)
+					logerror("recvfrom inet");
+			}
+		} 
+	}
+}
+
+void
+usage()
+{
+
+	(void)fprintf(stderr,
+	    "usage: syslogd [-f conffile] [-m markinterval] [-p logpath]\n");
+	exit(1);
+}
+
+/*
+ * Take a raw input line, decode the message, and print the message
+ * on the appropriate log files.
+ */
+void
+printline(hname, msg)
+	char *hname;
+	char *msg;
+{
+	int c, pri;
+	char *p, *q, line[MAXLINE + 1];
+
+	/* test for special codes */
+	pri = DEFUPRI;
+	p = msg;
+	if (*p == '<') {
+		pri = 0;
+		while (isdigit(*++p))
+			pri = 10 * pri + (*p - '0');
+		if (*p == '>')
+			++p;
+	}
+	if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
+		pri = DEFUPRI;
+
+	/* don't allow users to log kernel messages */
+	if (LOG_FAC(pri) == LOG_KERN)
+		pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri));
+
+	q = line;
+
+	while ((c = *p++) != '\0' &&
+	    q < &line[sizeof(line) - 2]) {
+		c &= 0177;
+		if (iscntrl(c))
+			if (c == '\n')
+				*q++ = ' ';
+			else if (c == '\t')
+				*q++ = '\t';
+			else {
+				*q++ = '^';
+				*q++ = c ^ 0100;
+			}
+		else
+			*q++ = c;
+	}
+	*q = '\0';
+
+	logmsg(pri, line, hname, 0);
+}
+
+/*
+ * Take a raw input line from /dev/klog, split and format similar to syslog().
+ */
+void
+printsys(msg)
+	char *msg;
+{
+	int c, pri, flags;
+	char *lp, *p, *q, line[MAXLINE + 1];
+
+	(void)strcpy(line, "mach_kernel: ");
+	lp = line + strlen(line);
+	for (p = msg; *p != '\0'; ) {
+		flags = SYNC_FILE | ADDDATE;	/* fsync file after write */
+		pri = DEFSPRI;
+		if (*p == '<') {
+			pri = 0;
+			while (isdigit(*++p))
+				pri = 10 * pri + (*p - '0');
+			if (*p == '>')
+				++p;
+		} else {
+			/* kernel printf's come out on console */
+			flags |= IGN_CONS;
+		}
+		if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
+			pri = DEFSPRI;
+		q = lp;
+		while (*p != '\0' && (c = *p++) != '\n' &&
+		    q < &line[MAXLINE])
+			*q++ = c;
+		*q = '\0';
+		logmsg(pri, line, LocalHostName, flags);
+	}
+}
+
+time_t	now;
+
+/*
+ * Log a message to the appropriate log files, users, etc. based on
+ * the priority.
+ */
+void
+logmsg(pri, msg, from, flags)
+	int pri;
+	char *msg, *from;
+	int flags;
+{
+	struct filed *f;
+	int fac, msglen, omask, prilev;
+	char *timestamp;
+
+	dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n",
+	    pri, flags, from, msg);
+
+	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM));
+
+	/*
+	 * Check to see if msg looks non-standard.
+	 */
+	msglen = strlen(msg);
+	if (msglen < 16 || msg[3] != ' ' || msg[6] != ' ' ||
+	    msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')
+		flags |= ADDDATE;
+
+	(void)time(&now);
+	if (flags & ADDDATE)
+		timestamp = ctime(&now) + 4;
+	else {
+		timestamp = msg;
+		msg += 16;
+		msglen -= 16;
+	}
+
+	/* extract facility and priority level */
+	if (flags & MARK)
+		fac = LOG_NFACILITIES;
+	else
+		fac = LOG_FAC(pri);
+	prilev = LOG_PRI(pri);
+
+	/* log the message to the particular outputs */
+	if (!Initialized) {
+		f = &consfile;
+		f->f_file = open(ctty, O_WRONLY, 0);
+
+		if (f->f_file >= 0) {
+			fprintlog(f, flags, msg);
+			(void)close(f->f_file);
+		}
+		(void)sigsetmask(omask);
+		return;
+	}
+	for (f = Files; f; f = f->f_next) {
+		/* skip messages that are incorrect priority */
+		if (f->f_pmask[fac] < prilev ||
+		    f->f_pmask[fac] == INTERNAL_NOPRI)
+			continue;
+
+		if (f->f_type == F_CONSOLE && (flags & IGN_CONS))
+			continue;
+
+		/* don't output marks to recently written files */
+		if ((flags & MARK) && (now - f->f_time) < MarkInterval / 2)
+			continue;
+
+		/*
+		 * suppress duplicate lines to this file
+		 */
+		if ((flags & MARK) == 0 && msglen == f->f_prevlen &&
+		    !strcmp(msg, f->f_prevline) &&
+		    !strcmp(from, f->f_prevhost)) {
+			(void)strncpy(f->f_lasttime, timestamp, 15);
+			f->f_prevcount++;
+			dprintf("msg repeated %d times, %ld sec of %d\n",
+			    f->f_prevcount, now - f->f_time,
+			    repeatinterval[f->f_repeatcount]);
+			/*
+			 * If domark would have logged this by now,
+			 * flush it now (so we don't hold isolated messages),
+			 * but back off so we'll flush less often
+			 * in the future.
+			 */
+			if (now > REPEATTIME(f)) {
+				fprintlog(f, flags, (char *)NULL);
+				BACKOFF(f);
+			}
+		} else {
+			/* new line, save it */
+			if (f->f_prevcount)
+				fprintlog(f, 0, (char *)NULL);
+			f->f_repeatcount = 0;
+			(void)strncpy(f->f_lasttime, timestamp, 15);
+			(void)strncpy(f->f_prevhost, from,
+					sizeof(f->f_prevhost));
+			if (msglen < MAXSVLINE) {
+				f->f_prevlen = msglen;
+				f->f_prevpri = pri;
+				(void)strcpy(f->f_prevline, msg);
+				fprintlog(f, flags, (char *)NULL);
+			} else {
+				f->f_prevline[0] = 0;
+				f->f_prevlen = 0;
+				fprintlog(f, flags, msg);
+			}
+		}
+	}
+	(void)sigsetmask(omask);
+}
+
+void
+fprintlog(f, flags, msg)
+	struct filed *f;
+	int flags;
+	char *msg;
+{
+	struct iovec iov[6];
+	struct iovec *v;
+	int l;
+	char line[MAXLINE + 1], repbuf[80], greetings[200];
+
+	v = iov;
+	if (f->f_type == F_WALL) {
+		v->iov_base = greetings;
+		v->iov_len = snprintf(greetings, sizeof greetings, 
+		    "\r\n\7Message from syslogd@%s at %.24s ...\r\n",
+		    f->f_prevhost, ctime(&now));
+		v++;
+		v->iov_base = "";
+		v->iov_len = 0;
+		v++;
+	} else {
+		v->iov_base = f->f_lasttime;
+		v->iov_len = 15;
+		v++;
+		v->iov_base = " ";
+		v->iov_len = 1;
+		v++;
+	}
+	v->iov_base = f->f_prevhost;
+	v->iov_len = strlen(v->iov_base);
+	v++;
+	v->iov_base = " ";
+	v->iov_len = 1;
+	v++;
+
+	if (msg) {
+		v->iov_base = msg;
+		v->iov_len = strlen(msg);
+	} else if (f->f_prevcount > 1) {
+		v->iov_base = repbuf;
+		v->iov_len = snprintf(repbuf, sizeof repbuf, "last message repeated %d times",
+		    f->f_prevcount);
+	} else {
+		v->iov_base = f->f_prevline;
+		v->iov_len = f->f_prevlen;
+	}
+	v++;
+
+	dprintf("Logging to %s", TypeNames[f->f_type]);
+	f->f_time = now;
+
+	switch (f->f_type) {
+	case F_UNUSED:
+		dprintf("\n");
+		break;
+
+	case F_FORW:
+		dprintf(" %s\n", f->f_un.f_forw.f_hname);
+		l = snprintf(line, sizeof line, "<%d>%.15s %s", f->f_prevpri,
+		    iov[0].iov_base, iov[4].iov_base);
+		if (l > MAXLINE)
+			l = MAXLINE;
+		if (sendto(finet, line, l, 0,
+		    (struct sockaddr *)&f->f_un.f_forw.f_addr,
+		    sizeof(f->f_un.f_forw.f_addr)) != l) {
+			int e = errno;
+			(void)close(f->f_file);
+			f->f_type = F_UNUSED;
+			errno = e;
+			logerror("sendto");
+		}
+		break;
+
+	case F_CONSOLE:
+		if (flags & IGN_CONS) {
+			dprintf(" (ignored)\n");
+			break;
+		}
+		/* FALLTHROUGH */
+
+	case F_TTY:
+	case F_FILE:
+		dprintf(" %s\n", f->f_un.f_fname);
+		if (f->f_type != F_FILE) {
+			v->iov_base = "\r\n";
+			v->iov_len = 2;
+		} else {
+			v->iov_base = "\n";
+			v->iov_len = 1;
+		}
+	again:
+		if (writev(f->f_file, iov, 6) < 0) {
+			int e = errno;
+			(void)close(f->f_file);
+			/*
+			 * Check for errors on TTY's due to loss of tty
+			 */
+			if ((e == EIO || e == EBADF) && f->f_type != F_FILE) {
+				f->f_file = open(f->f_un.f_fname,
+				    O_WRONLY|O_APPEND, 0);
+				if (f->f_file < 0) {
+					f->f_type = F_UNUSED;
+					logerror(f->f_un.f_fname);
+				} else
+					goto again;
+			} else {
+				f->f_type = F_UNUSED;
+				errno = e;
+				logerror(f->f_un.f_fname);
+			}
+		} else if (flags & SYNC_FILE)
+			(void)fsync(f->f_file);
+		break;
+
+	case F_USERS:
+	case F_WALL:
+		dprintf("\n");
+		v->iov_base = "\r\n";
+		v->iov_len = 2;
+		wallmsg(f, iov);
+		break;
+	}
+	f->f_prevcount = 0;
+}
+
+/*
+ *  WALLMSG -- Write a message to the world at large
+ *
+ *	Write the specified message to either the entire
+ *	world, or a list of approved users.
+ */
+void
+wallmsg(f, iov)
+	struct filed *f;
+	struct iovec *iov;
+{
+	static int reenter;			/* avoid calling ourselves */
+	FILE *uf;
+	struct utmp ut;
+	int i;
+	char *p;
+	char line[sizeof(ut.ut_line) + 1];
+
+	if (reenter++)
+		return;
+	if ((uf = fopen(_PATH_UTMP, "r")) == NULL) {
+		logerror(_PATH_UTMP);
+		reenter = 0;
+		return;
+	}
+	/* NOSTRICT */
+	while (fread((char *)&ut, sizeof(ut), 1, uf) == 1) {
+		if (ut.ut_name[0] == '\0')
+			continue;
+		strncpy(line, ut.ut_line, sizeof(ut.ut_line));
+		line[sizeof(ut.ut_line)] = '\0';
+		if (f->f_type == F_WALL) {
+			if ((p = ttymsg(iov, 6, line, 60*5)) != NULL) {
+				errno = 0;	/* already in msg */
+				logerror(p);
+			}
+			continue;
+		}
+		/* should we send the message to this user? */
+		for (i = 0; i < MAXUNAMES; i++) {
+			if (!f->f_un.f_uname[i][0])
+				break;
+			if (!strncmp(f->f_un.f_uname[i], ut.ut_name,
+			    UT_NAMESIZE)) {
+				if ((p = ttymsg(iov, 6, line, 60*5)) != NULL) {
+					errno = 0;	/* already in msg */
+					logerror(p);
+				}
+				break;
+			}
+		}
+	}
+	(void)fclose(uf);
+	reenter = 0;
+}
+
+void
+reapchild(signo)
+	int signo;
+{
+	union wait status;
+
+	while (wait3((int *)&status, WNOHANG, (struct rusage *)NULL) > 0)
+		;
+}
+
+/*
+ * Return a printable representation of a host address.
+ */
+char *
+cvthname(f)
+	struct sockaddr_in *f;
+{
+	struct hostent *hp;
+	char *p;
+
+	dprintf("cvthname(%s)\n", inet_ntoa(f->sin_addr));
+
+	if (f->sin_family != AF_INET) {
+		dprintf("Malformed from address\n");
+		return ("???");
+	}
+	hp = gethostbyaddr((char *)&f->sin_addr,
+	    sizeof(struct in_addr), f->sin_family);
+	if (hp == 0) {
+		dprintf("Host name for your address (%s) unknown\n",
+			inet_ntoa(f->sin_addr));
+		return (inet_ntoa(f->sin_addr));
+	}
+	if ((p = strchr(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0)
+		*p = '\0';
+	return (hp->h_name);
+}
+
+void
+domark(signo)
+	int signo;
+{
+	struct filed *f;
+
+	now = time((time_t *)NULL);
+	MarkSeq += TIMERINTVL;
+	if (MarkSeq >= MarkInterval) {
+		logmsg(LOG_INFO, "-- MARK --", LocalHostName, ADDDATE|MARK);
+		MarkSeq = 0;
+	}
+
+	for (f = Files; f; f = f->f_next) {
+		if (f->f_prevcount && now >= REPEATTIME(f)) {
+			dprintf("flush %s: repeated %d times, %d sec.\n",
+			    TypeNames[f->f_type], f->f_prevcount,
+			    repeatinterval[f->f_repeatcount]);
+			fprintlog(f, 0, (char *)NULL);
+			BACKOFF(f);
+		}
+	}
+	(void)alarm(TIMERINTVL);
+}
+
+/*
+ * Print syslogd errors some place.
+ */
+void
+logerror(type)
+	char *type;
+{
+	char buf[100];
+
+	if (errno)
+		(void)snprintf(buf,
+		    sizeof(buf), "syslogd: %s: %s", type, strerror(errno));
+	else
+		(void)snprintf(buf, sizeof(buf), "syslogd: %s", type);
+	errno = 0;
+	dprintf("%s\n", buf);
+	logmsg(LOG_SYSLOG|LOG_ERR, buf, LocalHostName, ADDDATE);
+}
+
+void
+die(signo)
+	int signo;
+{
+	struct filed *f;
+	char buf[100];
+
+	for (f = Files; f != NULL; f = f->f_next) {
+		/* flush any pending output */
+		if (f->f_prevcount)
+			fprintlog(f, 0, (char *)NULL);
+	}
+	if (signo) {
+		dprintf("syslogd: exiting on signal %d\n", signo);
+		(void)snprintf(buf, sizeof buf, "exiting on signal %d", signo);
+		errno = 0;
+		logerror(buf);
+	}
+	(void)unlink(LogName);
+	exit(0);
+}
+
+/*
+ *  INIT -- Initialize syslogd from configuration table
+ */
+void
+init(signo)
+	int signo;
+{
+	int i;
+	FILE *cf;
+	struct filed *f, *next, **nextp;
+	char *p;
+	char cline[LINE_MAX];
+
+	dprintf("init\n");
+
+	/*
+	 *  Close all open log files.
+	 */
+	Initialized = 0;
+	for (f = Files; f != NULL; f = next) {
+		/* flush any pending output */
+		if (f->f_prevcount)
+			fprintlog(f, 0, (char *)NULL);
+
+		switch (f->f_type) {
+		case F_FILE:
+		case F_TTY:
+		case F_CONSOLE:
+		case F_FORW:
+			(void)close(f->f_file);
+			break;
+		}
+		next = f->f_next;
+		free((char *)f);
+	}
+	Files = NULL;
+	nextp = &Files;
+
+	/* open the configuration file */
+	if ((cf = fopen(ConfFile, "r")) == NULL) {
+		dprintf("cannot open %s\n", ConfFile);
+		*nextp = (struct filed *)calloc(1, sizeof(*f));
+		cfline("*.ERR\t/dev/console", *nextp);
+		(*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f));
+		cfline("*.PANIC\t*", (*nextp)->f_next);
+		Initialized = 1;
+		return;
+	}
+
+	/*
+	 *  Foreach line in the conf table, open that file.
+	 */
+	f = NULL;
+	while (fgets(cline, sizeof(cline), cf) != NULL) {
+		/*
+		 * check for end-of-section, comments, strip off trailing
+		 * spaces and newline character.
+		 */
+		for (p = cline; isspace(*p); ++p)
+			continue;
+		if (*p == NULL || *p == '#')
+			continue;
+		for (p = strchr(cline, '\0'); isspace(*--p);)
+			continue;
+		*++p = '\0';
+		f = (struct filed *)calloc(1, sizeof(*f));
+		*nextp = f;
+		nextp = &f->f_next;
+		cfline(cline, f);
+	}
+
+	/* close the configuration file */
+	(void)fclose(cf);
+
+	Initialized = 1;
+
+	if (Debug) {
+		for (f = Files; f; f = f->f_next) {
+			for (i = 0; i <= LOG_NFACILITIES; i++)
+				if (f->f_pmask[i] == INTERNAL_NOPRI)
+					printf("X ");
+				else
+					printf("%d ", f->f_pmask[i]);
+			printf("%s: ", TypeNames[f->f_type]);
+			switch (f->f_type) {
+			case F_FILE:
+			case F_TTY:
+			case F_CONSOLE:
+				printf("%s", f->f_un.f_fname);
+				break;
+
+			case F_FORW:
+				printf("%s", f->f_un.f_forw.f_hname);
+				break;
+
+			case F_USERS:
+				for (i = 0; i < MAXUNAMES && *f->f_un.f_uname[i]; i++)
+					printf("%s, ", f->f_un.f_uname[i]);
+				break;
+			}
+			printf("\n");
+		}
+	}
+
+	logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart", LocalHostName, ADDDATE);
+	dprintf("syslogd: restarted\n");
+}
+
+/*
+ * Crack a configuration file line
+ */
+void
+cfline(line, f)
+	char *line;
+	struct filed *f;
+{
+	struct hostent *hp;
+	int i, pri;
+	char *bp, *p, *q;
+	char buf[MAXLINE], ebuf[100];
+
+	dprintf("cfline(%s)\n", line);
+
+	errno = 0;	/* keep strerror() stuff out of logerror messages */
+
+	/* clear out file entry */
+	memset(f, 0, sizeof(*f));
+	for (i = 0; i <= LOG_NFACILITIES; i++)
+		f->f_pmask[i] = INTERNAL_NOPRI;
+
+	/* scan through the list of selectors */
+	for (p = line; *p && *p != '\t';) {
+
+		/* find the end of this facility name list */
+		for (q = p; *q && *q != '\t' && *q++ != '.'; )
+			continue;
+
+		/* collect priority name */
+		for (bp = buf; *q && !strchr("\t,;", *q); )
+			*bp++ = *q++;
+		*bp = '\0';
+
+		/* skip cruft */
+		while (strchr(", ;", *q))
+			q++;
+
+		/* decode priority name */
+		if (*buf == '*')
+			pri = LOG_PRIMASK + 1;
+		else {
+			pri = decode(buf, prioritynames);
+			if (pri < 0) {
+				(void)snprintf(ebuf, sizeof ebuf, 
+				    "unknown priority name \"%s\"", buf);
+				logerror(ebuf);
+				return;
+			}
+		}
+
+		/* scan facilities */
+		while (*p && !strchr("\t.;", *p)) {
+			for (bp = buf; *p && !strchr("\t,;.", *p); )
+				*bp++ = *p++;
+			*bp = '\0';
+			if (*buf == '*')
+				for (i = 0; i < LOG_NFACILITIES; i++)
+					f->f_pmask[i] = pri;
+			else {
+				i = decode(buf, facilitynames);
+				if (i < 0) {
+					(void)snprintf(ebuf, sizeof ebuf, 
+					    "unknown facility name \"%s\"",
+					    buf);
+					logerror(ebuf);
+					return;
+				}
+				f->f_pmask[i >> 3] = pri;
+			}
+			while (*p == ',' || *p == ' ')
+				p++;
+		}
+
+		p = q;
+	}
+
+	/* skip to action part */
+	while (*p == '\t')
+		p++;
+
+	switch (*p)
+	{
+	case '@':
+		if (!InetInuse)
+			break;
+		(void)strcpy(f->f_un.f_forw.f_hname, ++p);
+		hp = gethostbyname(p);
+		if (hp == NULL) {
+			extern int h_errno;
+
+			logerror(hstrerror(h_errno));
+			break;
+		}
+		memset(&f->f_un.f_forw.f_addr, 0,
+			 sizeof(f->f_un.f_forw.f_addr));
+		f->f_un.f_forw.f_addr.sin_family = AF_INET;
+		f->f_un.f_forw.f_addr.sin_port = LogPort;
+		memmove(&f->f_un.f_forw.f_addr.sin_addr, hp->h_addr, hp->h_length);
+		f->f_type = F_FORW;
+		break;
+
+	case '/':
+		(void)strcpy(f->f_un.f_fname, p);
+		if ((f->f_file = open(p, O_WRONLY|O_APPEND, 0)) < 0) {
+			f->f_file = F_UNUSED;
+			logerror(p);
+			break;
+		}
+		if (isatty(f->f_file))
+			f->f_type = F_TTY;
+		else
+			f->f_type = F_FILE;
+		if (strcmp(p, ctty) == 0)
+			f->f_type = F_CONSOLE;
+		break;
+
+	case '*':
+		f->f_type = F_WALL;
+		break;
+
+	default:
+		for (i = 0; i < MAXUNAMES && *p; i++) {
+			for (q = p; *q && *q != ','; )
+				q++;
+			(void)strncpy(f->f_un.f_uname[i], p, UT_NAMESIZE);
+			if ((q - p) > UT_NAMESIZE)
+				f->f_un.f_uname[i][UT_NAMESIZE] = '\0';
+			else
+				f->f_un.f_uname[i][q - p] = '\0';
+			while (*q == ',' || *q == ' ')
+				q++;
+			p = q;
+		}
+		f->f_type = F_USERS;
+		break;
+	}
+}
+
+
+/*
+ *  Decode a symbolic name to a numeric value
+ */
+int
+decode(name, codetab)
+	const char *name;
+	CODE *codetab;
+{
+	CODE *c;
+	char *p, buf[40];
+
+	if (isdigit(*name))
+		return (atoi(name));
+
+	for (p = buf; *name && p < &buf[sizeof(buf) - 1]; p++, name++) {
+		if (isupper(*name))
+			*p = tolower(*name);
+		else
+			*p = *name;
+	}
+	*p = '\0';
+	for (c = codetab; c->c_name; c++)
+		if (!strcmp(buf, c->c_name))
+			return (c->c_val);
+
+	return (-1);
+}
diff --git a/talk.tproj/Makefile b/talk.tproj/Makefile
new file mode 100644
index 0000000..de9a8fa
--- /dev/null
+++ b/talk.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = talk
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = talk.h talk_ctl.h
+
+CFILES = ctl.c ctl_transact.c display.c get_addrs.c get_names.c\
+         init_disp.c invite.c io.c look_up.c msgs.c talk.c
+
+OTHERSRCS = Makefile.preamble Makefile talk.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/talk.tproj/Makefile.preamble b/talk.tproj/Makefile.preamble
new file mode 100644
index 0000000..925a5c7
--- /dev/null
+++ b/talk.tproj/Makefile.preamble
@@ -0,0 +1,3 @@
+CLEAN_ALL_SUBPROJECTS = YES
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/talk.tproj/PB.project b/talk.tproj/PB.project
new file mode 100644
index 0000000..f6093c3
--- /dev/null
+++ b/talk.tproj/PB.project
@@ -0,0 +1,37 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (talk.h, talk_ctl.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (
+            ctl.c, 
+            ctl_transact.c, 
+            display.c, 
+            get_addrs.c, 
+            get_names.c, 
+            init_disp.c, 
+            invite.c, 
+            io.c, 
+            look_up.c, 
+            msgs.c, 
+            talk.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, talk.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = talk; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/talk.tproj/ctl.c b/talk.tproj/ctl.c
new file mode 100644
index 0000000..d1c016b
--- /dev/null
+++ b/talk.tproj/ctl.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/*
+ * This file handles haggling with the various talk daemons to
+ * get a socket to talk to. sockt is opened and connected in
+ * the progress
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <protocols/talkd.h>
+#include <netinet/in.h>
+#include "talk.h"
+#include "talk_ctl.h"
+
+struct	sockaddr_in daemon_addr = { sizeof(daemon_addr), AF_INET };
+struct	sockaddr_in ctl_addr = { sizeof(ctl_addr), AF_INET };
+struct	sockaddr_in my_addr = { sizeof(my_addr), AF_INET };
+
+	/* inet addresses of the two machines */
+struct	in_addr my_machine_addr;
+struct	in_addr his_machine_addr;
+
+u_short daemon_port;	/* port number of the talk daemon */
+
+int	ctl_sockt;
+int	sockt;
+int	invitation_waiting = 0;
+
+CTL_MSG msg;
+
+open_sockt()
+{
+	int length;
+
+	my_addr.sin_addr = my_machine_addr;
+	my_addr.sin_port = 0;
+	sockt = socket(AF_INET, SOCK_STREAM, 0);
+	if (sockt <= 0)
+		p_error("Bad socket");
+	if (bind(sockt, (struct sockaddr *)&my_addr, sizeof(my_addr)) != 0)
+		p_error("Binding local socket");
+	length = sizeof(my_addr);
+	if (getsockname(sockt, (struct sockaddr *)&my_addr, &length) == -1)
+		p_error("Bad address for socket");
+}
+
+/* open the ctl socket */
+open_ctl() 
+{
+	int length;
+
+	ctl_addr.sin_port = 0;
+	ctl_addr.sin_addr = my_machine_addr;
+	ctl_sockt = socket(AF_INET, SOCK_DGRAM, 0);
+	if (ctl_sockt <= 0)
+		p_error("Bad socket");
+	if (bind(ctl_sockt,
+	    (struct sockaddr *)&ctl_addr, sizeof(ctl_addr)) != 0)
+		p_error("Couldn't bind to control socket");
+	length = sizeof(ctl_addr);
+	if (getsockname(ctl_sockt,
+	    (struct sockaddr *)&ctl_addr, &length) == -1)
+		p_error("Bad address for ctl socket");
+}
+
+/* print_addr is a debug print routine */
+print_addr(addr)
+	struct sockaddr_in addr;
+{
+	int i;
+
+	printf("addr = %x, port = %o, family = %o zero = ",
+		addr.sin_addr, addr.sin_port, addr.sin_family);
+	for (i = 0; i<8;i++)
+	printf("%o ", (int)addr.sin_zero[i]);
+	putchar('\n');
+}
diff --git a/talk.tproj/ctl_transact.c b/talk.tproj/ctl_transact.c
new file mode 100644
index 0000000..85474dd
--- /dev/null
+++ b/talk.tproj/ctl_transact.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <protocols/talkd.h>
+#include <errno.h>
+#include "talk_ctl.h"
+
+#define CTL_WAIT 2	/* time to wait for a response, in seconds */
+
+/*
+ * SOCKDGRAM is unreliable, so we must repeat messages if we have
+ * not recieved an acknowledgement within a reasonable amount
+ * of time
+ */
+ctl_transact(target, msg, type, rp)
+	struct in_addr target;
+	CTL_MSG msg;
+	int type;
+	CTL_RESPONSE *rp;
+{
+	int read_mask, ctl_mask, nready, cc;
+	struct timeval wait;
+
+	msg.type = type;
+	daemon_addr.sin_addr = target;
+	daemon_addr.sin_port = daemon_port;
+	ctl_mask = 1 << ctl_sockt;
+
+	/*
+	 * Keep sending the message until a response of
+	 * the proper type is obtained.
+	 */
+	do {
+		wait.tv_sec = CTL_WAIT;
+		wait.tv_usec = 0;
+		/* resend message until a response is obtained */
+		do {
+			cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0,
+			    (struct sockaddr *)&daemon_addr,
+			    sizeof (daemon_addr));
+			if (cc != sizeof (msg)) {
+				if (errno == EINTR)
+					continue;
+				p_error("Error on write to talk daemon");
+			}
+			read_mask = ctl_mask;
+			nready = select(32, &read_mask, 0, 0, &wait);
+			if (nready < 0) {
+				if (errno == EINTR)
+					continue;
+				p_error("Error waiting for daemon response");
+			}
+		} while (nready == 0);
+		/*
+		 * Keep reading while there are queued messages 
+		 * (this is not necessary, it just saves extra
+		 * request/acknowledgements being sent)
+		 */
+		do {
+			cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0);
+			if (cc < 0) {
+				if (errno == EINTR)
+					continue;
+				p_error("Error on read from talk daemon");
+			}
+			read_mask = ctl_mask;
+			/* an immediate poll */
+			timerclear(&wait);
+			nready = select(32, &read_mask, 0, 0, &wait);
+		} while (nready > 0 && (rp->vers != TALK_VERSION ||
+		    rp->type != type));
+	} while (rp->vers != TALK_VERSION || rp->type != type);
+	rp->id_num = ntohl(rp->id_num);
+	rp->addr.sa_family = ntohs(rp->addr.sa_family);
+}
diff --git a/talk.tproj/display.c b/talk.tproj/display.c
new file mode 100644
index 0000000..6a725a6
--- /dev/null
+++ b/talk.tproj/display.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/*
+ * The window 'manager', initializes curses and handles the actual
+ * displaying of text
+ */
+#include "talk.h"
+
+xwin_t	my_win;
+xwin_t	his_win;
+WINDOW	*line_win;
+
+int	curses_initialized = 0;
+
+/*
+ * max HAS to be a function, it is called with
+ * a argument of the form --foo at least once.
+ */
+max(a,b)
+	int a, b;
+{
+
+	return (a > b ? a : b);
+}
+
+/*
+ * Display some text on somebody's window, processing some control
+ * characters while we are at it.
+ */
+display(win, text, size)
+	register xwin_t *win;
+	register char *text;
+	int size;
+{
+	register int i;
+	char cch;
+
+	for (i = 0; i < size; i++) {
+		if (*text == '\n') {
+			xscroll(win, 0);
+			text++;
+			continue;
+		}
+		/* erase character */
+		if (*text == win->cerase) {
+			wmove(win->x_win, win->x_line, max(--win->x_col, 0));
+			getyx(win->x_win, win->x_line, win->x_col);
+			waddch(win->x_win, ' ');
+			wmove(win->x_win, win->x_line, win->x_col);
+			getyx(win->x_win, win->x_line, win->x_col);
+			text++;
+			continue;
+		}
+		/*
+		 * On word erase search backwards until we find
+		 * the beginning of a word or the beginning of
+		 * the line.
+		 */
+		if (*text == win->werase) {
+			int endcol, xcol, i, c;
+
+			endcol = win->x_col;
+			xcol = endcol - 1;
+			while (xcol >= 0) {
+				c = readwin(win->x_win, win->x_line, xcol);
+				if (c != ' ')
+					break;
+				xcol--;
+			}
+			while (xcol >= 0) {
+				c = readwin(win->x_win, win->x_line, xcol);
+				if (c == ' ')
+					break;
+				xcol--;
+			}
+			wmove(win->x_win, win->x_line, xcol + 1);
+			for (i = xcol + 1; i < endcol; i++)
+				waddch(win->x_win, ' ');
+			wmove(win->x_win, win->x_line, xcol + 1);
+			getyx(win->x_win, win->x_line, win->x_col);
+			text++;
+			continue;
+		}
+		/* line kill */
+		if (*text == win->kill) {
+			wmove(win->x_win, win->x_line, 0);
+			wclrtoeol(win->x_win);
+			getyx(win->x_win, win->x_line, win->x_col);
+			text++;
+			continue;
+		}
+		if (*text == '\f') {
+			if (win == &my_win)
+				wrefresh(curscr);
+			text++;
+			continue;
+		}
+		if (win->x_col == COLS-1) {
+			/* check for wraparound */
+			xscroll(win, 0);
+		}
+		if (*text < ' ' && *text != '\t') {
+			waddch(win->x_win, '^');
+			getyx(win->x_win, win->x_line, win->x_col);
+			if (win->x_col == COLS-1) /* check for wraparound */
+				xscroll(win, 0);
+			cch = (*text & 63) + 64;
+			waddch(win->x_win, cch);
+		} else
+			waddch(win->x_win, *text);
+		getyx(win->x_win, win->x_line, win->x_col);
+		text++;
+	}
+	wrefresh(win->x_win);
+}
+
+/*
+ * Read the character at the indicated position in win
+ */
+readwin(win, line, col)
+	WINDOW *win;
+{
+	int oldline, oldcol;
+	register int c;
+
+	getyx(win, oldline, oldcol);
+	wmove(win, line, col);
+	c = winch(win);
+	wmove(win, oldline, oldcol);
+	return (c);
+}
+
+/*
+ * Scroll a window, blanking out the line following the current line
+ * so that the current position is obvious
+ */
+xscroll(win, flag)
+	register xwin_t *win;
+	int flag;
+{
+
+	if (flag == -1) {
+		wmove(win->x_win, 0, 0);
+		win->x_line = 0;
+		win->x_col = 0;
+		return;
+	}
+	win->x_line = (win->x_line + 1) % win->x_nlines;
+	win->x_col = 0;
+	wmove(win->x_win, win->x_line, win->x_col);
+	wclrtoeol(win->x_win);
+	wmove(win->x_win, (win->x_line + 1) % win->x_nlines, win->x_col);
+	wclrtoeol(win->x_win);
+	wmove(win->x_win, win->x_line, win->x_col);
+}
diff --git a/talk.tproj/get_addrs.c b/talk.tproj/get_addrs.c
new file mode 100644
index 0000000..ce728c5
--- /dev/null
+++ b/talk.tproj/get_addrs.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <protocols/talkd.h>
+#include <netdb.h>
+#include <stdio.h>
+#include "talk_ctl.h"
+
+get_addrs(my_machine_name, his_machine_name)
+	char *my_machine_name, *his_machine_name;
+{
+	struct hostent *hp;
+	struct servent *sp;
+
+	msg.pid = htonl(getpid());
+	/* look up the address of the local host */
+	hp = gethostbyname(my_machine_name);
+	if (hp == NULL) {
+		fprintf(stderr, "talk: %s: ", my_machine_name);
+		herror((char *)NULL);
+		exit(-1);
+	}
+	bcopy(hp->h_addr, (char *)&my_machine_addr, hp->h_length);
+	/*
+	 * If the callee is on-machine, just copy the
+	 * network address, otherwise do a lookup...
+	 */
+	if (strcmp(his_machine_name, my_machine_name)) {
+		hp = gethostbyname(his_machine_name);
+		if (hp == NULL) {
+			fprintf(stderr, "talk: %s: ", his_machine_name);
+			herror((char *)NULL);
+			exit(-1);
+		}
+		bcopy(hp->h_addr, (char *) &his_machine_addr, hp->h_length);
+	} else
+		his_machine_addr = my_machine_addr;
+	/* find the server's port */
+	sp = getservbyname("ntalk", "udp");
+	if (sp == 0) {
+		fprintf(stderr, "talk: %s/%s: service is not registered.\n",
+		     "ntalk", "udp");
+		exit(-1);
+	}
+	daemon_port = sp->s_port;
+}
diff --git a/talk.tproj/get_names.c b/talk.tproj/get_names.c
new file mode 100644
index 0000000..adf43bc
--- /dev/null
+++ b/talk.tproj/get_names.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <protocols/talkd.h>
+#include <pwd.h>
+#include "talk.h"
+
+char	*getlogin();
+char	*ttyname();
+char	*rindex();
+extern	CTL_MSG msg;
+
+/*
+ * Determine the local and remote user, tty, and machines
+ */
+get_names(argc, argv)
+	int argc;
+	char *argv[];
+{
+	char hostname[MAXHOSTNAMELEN];
+	char *his_name, *my_name;
+	char *my_machine_name, *his_machine_name;
+	char *my_tty, *his_tty;
+	register char *cp;
+
+	if (argc < 2 ) {
+		printf("Usage: talk user [ttyname]\n");
+		exit(-1);
+	}
+	if (!isatty(0)) {
+		printf("Standard input must be a tty, not a pipe or a file\n");
+		exit(-1);
+	}
+	if ((my_name = getlogin()) == NULL) {
+		struct passwd *pw;
+
+		if ((pw = getpwuid(getuid())) == NULL) {
+			printf("You don't exist. Go away.\n");
+			exit(-1);
+		}
+		my_name = pw->pw_name;
+	}
+	gethostname(hostname, sizeof (hostname));
+	my_machine_name = hostname;
+	/* check for, and strip out, the machine name of the target */
+	for (cp = argv[1]; *cp && !index("@:!.", *cp); cp++)
+		;
+	if (*cp == '\0') {
+		/* this is a local to local talk */
+		his_name = argv[1];
+		his_machine_name = my_machine_name;
+	} else {
+		if (*cp++ == '@') {
+			/* user@host */
+			his_name = argv[1];
+			his_machine_name = cp;
+		} else {
+			/* host.user or host!user or host:user */
+			his_name = cp;
+			his_machine_name = argv[1];
+		}
+		*--cp = '\0';
+	}
+	if (argc > 2)
+		his_tty = argv[2];	/* tty name is arg 2 */
+	else
+		his_tty = "";
+	get_addrs(my_machine_name, his_machine_name);
+	/*
+	 * Initialize the message template.
+	 */
+	msg.vers = TALK_VERSION;
+	msg.addr.sa_family = htons(AF_INET);
+	msg.ctl_addr.sa_family = htons(AF_INET);
+	msg.id_num = htonl(0);
+	strncpy(msg.l_name, my_name, NAME_SIZE);
+	msg.l_name[NAME_SIZE - 1] = '\0';
+	strncpy(msg.r_name, his_name, NAME_SIZE);
+	msg.r_name[NAME_SIZE - 1] = '\0';
+	strncpy(msg.r_tty, his_tty, TTY_SIZE);
+	msg.r_tty[TTY_SIZE - 1] = '\0';
+}
diff --git a/talk.tproj/init_disp.c b/talk.tproj/init_disp.c
new file mode 100644
index 0000000..1332107
--- /dev/null
+++ b/talk.tproj/init_disp.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/*
+ * Initialization code for the display package,
+ * as well as the signal handling routines.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/ioctl_compat.h>
+
+#include <signal.h>
+#include <err.h>
+#include "talk.h"
+
+/* 
+ * Set up curses, catch the appropriate signals,
+ * and build the various windows.
+ */
+init_display()
+{
+	void sig_sent();
+	struct sigvec sigv;
+
+	if (initscr() == NULL)
+		errx(1, "Terminal type unset or lacking necessary features.");
+	(void) sigvec(SIGTSTP, (struct sigvec *)0, &sigv);
+	sigv.sv_mask |= sigmask(SIGALRM);
+	(void) _sigvec_nobind(SIGTSTP, &sigv, (struct sigvec *)0);
+	curses_initialized = 1;
+	clear();
+	refresh();
+	noecho();
+	crmode();
+	signal(SIGINT, sig_sent);
+	signal(SIGPIPE, sig_sent);
+	/* curses takes care of ^Z */
+	my_win.x_nlines = LINES / 2;
+	my_win.x_ncols = COLS;
+	my_win.x_win = newwin(my_win.x_nlines, my_win.x_ncols, 0, 0);
+	scrollok(my_win.x_win, FALSE);
+	wclear(my_win.x_win);
+
+	his_win.x_nlines = LINES / 2 - 1;
+	his_win.x_ncols = COLS;
+	his_win.x_win = newwin(his_win.x_nlines, his_win.x_ncols,
+	    my_win.x_nlines+1, 0);
+	scrollok(his_win.x_win, FALSE);
+	wclear(his_win.x_win);
+
+	line_win = newwin(1, COLS, my_win.x_nlines, 0);
+	box(line_win, '-', '-');
+	wrefresh(line_win);
+	/* let them know we are working on it */
+	current_state = "No connection yet";
+}
+
+/*
+ * Trade edit characters with the other talk. By agreement
+ * the first three characters each talk transmits after
+ * connection are the three edit characters.
+ */
+set_edit_chars()
+{
+	char buf[3];
+	int cc;
+	struct sgttyb tty;
+	struct ltchars ltc;
+	
+	ioctl(0, TIOCGETP, &tty);
+	ioctl(0, TIOCGLTC, (struct sgttyb *)&ltc);
+	my_win.cerase = tty.sg_erase;
+	my_win.kill = tty.sg_kill;
+	if (ltc.t_werasc == (char) -1)
+		my_win.werase = '\027';	 /* control W */
+	else
+		my_win.werase = ltc.t_werasc;
+	buf[0] = my_win.cerase;
+	buf[1] = my_win.kill;
+	buf[2] = my_win.werase;
+	cc = write(sockt, buf, sizeof(buf));
+	if (cc != sizeof(buf) )
+		p_error("Lost the connection");
+	cc = read(sockt, buf, sizeof(buf));
+	if (cc != sizeof(buf) )
+		p_error("Lost the connection");
+	his_win.cerase = buf[0];
+	his_win.kill = buf[1];
+	his_win.werase = buf[2];
+}
+
+void
+sig_sent()
+{
+
+	message("Connection closing. Exiting");
+	quit();
+}
+
+/*
+ * All done talking...hang up the phone and reset terminal thingy's
+ */
+quit()
+{
+
+	if (curses_initialized) {
+		wmove(his_win.x_win, his_win.x_nlines-1, 0);
+		wclrtoeol(his_win.x_win);
+		wrefresh(his_win.x_win);
+		endwin();
+	}
+	if (invitation_waiting)
+		send_delete();
+	exit(0);
+}
diff --git a/talk.tproj/invite.c b/talk.tproj/invite.c
new file mode 100644
index 0000000..47fbf44
--- /dev/null
+++ b/talk.tproj/invite.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <netinet/in.h>
+#include <protocols/talkd.h>
+#include <errno.h>
+#include <setjmp.h>
+#include "talk_ctl.h"
+#include "talk.h"
+
+/*
+ * There wasn't an invitation waiting, so send a request containing
+ * our sockt address to the remote talk daemon so it can invite
+ * him 
+ */
+
+/*
+ * The msg.id's for the invitations
+ * on the local and remote machines.
+ * These are used to delete the 
+ * invitations.
+ */
+int	local_id, remote_id;
+void	re_invite();
+jmp_buf invitebuf;
+
+invite_remote()
+{
+	int nfd, read_mask, template, new_sockt;
+	struct itimerval itimer;
+	CTL_RESPONSE response;
+
+	itimer.it_value.tv_sec = RING_WAIT;
+	itimer.it_value.tv_usec = 0;
+	itimer.it_interval = itimer.it_value;
+	if (listen(sockt, 5) != 0)
+		p_error("Error on attempt to listen for caller");
+#ifdef MSG_EOR
+	/* copy new style sockaddr to old, swap family (short in old) */
+	msg.addr = *(struct osockaddr *)&my_addr;  /* XXX new to old  style*/
+	msg.addr.sa_family = htons(my_addr.sin_family);
+#else
+	msg.addr = *(struct sockaddr *)&my_addr;
+#endif
+	msg.id_num = htonl(-1);		/* an impossible id_num */
+	invitation_waiting = 1;
+	announce_invite();
+	/*
+	 * Shut off the automatic messages for a while,
+	 * so we can use the interupt timer to resend the invitation
+	 */
+	end_msgs();
+	setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
+	message("Waiting for your party to respond");
+	signal(SIGALRM, re_invite);
+	(void) setjmp(invitebuf);
+	while ((new_sockt = accept(sockt, 0, 0)) < 0) {
+		if (errno == EINTR)
+			continue;
+		p_error("Unable to connect with your party");
+	}
+	close(sockt);
+	sockt = new_sockt;
+
+	/*
+	 * Have the daemons delete the invitations now that we
+	 * have connected.
+	 */
+	current_state = "Waiting for your party to respond";
+	start_msgs();
+
+	msg.id_num = htonl(local_id);
+	ctl_transact(my_machine_addr, msg, DELETE, &response);
+	msg.id_num = htonl(remote_id);
+	ctl_transact(his_machine_addr, msg, DELETE, &response);
+	invitation_waiting = 0;
+}
+
+/*
+ * Routine called on interupt to re-invite the callee
+ */
+void
+re_invite()
+{
+
+	message("Ringing your party again");
+	current_line++;
+	/* force a re-announce */
+	msg.id_num = htonl(remote_id + 1);
+	announce_invite();
+	longjmp(invitebuf, 1);
+}
+
+static	char *answers[] = {
+	"answer #0",					/* SUCCESS */
+	"Your party is not logged on",			/* NOT_HERE */
+	"Target machine is too confused to talk to us",	/* FAILED */
+	"Target machine does not recognize us",		/* MACHINE_UNKNOWN */
+	"Your party is refusing messages",		/* PERMISSION_REFUSED */
+	"Target machine can not handle remote talk",	/* UNKNOWN_REQUEST */
+	"Target machine indicates protocol mismatch",	/* BADVERSION */
+	"Target machine indicates protocol botch (addr)",/* BADADDR */
+	"Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */
+};
+#define	NANSWERS	(sizeof (answers) / sizeof (answers[0]))
+
+/*
+ * Transmit the invitation and process the response
+ */
+announce_invite()
+{
+	CTL_RESPONSE response;
+
+	current_state = "Trying to connect to your party's talk daemon";
+	ctl_transact(his_machine_addr, msg, ANNOUNCE, &response);
+	remote_id = response.id_num;
+	if (response.answer != SUCCESS) {
+		if (response.answer < NANSWERS)
+			message(answers[response.answer]);
+		quit();
+	}
+	/* leave the actual invitation on my talk daemon */
+	ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response);
+	local_id = response.id_num;
+}
+
+/*
+ * Tell the daemon to remove your invitation
+ */
+send_delete()
+{
+
+	msg.type = DELETE;
+	/*
+	 * This is just a extra clean up, so just send it
+	 * and don't wait for an answer
+	 */
+	msg.id_num = htonl(remote_id);
+	daemon_addr.sin_addr = his_machine_addr;
+	if (sendto(ctl_sockt, &msg, sizeof (msg), 0,
+	    (struct sockaddr *)&daemon_addr,
+	    sizeof (daemon_addr)) != sizeof(msg))
+		perror("send_delete (remote)");
+	msg.id_num = htonl(local_id);
+	daemon_addr.sin_addr = my_machine_addr;
+	if (sendto(ctl_sockt, &msg, sizeof (msg), 0,
+	    (struct sockaddr *)&daemon_addr,
+	    sizeof (daemon_addr)) != sizeof (msg))
+		perror("send_delete (local)");
+}
diff --git a/talk.tproj/io.c b/talk.tproj/io.c
new file mode 100644
index 0000000..efd3c30
--- /dev/null
+++ b/talk.tproj/io.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/*
+ * This file contains the I/O handling and the exchange of 
+ * edit characters. This connection itself is established in
+ * ctl.c
+ */
+
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include "talk.h"
+
+#define A_LONG_TIME 10000000
+#define STDIN_MASK (1<<fileno(stdin))	/* the bit mask for standard
+					   input */
+
+/*
+ * The routine to do the actual talking
+ */
+talk()
+{
+	register int read_template, sockt_mask;
+	int read_set, nb;
+	char buf[BUFSIZ];
+	struct timeval wait;
+
+	message("Connection established\007\007\007");
+	current_line = 0;
+	sockt_mask = (1<<sockt);
+
+	/*
+	 * Wait on both the other process (sockt_mask) and 
+	 * standard input ( STDIN_MASK )
+	 */
+	read_template = sockt_mask | STDIN_MASK;
+	for (;;) {
+		read_set = read_template;
+		wait.tv_sec = A_LONG_TIME;
+		wait.tv_usec = 0;
+		nb = select(32, &read_set, 0, 0, &wait);
+		if (nb <= 0) {
+			if (errno == EINTR) {
+				read_set = read_template;
+				continue;
+			}
+			/* panic, we don't know what happened */
+			p_error("Unexpected error from select");
+			quit();
+		}
+		if (read_set & sockt_mask) { 
+			/* There is data on sockt */
+			nb = read(sockt, buf, sizeof buf);
+			if (nb <= 0) {
+				message("Connection closed. Exiting");
+				quit();
+			}
+			display(&his_win, buf, nb);
+		}
+		if (read_set & STDIN_MASK) {
+			/*
+			 * We can't make the tty non_blocking, because
+			 * curses's output routines would screw up
+			 */
+			ioctl(0, FIONREAD, (struct sgttyb *) &nb);
+			nb = read(0, buf, nb);
+			display(&my_win, buf, nb);
+			/* might lose data here because sockt is non-blocking */
+			write(sockt, buf, nb);
+		}
+	}
+}
+
+extern	int errno;
+extern	int sys_nerr;
+
+/*
+ * p_error prints the system error message on the standard location
+ * on the screen and then exits. (i.e. a curses version of perror)
+ */
+p_error(string) 
+	char *string;
+{
+	wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
+	wprintw(my_win.x_win, "[%s : %s (%d)]\n",
+	    string, strerror(errno), errno);
+	wrefresh(my_win.x_win);
+	move(LINES-1, 0);
+	refresh();
+	quit();
+}
+
+/*
+ * Display string in the standard location
+ */
+message(string)
+	char *string;
+{
+	wmove(my_win.x_win, current_line % my_win.x_nlines, 0);
+	wprintw(my_win.x_win, "[%s]", string);
+	wclrtoeol(my_win.x_win);
+	current_line++;
+	wmove(my_win.x_win, current_line % my_win.x_nlines, 0);
+	wrefresh(my_win.x_win);
+}
diff --git a/talk.tproj/look_up.c b/talk.tproj/look_up.c
new file mode 100644
index 0000000..3d46cb3
--- /dev/null
+++ b/talk.tproj/look_up.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <protocols/talkd.h>
+#include <errno.h>
+#include "talk_ctl.h"
+#include "talk.h"
+
+/*
+ * See if the local daemon has an invitation for us.
+ */
+check_local()
+{
+	CTL_RESPONSE response;
+	register CTL_RESPONSE *rp = &response;
+
+	/* the rest of msg was set up in get_names */
+#ifdef MSG_EOR
+	/* copy new style sockaddr to old, swap family (short in old) */
+	msg.ctl_addr = *(struct osockaddr *)&ctl_addr;
+	msg.ctl_addr.sa_family = htons(ctl_addr.sin_family);
+#else
+	msg.ctl_addr = *(struct sockaddr *)&ctl_addr;
+#endif
+	/* must be initiating a talk */
+	if (!look_for_invite(rp))
+		return (0);
+	/*
+	 * There was an invitation waiting for us, 
+	 * so connect with the other (hopefully waiting) party 
+	 */
+	current_state = "Waiting to connect with caller";
+	do {
+		if (rp->addr.sa_family != AF_INET)
+			p_error("Response uses invalid network address");
+		errno = 0;
+		if (connect(sockt,
+		    (struct sockaddr *)&rp->addr, sizeof (rp->addr)) != -1)
+			return (1);
+	} while (errno == EINTR);
+	if (errno == ECONNREFUSED) {
+		/*
+		 * The caller gave up, but his invitation somehow
+		 * was not cleared. Clear it and initiate an 
+		 * invitation. (We know there are no newer invitations,
+		 * the talkd works LIFO.)
+		 */
+		ctl_transact(his_machine_addr, msg, DELETE, rp);
+		close(sockt);
+		open_sockt();
+		return (0);
+	}
+	p_error("Unable to connect with initiator");
+	/*NOTREACHED*/
+}
+
+/*
+ * Look for an invitation on 'machine'
+ */
+look_for_invite(rp)
+	CTL_RESPONSE *rp;
+{
+	struct in_addr machine_addr;
+
+	current_state = "Checking for invitation on caller's machine";
+	ctl_transact(his_machine_addr, msg, LOOK_UP, rp);
+	/* the switch is for later options, such as multiple invitations */
+	switch (rp->answer) {
+
+	case SUCCESS:
+		msg.id_num = htonl(rp->id_num);
+		return (1);
+
+	default:
+		/* there wasn't an invitation waiting for us */
+		return (0);
+	}
+}
diff --git a/talk.tproj/msgs.c b/talk.tproj/msgs.c
new file mode 100644
index 0000000..7e1edb1
--- /dev/null
+++ b/talk.tproj/msgs.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/* 
+ * A package to display what is happening every MSG_INTERVAL seconds
+ * if we are slow connecting.
+ */
+
+#include <sys/time.h>
+#include <signal.h>
+#include <stdio.h>
+#include "talk.h"
+
+#define MSG_INTERVAL 4
+
+char	*current_state;
+int	current_line = 0;
+
+void
+disp_msg()
+{
+	message(current_state);
+}
+
+start_msgs()
+{
+	struct itimerval itimer;
+
+	message(current_state);
+	signal(SIGALRM, disp_msg);
+	itimer.it_value.tv_sec = itimer.it_interval.tv_sec = MSG_INTERVAL;
+	itimer.it_value.tv_usec = itimer.it_interval.tv_usec = 0;
+	setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
+}
+
+end_msgs()
+{
+	struct itimerval itimer;
+
+	timerclear(&itimer.it_value);
+	timerclear(&itimer.it_interval);
+	setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
+	signal(SIGALRM, SIG_DFL);
+}
diff --git a/talk.tproj/talk.1 b/talk.tproj/talk.1
new file mode 100644
index 0000000..18c3304
--- /dev/null
+++ b/talk.tproj/talk.1
@@ -0,0 +1,129 @@
+.\" Copyright (c) 1983, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)talk.1	8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt TALK 1
+.Os BSD 4.2
+.Sh NAME
+.Nm talk
+.Nd talk to another user
+.Sh SYNOPSIS
+.Nm talk
+.Ar person
+.Op Ar ttyname
+.Sh DESCRIPTION
+.Nm Talk
+is a visual communication program which copies lines from your
+terminal to that of another user.
+.Pp
+Options available:
+.Bl -tag -width ttyname
+.It Ar person
+If you wish to talk to someone on your own machine, then
+.Ar person
+is just the person's login name.  If you wish to talk to a user on
+another host, then
+.Ar person
+is of the form
+.Ql user@host .
+.It Ar ttyname
+If you wish to talk to a user who is logged in more than once, the
+.Ar ttyname
+argument may be used to indicate the appropriate terminal
+name, where
+.Ar ttyname
+is of the form
+.Ql ttyXX .
+.El
+.Pp
+When first called,
+.Nm talk
+sends the message
+.Bd -literal -offset indent -compact
+Message from TalkDaemon@his_machine...
+talk: connection requested by your_name@your_machine.
+talk: respond with: talk your_name@your_machine
+.Ed
+.Pp
+to the user you wish to talk to. At this point, the recipient
+of the message should reply by typing
+.Pp
+.Dl talk \ your_name@your_machine
+.Pp
+It doesn't matter from which machine the recipient replies, as
+long as his login-name is the same.  Once communication is established,
+the two parties may type simultaneously, with their output appearing
+in separate windows.  Typing control-L
+.Ql ^L
+will cause the screen to
+be reprinted, while your erase, kill, and word kill characters will
+behave normally.  To exit, just type your interrupt character;
+.Nm talk
+then moves the cursor to the bottom of the screen and restores the
+terminal to its previous state.
+.Pp
+Permission to talk may be denied or granted by use of the
+.Xr mesg 1
+command.  At the outset talking is allowed.  Certain commands, in
+particular
+.Xr nroff 1
+and
+.Xr pr 1 ,
+disallow messages in order to
+prevent messy output.
+.Pp
+.Sh FILES
+.Bl -tag -width /var/run/utmp -compact
+.It Pa /etc/hosts
+to find the recipient's machine
+.It Pa /var/run/utmp
+to find the recipient's tty
+.El
+.Sh SEE ALSO
+.Xr mail 1 ,
+.Xr mesg 1 ,
+.Xr who 1 ,
+.Xr write 1
+.Sh BUGS
+The version of
+.Xr talk 1
+released with
+.Bx 4.3
+uses a protocol that
+is incompatible with the protocol used in the version released with
+.Bx 4.2 .
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/talk.tproj/talk.c b/talk.tproj/talk.c
new file mode 100644
index 0000000..3690d01
--- /dev/null
+++ b/talk.tproj/talk.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#include "talk.h"
+
+/*
+ * talk:	A visual form of write. Using sockets, a two way 
+ *		connection is set up between the two people talking. 
+ *		With the aid of curses, the screen is split into two 
+ *		windows, and each users text is added to the window,
+ *		one character at a time...
+ *
+ *		Written by Kipp Hickman
+ *		
+ *		Modified to run under 4.1a by Clem Cole and Peter Moore
+ *		Modified to run between hosts by Peter Moore, 8/19/82
+ *		Modified to run under 4.1c by Peter Moore 3/17/83
+ */
+
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	get_names(argc, argv);
+	init_display();
+	open_ctl();
+	open_sockt();
+	start_msgs();
+	if (!check_local())
+		invite_remote();
+	end_msgs();
+	set_edit_chars();
+	talk();
+}
diff --git a/talk.tproj/talk.h b/talk.tproj/talk.h
new file mode 100644
index 0000000..2458247
--- /dev/null
+++ b/talk.tproj/talk.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)talk.h	8.1 (Berkeley) 6/6/93
+ */
+
+#include <curses.h>
+
+extern	int sockt;
+extern	int curses_initialized;
+extern	int invitation_waiting;
+
+extern	char *current_state;
+extern	int current_line;
+
+typedef struct xwin {
+	WINDOW	*x_win;
+	int	x_nlines;
+	int	x_ncols;
+	int	x_line;
+	int	x_col;
+	char	kill;
+	char	cerase;
+	char	werase;
+} xwin_t;
+
+extern	xwin_t my_win;
+extern	xwin_t his_win;
+extern	WINDOW *line_win;
diff --git a/talk.tproj/talk_ctl.h b/talk.tproj/talk_ctl.h
new file mode 100644
index 0000000..bfe8416
--- /dev/null
+++ b/talk.tproj/talk_ctl.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)talk_ctl.h	8.1 (Berkeley) 6/6/93
+ */
+
+extern	struct sockaddr_in daemon_addr;
+extern	struct sockaddr_in ctl_addr;
+extern	struct sockaddr_in my_addr;
+extern	struct in_addr my_machine_addr;
+extern	struct in_addr his_machine_addr;
+extern	u_short daemon_port;
+extern	int ctl_sockt;
+extern	CTL_MSG msg;
diff --git a/talkd.tproj/Makefile b/talkd.tproj/Makefile
new file mode 100644
index 0000000..e727fa6
--- /dev/null
+++ b/talkd.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ntalkd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = talkd.h
+
+CFILES = announce.c print.c process.c table.c talkd.c
+
+OTHERSRCS = Makefile Makefile.dist Makefile.postamble Makefile.preamble\
+            talkd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/talkd.tproj/Makefile.dist b/talkd.tproj/Makefile.dist
new file mode 100644
index 0000000..51f6806
--- /dev/null
+++ b/talkd.tproj/Makefile.dist
@@ -0,0 +1,8 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/4/93
+
+PROG=	ntalkd
+SRCS=	talkd.c announce.c process.c table.c print.c ttymsg.c
+.PATH:  ${.CURDIR}/../../usr.bin/wall
+MAN8=	talkd.0
+
+.include <bsd.prog.mk>
diff --git a/talkd.tproj/Makefile.postamble b/talkd.tproj/Makefile.postamble
new file mode 100644
index 0000000..9d4f92c
--- /dev/null
+++ b/talkd.tproj/Makefile.postamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
+VPATH += :../wall.tproj
+
diff --git a/talkd.tproj/Makefile.preamble b/talkd.tproj/Makefile.preamble
new file mode 100644
index 0000000..9764639
--- /dev/null
+++ b/talkd.tproj/Makefile.preamble
@@ -0,0 +1,120 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR = 
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES= ttymsg.o
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+OTHER_OFILES = ttymsg.o
+-include ../Makefile.include
diff --git a/talkd.tproj/PB.project b/talkd.tproj/PB.project
new file mode 100644
index 0000000..15be3ec
--- /dev/null
+++ b/talkd.tproj/PB.project
@@ -0,0 +1,39 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (talkd.h); 
+        M_FILES = (); 
+        OTHER_LINKED = (announce.c, print.c, process.c, table.c, talkd.c); 
+        OTHER_SOURCES = (Makefile, Makefile.dist, Makefile.postamble, Makefile.preamble, talkd.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ntalkd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/talkd.tproj/announce.c b/talkd.tproj/announce.c
new file mode 100644
index 0000000..cda84a1
--- /dev/null
+++ b/talkd.tproj/announce.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)announce.c	8.3 (Berkeley) 1/7/94";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <protocols/talkd.h>
+#include <sgtty.h>
+#include <errno.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
+#include <vis.h>
+#include "talkd.h"
+
+extern char hostname[];
+
+int print_mesg __P((char *tty, CTL_MSG *request, char *remote_machine));
+
+/*
+ * Announce an invitation to talk.
+ */
+	
+/*
+ * See if the user is accepting messages. If so, announce that 
+ * a talk is requested.
+ */
+int
+announce(request, remote_machine)
+	CTL_MSG *request;
+	char *remote_machine;
+{
+	char full_tty[32];
+	struct stat stbuf;
+
+	(void)snprintf(full_tty, sizeof(full_tty),
+	    "%s%s", _PATH_DEV, request->r_tty);
+	if (stat(full_tty, &stbuf) < 0 || (stbuf.st_mode&020) == 0)
+		return (PERMISSION_DENIED);
+	return (print_mesg(request->r_tty, request, remote_machine));
+}
+
+#define max(a,b) ( (a) > (b) ? (a) : (b) )
+#define N_LINES 5
+#define N_CHARS 256
+
+/*
+ * Build a block of characters containing the message. 
+ * It is sent blank filled and in a single block to
+ * try to keep the message in one piece if the recipient
+ * in in vi at the time
+ */
+int
+print_mesg(tty, request, remote_machine)
+	char *tty;
+	CTL_MSG *request;
+	char *remote_machine;
+{
+	struct timeval clock;
+	struct timezone zone;
+	struct tm *localtime();
+	struct tm *localclock;
+	struct iovec iovec;
+	char line_buf[N_LINES][N_CHARS];
+	int sizes[N_LINES];
+	char big_buf[N_LINES*N_CHARS];
+	char *bptr, *lptr, *vis_user;
+	int i, j, max_size;
+
+	i = 0;
+	max_size = 0;
+	gettimeofday(&clock, &zone);
+	localclock = localtime( &clock.tv_sec );
+	(void)snprintf(line_buf[i], N_CHARS, " ");
+	sizes[i] = strlen(line_buf[i]);
+	max_size = max(max_size, sizes[i]);
+	i++;
+	(void)snprintf(line_buf[i], N_CHARS,
+		"Message from Talk_Daemon@%s at %d:%02d ...",
+		hostname, localclock->tm_hour , localclock->tm_min );
+	sizes[i] = strlen(line_buf[i]);
+	max_size = max(max_size, sizes[i]);
+	i++;
+
+	vis_user = malloc(strlen(request->l_name) * 4 + 1);
+	strvis(vis_user, request->l_name, VIS_CSTYLE);
+	(void)snprintf(line_buf[i], N_CHARS,
+	"talk: connection requested by %s@%s", vis_user, remote_machine);
+	sizes[i] = strlen(line_buf[i]);
+	max_size = max(max_size, sizes[i]);
+	i++;
+	(void)snprintf(line_buf[i], N_CHARS, "talk: respond with:  talk %s@%s",
+	vis_user, remote_machine);
+	sizes[i] = strlen(line_buf[i]);
+	max_size = max(max_size, sizes[i]);
+	i++;
+	(void)snprintf(line_buf[i], N_CHARS, " ");
+	sizes[i] = strlen(line_buf[i]);
+	max_size = max(max_size, sizes[i]);
+	i++;
+	bptr = big_buf;
+	*bptr++ = ''; /* send something to wake them up */
+	*bptr++ = '\r';	/* add a \r in case of raw mode */
+	*bptr++ = '\n';
+	for (i = 0; i < N_LINES; i++) {
+		/* copy the line into the big buffer */
+		lptr = line_buf[i];
+		while (*lptr != '\0')
+			*(bptr++) = *(lptr++);
+		/* pad out the rest of the lines with blanks */
+		for (j = sizes[i]; j < max_size + 2; j++)
+			*(bptr++) = ' ';
+		*(bptr++) = '\r';	/* add a \r in case of raw mode */
+		*(bptr++) = '\n';
+	}
+	*bptr = '\0';
+	iovec.iov_base = big_buf;
+	iovec.iov_len = bptr - big_buf;
+	/*
+	 * we choose a timeout of RING_WAIT-5 seconds so that we don't
+	 * stack up processes trying to write messages to a tty
+	 * that is permanently blocked.
+	 */
+	if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL)
+		return (FAILED);
+
+	return (SUCCESS);
+}
diff --git a/talkd.tproj/print.c b/talkd.tproj/print.c
new file mode 100644
index 0000000..74f7aa8
--- /dev/null
+++ b/talkd.tproj/print.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)print.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* debug print routines */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <protocols/talkd.h>
+#include <syslog.h>
+#include <stdio.h>
+
+static	char *types[] =
+    { "leave_invite", "look_up", "delete", "announce" };
+#define	NTYPES	(sizeof (types) / sizeof (types[0]))
+static	char *answers[] = 
+    { "success", "not_here", "failed", "machine_unknown", "permission_denied",
+      "unknown_request", "badversion", "badaddr", "badctladdr" };
+#define	NANSWERS	(sizeof (answers) / sizeof (answers[0]))
+
+void
+print_request(cp, mp)
+	char *cp;
+	register CTL_MSG *mp;
+{
+	char tbuf[80], *tp;
+	
+	if (mp->type > NTYPES) {
+		(void)sprintf(tbuf, "type %d", mp->type);
+		tp = tbuf;
+	} else
+		tp = types[mp->type];
+	syslog(LOG_DEBUG, "%s: %s: id %d, l_user %s, r_user %s, r_tty %s",
+	    cp, tp, mp->id_num, mp->l_name, mp->r_name, mp->r_tty);
+}
+
+void
+print_response(cp, rp)
+	char *cp;
+	register CTL_RESPONSE *rp;
+{
+	char tbuf[80], *tp, abuf[80], *ap;
+	
+	if (rp->type > NTYPES) {
+		(void)sprintf(tbuf, "type %d", rp->type);
+		tp = tbuf;
+	} else
+		tp = types[rp->type];
+	if (rp->answer > NANSWERS) {
+		(void)sprintf(abuf, "answer %d", rp->answer);
+		ap = abuf;
+	} else
+		ap = answers[rp->answer];
+	syslog(LOG_DEBUG, "%s: %s: %s, id %d", cp, tp, ap, ntohl(rp->id_num));
+}
diff --git a/talkd.tproj/process.c b/talkd.tproj/process.c
new file mode 100644
index 0000000..c7d7b2c
--- /dev/null
+++ b/talkd.tproj/process.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)process.c	8.2 (Berkeley) 11/16/93";
+#endif /* not lint */
+
+/*
+ * process.c handles the requests, which can be of three types:
+ *	ANNOUNCE - announce to a user that a talk is wanted
+ *	LEAVE_INVITE - insert the request into the table
+ *	LOOK_UP - look up to see if a request is waiting in
+ *		  in the table for the local user
+ *	DELETE - delete invitation
+ */
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <protocols/talkd.h>
+#include <netdb.h>
+#include <syslog.h>
+#include <stdio.h>
+#include <string.h>
+#include <paths.h>
+#include "talkd.h"
+
+CTL_MSG *find_request();
+CTL_MSG *find_match();
+
+void
+process_request(mp, rp)
+	register CTL_MSG *mp;
+	register CTL_RESPONSE *rp;
+{
+	register CTL_MSG *ptr;
+	extern int debug;
+
+	rp->vers = TALK_VERSION;
+	rp->type = mp->type;
+	rp->id_num = htonl(0);
+	if (mp->vers != TALK_VERSION) {
+		syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
+		rp->answer = BADVERSION;
+		return;
+	}
+	mp->id_num = ntohl(mp->id_num);
+	mp->addr.sa_family = ntohs(mp->addr.sa_family);
+	if (mp->addr.sa_family != AF_INET) {
+		syslog(LOG_WARNING, "Bad address, family %d",
+		    mp->addr.sa_family);
+		rp->answer = BADADDR;
+		return;
+	}
+	mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family);
+	if (mp->ctl_addr.sa_family != AF_INET) {
+		syslog(LOG_WARNING, "Bad control address, family %d",
+		    mp->ctl_addr.sa_family);
+		rp->answer = BADCTLADDR;
+		return;
+	}
+	mp->pid = ntohl(mp->pid);
+	if (debug)
+		print_request("process_request", mp);
+	switch (mp->type) {
+
+	case ANNOUNCE:
+		do_announce(mp, rp);
+		break;
+
+	case LEAVE_INVITE:
+		ptr = find_request(mp);
+		if (ptr != (CTL_MSG *)0) {
+			rp->id_num = htonl(ptr->id_num);
+			rp->answer = SUCCESS;
+		} else
+			insert_table(mp, rp);
+		break;
+
+	case LOOK_UP:
+		ptr = find_match(mp);
+		if (ptr != (CTL_MSG *)0) {
+			rp->id_num = htonl(ptr->id_num);
+			rp->addr = ptr->addr;
+			rp->addr.sa_family = htons(ptr->addr.sa_family);
+			rp->answer = SUCCESS;
+		} else
+			rp->answer = NOT_HERE;
+		break;
+
+	case DELETE:
+		rp->answer = delete_invite(mp->id_num);
+		break;
+
+	default:
+		rp->answer = UNKNOWN_REQUEST;
+		break;
+	}
+	if (debug)
+		print_response("process_request", rp);
+}
+
+void
+do_announce(mp, rp)
+	register CTL_MSG *mp;
+	CTL_RESPONSE *rp;
+{
+	struct hostent *hp;
+	CTL_MSG *ptr;
+	int result;
+
+	/* see if the user is logged */
+	result = find_user(mp->r_name, mp->r_tty);
+	if (result != SUCCESS) {
+		rp->answer = result;
+		return;
+	}
+#define	satosin(sa)	((struct sockaddr_in *)(sa))
+	hp = gethostbyaddr((char *)&satosin(&mp->ctl_addr)->sin_addr,
+		sizeof (struct in_addr), AF_INET);
+	if (hp == (struct hostent *)0) {
+		rp->answer = MACHINE_UNKNOWN;
+		return;
+	}
+	ptr = find_request(mp);
+	if (ptr == (CTL_MSG *) 0) {
+		insert_table(mp, rp);
+		rp->answer = announce(mp, hp->h_name);
+		return;
+	}
+	if (mp->id_num > ptr->id_num) {
+		/*
+		 * This is an explicit re-announce, so update the id_num
+		 * field to avoid duplicates and re-announce the talk.
+		 */
+		ptr->id_num = new_id();
+		rp->id_num = htonl(ptr->id_num);
+		rp->answer = announce(mp, hp->h_name);
+	} else {
+		/* a duplicated request, so ignore it */
+		rp->id_num = htonl(ptr->id_num);
+		rp->answer = SUCCESS;
+	}
+}
+
+#include <utmp.h>
+
+/*
+ * Search utmp for the local user
+ */
+int
+find_user(name, tty)
+	char *name, *tty;
+{
+	struct utmp ubuf;
+	int status;
+	FILE *fd;
+	struct stat statb;
+	char line[sizeof(ubuf.ut_line) + 1];
+	char ftty[sizeof(_PATH_DEV) - 1 + sizeof(line)];
+
+	if ((fd = fopen(_PATH_UTMP, "r")) == NULL) {
+		fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP);
+		return (FAILED);
+	}
+#define SCMPN(a, b)	strncmp(a, b, sizeof (a))
+	status = NOT_HERE;
+	(void) strcpy(ftty, _PATH_DEV);
+	while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
+		if (SCMPN(ubuf.ut_name, name) == 0) {
+			strncpy(line, ubuf.ut_line, sizeof(ubuf.ut_line));
+			line[sizeof(ubuf.ut_line)] = '\0';
+			if (*tty == '\0') {
+				status = PERMISSION_DENIED;
+				/* no particular tty was requested */
+				(void) strcpy(ftty + sizeof(_PATH_DEV) - 1,
+				    line);
+				if (stat(ftty, &statb) == 0) {
+					if (!(statb.st_mode & 020))
+						continue;
+					(void) strcpy(tty, line);
+					status = SUCCESS;
+					break;
+				}
+			}
+			if (strcmp(line, tty) == 0) {
+				status = SUCCESS;
+				break;
+			}
+		}
+	fclose(fd);
+	return (status);
+}
diff --git a/talkd.tproj/table.c b/talkd.tproj/table.c
new file mode 100644
index 0000000..df3fb23
--- /dev/null
+++ b/talkd.tproj/table.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)table.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * Routines to handle insertion, deletion, etc on the table
+ * of requests kept by the daemon. Nothing fancy here, linear
+ * search on a double-linked list. A time is kept with each 
+ * entry so that overly old invitations can be eliminated.
+ *
+ * Consider this a mis-guided attempt at modularity
+ */
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <protocols/talkd.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "talkd.h"
+
+#define MAX_ID 16000	/* << 2^15 so I don't have sign troubles */
+
+#define NIL ((TABLE_ENTRY *)0)
+
+extern	int debug;
+struct	timeval tp;
+struct	timezone txp;
+
+typedef struct table_entry TABLE_ENTRY;
+
+struct table_entry {
+	CTL_MSG request;
+	long	time;
+	TABLE_ENTRY *next;
+	TABLE_ENTRY *last;
+};
+
+TABLE_ENTRY *table = NIL;
+CTL_MSG *find_request();
+CTL_MSG *find_match();
+
+void	delete __P((TABLE_ENTRY *ptr));
+
+/*
+ * Look in the table for an invitation that matches the current
+ * request looking for an invitation
+ */
+CTL_MSG *
+find_match(request)
+	register CTL_MSG *request;
+{
+	register TABLE_ENTRY *ptr;
+	time_t current_time;
+
+	gettimeofday(&tp, &txp);
+	current_time = tp.tv_sec;
+	if (debug)
+		print_request("find_match", request);
+	for (ptr = table; ptr != NIL; ptr = ptr->next) {
+		if ((ptr->time - current_time) > MAX_LIFE) {
+			/* the entry is too old */
+			if (debug)
+				print_request("deleting expired entry",
+				    &ptr->request);
+			delete(ptr);
+			continue;
+		}
+		if (debug)
+			print_request("", &ptr->request);
+		if (strcmp(request->l_name, ptr->request.r_name) == 0 &&
+		    strcmp(request->r_name, ptr->request.l_name) == 0 &&
+		     ptr->request.type == LEAVE_INVITE)
+			return (&ptr->request);
+	}
+	return ((CTL_MSG *)0);
+}
+
+/*
+ * Look for an identical request, as opposed to a complimentary
+ * one as find_match does 
+ */
+CTL_MSG *
+find_request(request)
+	register CTL_MSG *request;
+{
+	register TABLE_ENTRY *ptr;
+	time_t current_time;
+
+	gettimeofday(&tp, &txp);
+	current_time = tp.tv_sec;
+	/*
+	 * See if this is a repeated message, and check for
+	 * out of date entries in the table while we are it.
+	 */
+	if (debug)
+		print_request("find_request", request);
+	for (ptr = table; ptr != NIL; ptr = ptr->next) {
+		if ((ptr->time - current_time) > MAX_LIFE) {
+			/* the entry is too old */
+			if (debug)
+				print_request("deleting expired entry",
+				    &ptr->request);
+			delete(ptr);
+			continue;
+		}
+		if (debug)
+			print_request("", &ptr->request);
+		if (strcmp(request->r_name, ptr->request.r_name) == 0 &&
+		    strcmp(request->l_name, ptr->request.l_name) == 0 &&
+		    request->type == ptr->request.type &&
+		    request->pid == ptr->request.pid) {
+			/* update the time if we 'touch' it */
+			ptr->time = current_time;
+			return (&ptr->request);
+		}
+	}
+	return ((CTL_MSG *)0);
+}
+
+void
+insert_table(request, response)
+	CTL_MSG *request;
+	CTL_RESPONSE *response;
+{
+	register TABLE_ENTRY *ptr;
+	time_t current_time;
+
+	gettimeofday(&tp, &txp);
+	current_time = tp.tv_sec;
+	request->id_num = new_id();
+	response->id_num = htonl(request->id_num);
+	/* insert a new entry into the top of the list */
+	ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY));
+	if (ptr == NIL) {
+		syslog(LOG_ERR, "insert_table: Out of memory");
+		_exit(1);
+	}
+	ptr->time = current_time;
+	ptr->request = *request;
+	ptr->next = table;
+	if (ptr->next != NIL)
+		ptr->next->last = ptr;
+	ptr->last = NIL;
+	table = ptr;
+}
+
+/*
+ * Generate a unique non-zero sequence number
+ */
+int
+new_id()
+{
+	static int current_id = 0;
+
+	current_id = (current_id + 1) % MAX_ID;
+	/* 0 is reserved, helps to pick up bugs */
+	if (current_id == 0)
+		current_id = 1;
+	return (current_id);
+}
+
+/*
+ * Delete the invitation with id 'id_num'
+ */
+int
+delete_invite(id_num)
+	int id_num;
+{
+	register TABLE_ENTRY *ptr;
+
+	ptr = table;
+	if (debug)
+		syslog(LOG_DEBUG, "delete_invite(%d)", id_num);
+	for (ptr = table; ptr != NIL; ptr = ptr->next) {
+		if (ptr->request.id_num == id_num)
+			break;
+		if (debug)
+			print_request("", &ptr->request);
+	}
+	if (ptr != NIL) {
+		delete(ptr);
+		return (SUCCESS);
+	}
+	return (NOT_HERE);
+}
+
+/*
+ * Classic delete from a double-linked list
+ */
+void
+delete(ptr)
+	register TABLE_ENTRY *ptr;
+{
+
+	if (debug)
+		print_request("delete", &ptr->request);
+	if (table == ptr)
+		table = ptr->next;
+	else if (ptr->last != NIL)
+		ptr->last->next = ptr->next;
+	if (ptr->next != NIL)
+		ptr->next->last = ptr->last;
+	free((char *)ptr);
+}
diff --git a/talkd.tproj/talkd.8 b/talkd.tproj/talkd.8
new file mode 100644
index 0000000..36dfb28
--- /dev/null
+++ b/talkd.tproj/talkd.8
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)talkd.8	8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt TALKD 8
+.Os BSD 4.3
+.Sh NAME
+.Nm talkd
+.Nd remote user communication server
+.Sh SYNOPSIS
+.Nm talkd
+.Sh DESCRIPTION
+.Nm Talkd
+is the server that notifies a user that someone else wants to
+initiate a conversation.
+It acts as a repository of invitations, responding to requests
+by clients wishing to rendezvous to hold a conversation.
+In normal operation, a client, the caller,
+initiates a rendezvous by sending a
+.Tn CTL_MSG
+to the server of
+type
+.Tn LOOK_UP
+(see
+.Aq Pa protocols/talkd.h ) .
+This causes the server to search its invitation
+tables to check if an invitation currently exists for the caller
+(to speak to the callee specified in the message).
+If the lookup fails,
+the caller then sends an
+.Tn ANNOUNCE
+message causing the server to
+broadcast an announcement on the callee's login ports requesting contact.
+When the callee responds, the local server uses the
+recorded invitation to respond with the appropriate rendezvous
+address and the caller and callee client programs establish a
+stream connection through which the conversation takes place.
+.Sh SEE ALSO
+.Xr talk 1 ,
+.Xr write 1
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 .
diff --git a/talkd.tproj/talkd.c b/talkd.tproj/talkd.c
new file mode 100644
index 0000000..7281351
--- /dev/null
+++ b/talkd.tproj/talkd.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)talkd.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * The top level of the daemon, the format is heavily borrowed
+ * from rwhod.c. Basically: find out who and where you are; 
+ * disconnect all descriptors and ttys, and then endless
+ * loop on waiting for and processing requests
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <protocols/talkd.h>
+#include <signal.h>
+#include <syslog.h>
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
+#include <sys/param.h>
+#include "talkd.h"
+
+CTL_MSG		request;
+CTL_RESPONSE	response;
+
+int	sockt;
+int	debug = 0;
+void	timeout();
+long	lastmsgtime;
+
+char	hostname[MAXHOSTNAMELEN + 1];
+
+#define TIMEOUT 30
+#define MAXIDLE 120
+
+void
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register CTL_MSG *mp = &request;
+	int cc;
+
+	if (getuid()) {
+		fprintf(stderr, "%s: getuid: not super-user\n", argv[0]);
+		exit(1);
+	}
+	openlog("talkd", LOG_PID, LOG_DAEMON);
+	if (gethostname(hostname, sizeof (hostname) - 1) < 0) {
+		syslog(LOG_ERR, "gethostname: %m");
+		_exit(1);
+	}
+	if (chdir(_PATH_DEV) < 0) {
+		syslog(LOG_ERR, "chdir: %s: %m", _PATH_DEV);
+		_exit(1);
+	}
+	if (argc > 1 && strcmp(argv[1], "-d") == 0)
+		debug = 1;
+	signal(SIGALRM, timeout);
+	alarm(TIMEOUT);
+	for (;;) {
+		extern int errno;
+
+		cc = recv(0, (char *)mp, sizeof (*mp), 0);
+		if (cc != sizeof (*mp)) {
+			if (cc < 0 && errno != EINTR)
+				syslog(LOG_WARNING, "recv: %m");
+			continue;
+		}
+		lastmsgtime = time(0);
+		process_request(mp, &response);
+		/* can block here, is this what I want? */
+		cc = sendto(sockt, (char *)&response,
+		    sizeof (response), 0, (struct sockaddr *)&mp->ctl_addr,
+		    sizeof (mp->ctl_addr));
+		if (cc != sizeof (response))
+			syslog(LOG_WARNING, "sendto: %m");
+	}
+}
+
+void
+timeout()
+{
+
+	if (time(0) - lastmsgtime >= MAXIDLE)
+		_exit(0);
+	alarm(TIMEOUT);
+}
diff --git a/talkd.tproj/talkd.h b/talkd.tproj/talkd.h
new file mode 100644
index 0000000..9a686c5
--- /dev/null
+++ b/talkd.tproj/talkd.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+extern int	announce __P((CTL_MSG *request, char *remote_machine));
+extern void	do_announce __P((CTL_MSG *mp, CTL_RESPONSE *rp));
+extern int	delete_invite __P((int id_num));
+extern int	find_user __P((char *name, char *tty));
+extern void	insert_table __P((CTL_MSG *request, CTL_RESPONSE *response));
+extern int	new_id __P((void));
+extern void	print_request __P((char *cp, CTL_MSG *mp));
+extern void	print_response __P((char *cp, CTL_RESPONSE *rp));
+extern void	process_request __P((CTL_MSG *mp, CTL_RESPONSE *rp));
diff --git a/tcpdump.tproj/Makefile b/tcpdump.tproj/Makefile
new file mode 100644
index 0000000..fb9c458
--- /dev/null
+++ b/tcpdump.tproj/Makefile
@@ -0,0 +1,63 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = tcpdump
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = machdep.h addrtoname.h ntp.h nfsfh.h igrp.h interface.h\
+         os-sunos4.h decnet.h ipx.h mib.h os-ultrix4.h netbios.h\
+         bootp.h ospf.h llc.h nfs.h os-solaris2.h nfsv2.h fddi.h\
+         gnuc.h ethertype.h extract.h appletalk.h
+
+CFILES = addrtoname.c bpf_dump.c machdep.c parsenfsfh.c print-arp.c\
+         print-atalk.c print-atm.c print-bootp.c print-decnet.c\
+         print-domain.c print-dvmrp.c print-egp.c print-ether.c\
+         print-fddi.c print-gre.c print-icmp.c print-igrp.c print-ip.c\
+         print-ipx.c print-isoclns.c print-krb.c print-llc.c\
+         print-netbios.c print-nfs.c print-ntp.c print-null.c\
+         print-ospf.c print-pim.c print-ppp.c print-rip.c print-skip.c\
+         print-sl.c print-snmp.c print-sunrpc.c print-tcp.c\
+         print-tftp.c print-udp.c print-wb.c strcasecmp.c tcpdump.c\
+         util.c version.c vfprintf.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+LIBS = -lpcap
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -traditional-cpp
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/tcpdump.tproj/Makefile.postamble b/tcpdump.tproj/Makefile.postamble
new file mode 100644
index 0000000..7823726
--- /dev/null
+++ b/tcpdump.tproj/Makefile.postamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
diff --git a/tcpdump.tproj/Makefile.preamble b/tcpdump.tproj/Makefile.preamble
new file mode 100644
index 0000000..faec713
--- /dev/null
+++ b/tcpdump.tproj/Makefile.preamble
@@ -0,0 +1,130 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS =-DRETSIGTYPE=void
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES =
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
diff --git a/tcpdump.tproj/PB.project b/tcpdump.tproj/PB.project
new file mode 100644
index 0000000..143e686
--- /dev/null
+++ b/tcpdump.tproj/PB.project
@@ -0,0 +1,98 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        CLASSES = (); 
+        FRAMEWORKS = (); 
+        H_FILES = (
+            machdep.h, 
+            addrtoname.h, 
+            ntp.h, 
+            nfsfh.h, 
+            igrp.h, 
+            interface.h, 
+            "os-sunos4.h", 
+            decnet.h, 
+            ipx.h, 
+            mib.h, 
+            "os-ultrix4.h", 
+            netbios.h, 
+            bootp.h, 
+            ospf.h, 
+            llc.h, 
+            nfs.h, 
+            "os-solaris2.h", 
+            nfsv2.h, 
+            fddi.h, 
+            gnuc.h, 
+            ethertype.h, 
+            extract.h, 
+            appletalk.h
+        ); 
+        OTHER_LIBS = (pcap); 
+        OTHER_LINKED = (
+            addrtoname.c, 
+            bpf_dump.c, 
+            machdep.c, 
+            parsenfsfh.c, 
+            "print-arp.c", 
+            "print-atalk.c", 
+            "print-atm.c", 
+            "print-bootp.c", 
+            "print-decnet.c", 
+            "print-domain.c", 
+            "print-dvmrp.c", 
+            "print-egp.c", 
+            "print-ether.c", 
+            "print-fddi.c", 
+            "print-gre.c", 
+            "print-icmp.c", 
+            "print-igrp.c", 
+            "print-ip.c", 
+            "print-ipx.c", 
+            "print-isoclns.c", 
+            "print-krb.c", 
+            "print-llc.c", 
+            "print-netbios.c", 
+            "print-nfs.c", 
+            "print-ntp.c", 
+            "print-null.c", 
+            "print-ospf.c", 
+            "print-pim.c", 
+            "print-ppp.c", 
+            "print-rip.c", 
+            "print-skip.c", 
+            "print-sl.c", 
+            "print-snmp.c", 
+            "print-sunrpc.c", 
+            "print-tcp.c", 
+            "print-tftp.c", 
+            "print-udp.c", 
+            "print-wb.c", 
+            strcasecmp.c, 
+            tcpdump.c, 
+            util.c, 
+            version.c, 
+            vfprintf.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-traditional-cpp"; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = tcpdump; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/tcpdump.tproj/addrtoname.c b/tcpdump.tproj/addrtoname.c
new file mode 100644
index 0000000..f940348
--- /dev/null
+++ b/tcpdump.tproj/addrtoname.c
@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *  Internet, ethernet, port, and protocol string to address
+ *  and address to string conversion routines
+ */
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/addrtoname.c,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <pcap-namedb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "llc.h"
+
+/* Forwards */
+static RETSIGTYPE nohostname(int);
+
+/*
+ * hash tables for whatever-to-name translations
+ */
+
+#define HASHNAMESIZE 4096
+
+struct hnamemem {
+	u_int32_t addr;
+	char *name;
+	struct hnamemem *nxt;
+};
+
+struct hnamemem hnametable[HASHNAMESIZE];
+struct hnamemem tporttable[HASHNAMESIZE];
+struct hnamemem uporttable[HASHNAMESIZE];
+struct hnamemem eprototable[HASHNAMESIZE];
+struct hnamemem dnaddrtable[HASHNAMESIZE];
+struct hnamemem llcsaptable[HASHNAMESIZE];
+
+struct enamemem {
+	u_short e_addr0;
+	u_short e_addr1;
+	u_short e_addr2;
+	char *e_name;
+	u_char *e_nsap;			/* used only for nsaptable[] */
+	struct enamemem *e_nxt;
+};
+
+struct enamemem enametable[HASHNAMESIZE];
+struct enamemem nsaptable[HASHNAMESIZE];
+
+struct protoidmem {
+	u_int32_t p_oui;
+	u_short p_proto;
+	char *p_name;
+	struct protoidmem *p_nxt;
+};
+
+struct protoidmem protoidtable[HASHNAMESIZE];
+
+/*
+ * A faster replacement for inet_ntoa().
+ */
+char *
+intoa(u_int32_t addr)
+{
+	register char *cp;
+	register u_int byte;
+	register int n;
+	static char buf[sizeof(".xxx.xxx.xxx.xxx")];
+
+	NTOHL(addr);
+	cp = &buf[sizeof buf];
+	*--cp = '\0';
+
+	n = 4;
+	do {
+		byte = addr & 0xff;
+		*--cp = byte % 10 + '0';
+		byte /= 10;
+		if (byte > 0) {
+			*--cp = byte % 10 + '0';
+			byte /= 10;
+			if (byte > 0)
+				*--cp = byte + '0';
+		}
+		*--cp = '.';
+		addr >>= 8;
+	} while (--n > 0);
+
+	return cp + 1;
+}
+
+static u_int32_t f_netmask;
+static u_int32_t f_localnet;
+static u_int32_t netmask;
+
+/*
+ * "getname" is written in this atrocious way to make sure we don't
+ * wait forever while trying to get hostnames from yp.
+ */
+#include <setjmp.h>
+
+jmp_buf getname_env;
+
+static RETSIGTYPE
+nohostname(int signo)
+{
+	longjmp(getname_env, 1);
+}
+
+/*
+ * Return a name for the IP address pointed to by ap.  This address
+ * is assumed to be in network byte order.
+ */
+char *
+getname(const u_char *ap)
+{
+	register struct hostent *hp;
+	u_int32_t addr;
+	static struct hnamemem *p;		/* static for longjmp() */
+
+#ifndef LBL_ALIGN
+	addr = *(const u_int32_t *)ap;
+#else
+	/*
+	 * Extract 32 bits in network order, dealing with alignment.
+	 */
+	switch ((long)ap & 3) {
+
+	case 0:
+		addr = *(u_int32_t *)ap;
+		break;
+
+	case 2:
+#ifdef WORDS_BIGENDIAN
+		addr = ((u_int32_t)*(u_short *)ap << 16) |
+			(u_int32_t)*(u_short *)(ap + 2);
+#else
+		addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) |
+			(u_int32_t)*(u_short *)ap;
+#endif
+		break;
+
+	default:
+#ifdef WORDS_BIGENDIAN
+		addr = ((u_int32_t)ap[0] << 24) |
+			((u_int32_t)ap[1] << 16) |
+			((u_int32_t)ap[2] << 8) |
+			(u_int32_t)ap[3];
+#else
+		addr = ((u_int32_t)ap[3] << 24) |
+			((u_int32_t)ap[2] << 16) |
+			((u_int32_t)ap[1] << 8) |
+			(u_int32_t)ap[0];
+#endif
+		break;
+	}
+#endif
+	p = &hnametable[addr & (HASHNAMESIZE-1)];
+	for (; p->nxt; p = p->nxt) {
+		if (p->addr == addr)
+			return (p->name);
+	}
+	p->addr = addr;
+	p->nxt = newhnamemem();
+
+	/*
+	 * Only print names when:
+	 *	(1) -n was not given.
+	 *	(2) Address is foreign and -f was given.  If -f was not
+	 *	    present, f_netmask and f_local are 0 and the second
+	 *	    test will succeed.
+	 *	(3) The host portion is not 0 (i.e., a network address).
+	 *	(4) The host portion is not broadcast.
+	 */
+	if (!nflag && (addr & f_netmask) == f_localnet
+	    && (addr &~ netmask) != 0 && (addr | netmask) != 0xffffffff) {
+		if (!setjmp(getname_env)) {
+			(void)signal(SIGALRM, nohostname);
+			(void)alarm(20);
+			hp = gethostbyaddr((char *)&addr, 4, AF_INET);
+			(void)alarm(0);
+			if (hp) {
+				char *dotp;
+
+				p->name = savestr(hp->h_name);
+				if (Nflag) {
+					/* Remove domain qualifications */
+					dotp = strchr(p->name, '.');
+					if (dotp)
+						*dotp = '\0';
+				}
+				return (p->name);
+			}
+		}
+	}
+	p->name = savestr(intoa(addr));
+	return (p->name);
+}
+
+static char hex[] = "0123456789abcdef";
+
+
+/* Find the hash node that corresponds the ether address 'ep' */
+
+static inline struct enamemem *
+lookup_emem(const u_char *ep)
+{
+	register u_int i, j, k;
+	struct enamemem *tp;
+
+	k = (ep[0] << 8) | ep[1];
+	j = (ep[2] << 8) | ep[3];
+	i = (ep[4] << 8) | ep[5];
+
+	tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
+	while (tp->e_nxt)
+		if (tp->e_addr0 == i &&
+		    tp->e_addr1 == j &&
+		    tp->e_addr2 == k)
+			return tp;
+		else
+			tp = tp->e_nxt;
+	tp->e_addr0 = i;
+	tp->e_addr1 = j;
+	tp->e_addr2 = k;
+	tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
+	if (tp->e_nxt == NULL)
+		error("lookup_emem: calloc");
+
+	return tp;
+}
+
+/* Find the hash node that corresponds the NSAP 'nsap' */
+
+static inline struct enamemem *
+lookup_nsap(register const u_char *nsap)
+{
+	register u_int i, j, k;
+	int nlen = *nsap;
+	struct enamemem *tp;
+	const u_char *ensap = nsap + nlen - 6;
+
+	if (nlen > 6) {
+		k = (ensap[0] << 8) | ensap[1];
+		j = (ensap[2] << 8) | ensap[3];
+		i = (ensap[4] << 8) | ensap[5];
+	}
+	else
+		i = j = k = 0;
+
+	tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
+	while (tp->e_nxt)
+		if (tp->e_addr0 == i &&
+		    tp->e_addr1 == j &&
+		    tp->e_addr2 == k &&
+		    tp->e_nsap[0] == nlen &&
+		    memcmp((char *)&(nsap[1]),
+			(char *)&(tp->e_nsap[1]), nlen) == 0)
+			return tp;
+		else
+			tp = tp->e_nxt;
+	tp->e_addr0 = i;
+	tp->e_addr1 = j;
+	tp->e_addr2 = k;
+	tp->e_nsap = (u_char *)malloc(nlen + 1);
+	if (tp->e_nsap == NULL)
+		error("lookup_nsap: malloc");
+	memcpy(tp->e_nsap, nsap, nlen + 1);
+	tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
+	if (tp->e_nxt == NULL)
+		error("lookup_nsap: calloc");
+
+	return tp;
+}
+
+/* Find the hash node that corresponds the protoid 'pi'. */
+
+static inline struct protoidmem *
+lookup_protoid(const u_char *pi)
+{
+	register u_int i, j;
+	struct protoidmem *tp;
+
+	/* 5 octets won't be aligned */
+	i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
+	j =   (pi[3] << 8) + pi[4];
+	/* XXX should be endian-insensitive, but do big-endian testing  XXX */
+
+	tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
+	while (tp->p_nxt)
+		if (tp->p_oui == i && tp->p_proto == j)
+			return tp;
+		else
+			tp = tp->p_nxt;
+	tp->p_oui = i;
+	tp->p_proto = j;
+	tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
+	if (tp->p_nxt == NULL)
+		error("lookup_protoid: calloc");
+
+	return tp;
+}
+
+char *
+etheraddr_string(register const u_char *ep)
+{
+	register u_int i, j;
+	register char *cp;
+	register struct enamemem *tp;
+	char buf[sizeof("00:00:00:00:00:00")];
+
+	tp = lookup_emem(ep);
+	if (tp->e_name)
+		return (tp->e_name);
+#ifdef HAVE_ETHER_NTOHOST
+	if (!nflag) {
+		char buf[128];
+		if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) {
+			tp->e_name = savestr(buf);
+			return (tp->e_name);
+		}
+	}
+#endif
+	cp = buf;
+	if ((j = *ep >> 4) != 0)
+		*cp++ = hex[j];
+	*cp++ = hex[*ep++ & 0xf];
+	for (i = 5; (int)--i >= 0;) {
+		*cp++ = ':';
+		if ((j = *ep >> 4) != 0)
+			*cp++ = hex[j];
+		*cp++ = hex[*ep++ & 0xf];
+	}
+	*cp = '\0';
+	tp->e_name = savestr(buf);
+	return (tp->e_name);
+}
+
+char *
+etherproto_string(u_short port)
+{
+	register char *cp;
+	register struct hnamemem *tp;
+	register u_int32_t i = port;
+	char buf[sizeof("0000")];
+
+	for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+		if (tp->addr == i)
+			return (tp->name);
+
+	tp->addr = i;
+	tp->nxt = newhnamemem();
+
+	cp = buf;
+	NTOHS(port);
+	*cp++ = hex[port >> 12 & 0xf];
+	*cp++ = hex[port >> 8 & 0xf];
+	*cp++ = hex[port >> 4 & 0xf];
+	*cp++ = hex[port & 0xf];
+	*cp++ = '\0';
+	tp->name = savestr(buf);
+	return (tp->name);
+}
+
+char *
+protoid_string(register const u_char *pi)
+{
+	register u_int i, j;
+	register char *cp;
+	register struct protoidmem *tp;
+	char buf[sizeof("00:00:00:00:00")];
+
+	tp = lookup_protoid(pi);
+	if (tp->p_name)
+		return tp->p_name;
+
+	cp = buf;
+	if ((j = *pi >> 4) != 0)
+		*cp++ = hex[j];
+	*cp++ = hex[*pi++ & 0xf];
+	for (i = 4; (int)--i >= 0;) {
+		*cp++ = ':';
+		if ((j = *pi >> 4) != 0)
+			*cp++ = hex[j];
+		*cp++ = hex[*pi++ & 0xf];
+	}
+	*cp = '\0';
+	tp->p_name = savestr(buf);
+	return (tp->p_name);
+}
+
+char *
+llcsap_string(u_char sap)
+{
+	register char *cp;
+	register struct hnamemem *tp;
+	register u_int32_t i = sap;
+	char buf[sizeof("sap 00")];
+
+	for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+		if (tp->addr == i)
+			return (tp->name);
+
+	tp->addr = i;
+	tp->nxt = newhnamemem();
+
+	cp = buf;
+	(void)strcpy(cp, "sap ");
+	cp += strlen(cp);
+	*cp++ = hex[sap >> 4 & 0xf];
+	*cp++ = hex[sap & 0xf];
+	*cp++ = '\0';
+	tp->name = savestr(buf);
+	return (tp->name);
+}
+
+char *
+isonsap_string(const u_char *nsap)
+{
+	register u_int i, nlen = nsap[0];
+	register char *cp;
+	register struct enamemem *tp;
+
+	tp = lookup_nsap(nsap);
+	if (tp->e_name)
+		return tp->e_name;
+
+	tp->e_name = cp = (char *)malloc(nlen * 2 + 2);
+	if (cp == NULL)
+		error("isonsap_string: malloc");
+
+	nsap++;
+	*cp++ = '/';
+	for (i = nlen; (int)--i >= 0;) {
+		*cp++ = hex[*nsap >> 4];
+		*cp++ = hex[*nsap++ & 0xf];
+	}
+	*cp = '\0';
+	return (tp->e_name);
+}
+
+char *
+tcpport_string(u_short port)
+{
+	register struct hnamemem *tp;
+	register u_int32_t i = port;
+	char buf[sizeof("00000")];
+
+	for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+		if (tp->addr == i)
+			return (tp->name);
+
+	tp->addr = i;
+	tp->nxt = newhnamemem();
+
+	(void)sprintf(buf, "%u", i);
+	tp->name = savestr(buf);
+	return (tp->name);
+}
+
+char *
+udpport_string(register u_short port)
+{
+	register struct hnamemem *tp;
+	register u_int32_t i = port;
+	char buf[sizeof("00000")];
+
+	for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+		if (tp->addr == i)
+			return (tp->name);
+
+	tp->addr = i;
+	tp->nxt = newhnamemem();
+
+	(void)sprintf(buf, "%u", i);
+	tp->name = savestr(buf);
+	return (tp->name);
+}
+
+static void
+init_servarray(void)
+{
+	struct servent *sv;
+	register struct hnamemem *table;
+	register int i;
+	char buf[sizeof("0000000000")];
+
+	while ((sv = getservent()) != NULL) {
+		int port = ntohs(sv->s_port);
+		i = port & (HASHNAMESIZE-1);
+		if (strcmp(sv->s_proto, "tcp") == 0)
+			table = &tporttable[i];
+		else if (strcmp(sv->s_proto, "udp") == 0)
+			table = &uporttable[i];
+		else
+			continue;
+
+		while (table->name)
+			table = table->nxt;
+		if (nflag) {
+			(void)sprintf(buf, "%d", port);
+			table->name = savestr(buf);
+		} else
+			table->name = savestr(sv->s_name);
+		table->addr = port;
+		table->nxt = newhnamemem();
+	}
+	endservent();
+}
+
+/*XXX from libbpfc.a */
+extern struct eproto {
+	char *s;
+	u_short p;
+} eproto_db[];
+
+static void
+init_eprotoarray(void)
+{
+	register int i;
+	register struct hnamemem *table;
+
+	for (i = 0; eproto_db[i].s; i++) {
+		int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1);
+		table = &eprototable[j];
+		while (table->name)
+			table = table->nxt;
+		table->name = eproto_db[i].s;
+		table->addr = ntohs(eproto_db[i].p);
+		table->nxt = newhnamemem();
+	}
+}
+
+/*
+ * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
+ * types.
+ */
+static void
+init_protoidarray(void)
+{
+	register int i;
+	register struct protoidmem *tp;
+	u_char protoid[5];
+
+	protoid[0] = 0;
+	protoid[1] = 0;
+	protoid[2] = 0;
+	for (i = 0; eproto_db[i].s; i++) {
+		u_short etype = htons(eproto_db[i].p);
+
+		memcpy((char *)&protoid[3], (char *)&etype, 2);
+		tp = lookup_protoid(protoid);
+		tp->p_name = savestr(eproto_db[i].s);
+	}
+}
+
+static struct etherlist {
+	u_char addr[6];
+	char *name;
+} etherlist[] = {
+	{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
+	{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
+};
+
+/*
+ * Initialize the ethers hash table.  We take two different approaches
+ * depending on whether or not the system provides the ethers name
+ * service.  If it does, we just wire in a few names at startup,
+ * and etheraddr_string() fills in the table on demand.  If it doesn't,
+ * then we suck in the entire /etc/ethers file at startup.  The idea
+ * is that parsing the local file will be fast, but spinning through
+ * all the ethers entries via NIS & next_etherent might be very slow.
+ *
+ * XXX pcap_next_etherent doesn't belong in the pcap interface, but
+ * since the pcap module already does name-to-address translation,
+ * it's already does most of the work for the ethernet address-to-name
+ * translation, so we just pcap_next_etherent as a convenience.
+ */
+static void
+init_etherarray(void)
+{
+	register struct etherlist *el;
+	register struct enamemem *tp;
+#ifdef HAVE_ETHER_NTOHOST
+	char name[256];
+#else
+	register struct pcap_etherent *ep;
+	register FILE *fp;
+
+	/* Suck in entire ethers file */
+	fp = fopen(PCAP_ETHERS_FILE, "r");
+	if (fp != NULL) {
+		while ((ep = pcap_next_etherent(fp)) != NULL) {
+			tp = lookup_emem(ep->addr);
+			tp->e_name = savestr(ep->name);
+		}
+		(void)fclose(fp);
+	}
+#endif
+
+	/* Hardwire some ethernet names */
+	for (el = etherlist; el->name != NULL; ++el) {
+		tp = lookup_emem(el->addr);
+		/* Don't override existing name */
+		if (tp->e_name != NULL)
+			continue;
+
+#ifdef HAVE_ETHER_NTOHOST
+                /* Use yp/nis version of name if available */
+                if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) {
+                        tp->e_name = savestr(name);
+			continue;
+		}
+#endif
+		tp->e_name = el->name;
+	}
+}
+
+static struct tok llcsap_db[] = {
+	{ LLCSAP_NULL,		"null" },
+	{ LLCSAP_8021B_I,	"802.1b-gsap" },
+	{ LLCSAP_8021B_G,	"802.1b-isap" },
+	{ LLCSAP_IP,		"ip-sap" },
+	{ LLCSAP_PROWAYNM,	"proway-nm" },
+	{ LLCSAP_8021D,		"802.1d" },
+	{ LLCSAP_RS511,		"eia-rs511" },
+	{ LLCSAP_ISO8208,	"x.25/llc2" },
+	{ LLCSAP_PROWAY,	"proway" },
+	{ LLCSAP_ISONS,		"iso-clns" },
+	{ LLCSAP_GLOBAL,	"global" },
+	{ 0,			NULL }
+};
+
+static void
+init_llcsaparray(void)
+{
+	register int i;
+	register struct hnamemem *table;
+
+	for (i = 0; llcsap_db[i].s != NULL; i++) {
+		table = &llcsaptable[llcsap_db[i].v];
+		while (table->name)
+			table = table->nxt;
+		table->name = llcsap_db[i].s;
+		table->addr = llcsap_db[i].v;
+		table->nxt = newhnamemem();
+	}
+}
+
+/*
+ * Initialize the address to name translation machinery.  We map all
+ * non-local IP addresses to numeric addresses if fflag is true (i.e.,
+ * to prevent blocking on the nameserver).  localnet is the IP address
+ * of the local network.  mask is its subnet mask.
+ */
+void
+init_addrtoname(int fflag, u_int32_t localnet, u_int32_t mask)
+{
+	netmask = mask;
+	if (fflag) {
+		f_localnet = localnet;
+		f_netmask = mask;
+	}
+	if (nflag)
+		/*
+		 * Simplest way to suppress names.
+		 */
+		return;
+
+	init_etherarray();
+	init_servarray();
+	init_eprotoarray();
+	init_llcsaparray();
+	init_protoidarray();
+}
+
+char *
+dnaddr_string(u_short dnaddr)
+{
+	register struct hnamemem *tp;
+
+	for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
+	     tp = tp->nxt)
+		if (tp->addr == dnaddr)
+			return (tp->name);
+
+	tp->addr = dnaddr;
+	tp->nxt = newhnamemem();
+	if (nflag)
+		tp->name = dnnum_string(dnaddr);
+	else
+		tp->name = dnname_string(dnaddr);
+
+	return(tp->name);
+}
+
+/* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
+struct hnamemem *
+newhnamemem(void)
+{
+	register struct hnamemem *p;
+	static struct hnamemem *ptr = NULL;
+	static u_int num = 0;
+
+	if (num  <= 0) {
+		num = 64;
+		ptr = (struct hnamemem *)calloc(num, sizeof (*ptr));
+		if (ptr == NULL)
+			error("newhnamemem: calloc");
+	}
+	--num;
+	p = ptr++;
+	return (p);
+}
diff --git a/tcpdump.tproj/addrtoname.h b/tcpdump.tproj/addrtoname.h
new file mode 100644
index 0000000..c40b03f
--- /dev/null
+++ b/tcpdump.tproj/addrtoname.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1992, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/addrtoname.h,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL)
+ */
+
+/* Name to address translation routines. */
+
+extern char *etheraddr_string(const u_char *);
+extern char *etherproto_string(u_short);
+extern char *tcpport_string(u_short);
+extern char *udpport_string(u_short);
+extern char *getname(const u_char *);
+extern char *intoa(u_int32_t);
+
+extern void init_addrtoname(int, u_int32_t, u_int32_t);
+extern struct hnamemem *newhnamemem(void);
+
+#define ipaddr_string(p) getname((const u_char *)(p))
diff --git a/tcpdump.tproj/appletalk.h b/tcpdump.tproj/appletalk.h
new file mode 100644
index 0000000..49690e7
--- /dev/null
+++ b/tcpdump.tproj/appletalk.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * AppleTalk protocol formats (courtesy Bill Croft of Stanford/SUMEX).
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/appletalk.h,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL)
+ */
+
+struct LAP {
+	u_char	dst;
+	u_char	src;
+	u_char	type;
+};
+#define lapShortDDP	1	/* short DDP type */
+#define lapDDP		2	/* DDP type */
+#define lapKLAP		'K'	/* Kinetics KLAP type */
+
+/* Datagram Delivery Protocol */
+
+struct atDDP {
+	u_short	length;
+	u_short	checksum;
+	u_short	dstNet;
+	u_short	srcNet;
+	u_char	dstNode;
+	u_char	srcNode;
+	u_char	dstSkt;
+	u_char	srcSkt;
+	u_char	type;
+};
+
+struct atShortDDP {
+	u_short	length;
+	u_char	dstSkt;
+	u_char	srcSkt;
+	u_char	type;
+};
+
+#define	ddpMaxWKS	0x7F
+#define	ddpMaxData	586
+#define	ddpLengthMask	0x3FF
+#define	ddpHopShift	10
+#define	ddpSize		13	/* size of DDP header (avoid struct padding) */
+#define	ddpSSize	5
+#define	ddpWKS		128	/* boundary of DDP well known sockets */
+#define	ddpRTMP		1	/* RTMP type */
+#define	ddpRTMPrequest	5	/* RTMP request type */
+#define	ddpNBP		2	/* NBP type */
+#define	ddpATP		3	/* ATP type */
+#define	ddpECHO		4	/* ECHO type */
+#define	ddpIP		22	/* IP type */
+#define	ddpARP		23	/* ARP type */
+#define	ddpKLAP		0x4b	/* Kinetics KLAP type */
+
+
+/* AppleTalk Transaction Protocol */
+
+struct atATP {
+	u_char	control;
+	u_char	bitmap;
+	u_short	transID;
+	int32_t userData;
+};
+
+#define	atpReqCode	0x40
+#define	atpRspCode	0x80
+#define	atpRelCode	0xC0
+#define	atpXO		0x20
+#define	atpEOM		0x10
+#define	atpSTS		0x08
+#define	atpFlagMask	0x3F
+#define	atpControlMask	0xF8
+#define	atpMaxNum	8
+#define	atpMaxData	578
+
+
+/* AppleTalk Echo Protocol */
+
+struct atEcho {
+	u_char	echoFunction;
+	u_char	*echoData;
+};
+
+#define echoSkt		4		/* the echoer socket */
+#define echoSize	1		/* size of echo header */
+#define echoRequest	1		/* echo request */
+#define echoReply	2		/* echo request */
+
+
+/* Name Binding Protocol */
+
+struct atNBP {
+	u_char	control;
+	u_char	id;
+};
+
+struct atNBPtuple {
+	u_short	net;
+	u_char	node;
+	u_char	skt;
+	u_char	enumerator;
+};
+
+#define	nbpBrRq		0x10
+#define	nbpLkUp		0x20
+#define	nbpLkUpReply	0x30
+
+#define	nbpNIS		2
+#define	nbpTupleMax	15
+
+#define	nbpHeaderSize	2
+#define nbpTupleSize	5
+
+#define nbpSkt		2		/* NIS */
+
+
+/* Routing Table Maint. Protocol */
+
+#define	rtmpSkt		1	/* number of RTMP socket */
+#define	rtmpSize	4	/* minimum size */
+#define	rtmpTupleSize	3
+
+
+/* Zone Information Protocol */
+
+struct zipHeader {
+	u_char	command;
+	u_char	netcount;
+};
+
+#define	zipHeaderSize	2
+#define	zipQuery	1
+#define	zipReply	2
+#define	zipTakedown	3
+#define	zipBringup	4
+#define	ddpZIP		6
+#define	zipSkt		6
+#define	GetMyZone	7
+#define	GetZoneList	8
+
+/*
+ * UDP port range used for ddp-in-udp encapsulation is 16512-16639
+ * for client sockets (128-255) and 200-327 for server sockets
+ * (0-127).  We also try to recognize the pre-April 88 server
+ * socket range of 768-895.
+ */
+#define atalk_port(p) \
+	(((unsigned)((p) - 16512) < 128) || \
+	 ((unsigned)((p) - 200) < 128) || \
+	 ((unsigned)((p) - 768) < 128))
diff --git a/tcpdump.tproj/bootp.h b/tcpdump.tproj/bootp.h
new file mode 100644
index 0000000..74dc2c2
--- /dev/null
+++ b/tcpdump.tproj/bootp.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/bootp.h,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL) */
+/*
+ * Bootstrap Protocol (BOOTP).  RFC951 and RFC1048.
+ *
+ * This file specifies the "implementation-independent" BOOTP protocol
+ * information which is common to both client and server.
+ *
+ * Copyright 1988 by Carnegie Mellon.
+ *
+ * Permission to use, copy, modify, and distribute this program for any
+ * purpose and without fee is hereby granted, provided that this copyright
+ * and permission notice appear on all copies and supporting documentation,
+ * the name of Carnegie Mellon not be used in advertising or publicity
+ * pertaining to distribution of the program without specific prior
+ * permission, and notice be given in supporting documentation that copying
+ * and distribution is by permission of Carnegie Mellon and Stanford
+ * University.  Carnegie Mellon makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+
+struct bootp {
+	unsigned char	bp_op;		/* packet opcode type */
+	unsigned char	bp_htype;	/* hardware addr type */
+	unsigned char	bp_hlen;	/* hardware addr length */
+	unsigned char	bp_hops;	/* gateway hops */
+	u_int32_t	bp_xid;		/* transaction ID */
+	unsigned short	bp_secs;	/* seconds since boot began */
+	unsigned short	bp_unused;
+	struct in_addr	bp_ciaddr;	/* client IP address */
+	struct in_addr	bp_yiaddr;	/* 'your' IP address */
+	struct in_addr	bp_siaddr;	/* server IP address */
+	struct in_addr	bp_giaddr;	/* gateway IP address */
+	unsigned char	bp_chaddr[16];	/* client hardware address */
+	unsigned char	bp_sname[64];	/* server host name */
+	unsigned char	bp_file[128];	/* boot file name */
+	unsigned char	bp_vend[64];	/* vendor-specific area */
+};
+
+/*
+ * UDP port numbers, server and client.
+ */
+#define	IPPORT_BOOTPS		67
+#define	IPPORT_BOOTPC		68
+
+#define BOOTREPLY		2
+#define BOOTREQUEST		1
+
+
+/*
+ * Vendor magic cookie (v_magic) for CMU
+ */
+#define VM_CMU		"CMU"
+
+/*
+ * Vendor magic cookie (v_magic) for RFC1048
+ */
+#define VM_RFC1048	{ 99, 130, 83, 99 }
+
+
+
+/*
+ * RFC1048 tag values used to specify what information is being supplied in
+ * the vendor field of the packet.
+ */
+
+#define TAG_PAD			((unsigned char)   0)
+#define TAG_SUBNET_MASK		((unsigned char)   1)
+#define TAG_TIME_OFFSET		((unsigned char)   2)
+#define TAG_GATEWAY		((unsigned char)   3)
+#define TAG_TIME_SERVER		((unsigned char)   4)
+#define TAG_NAME_SERVER		((unsigned char)   5)
+#define TAG_DOMAIN_SERVER	((unsigned char)   6)
+#define TAG_LOG_SERVER		((unsigned char)   7)
+#define TAG_COOKIE_SERVER	((unsigned char)   8)
+#define TAG_LPR_SERVER		((unsigned char)   9)
+#define TAG_IMPRESS_SERVER	((unsigned char)  10)
+#define TAG_RLP_SERVER		((unsigned char)  11)
+#define TAG_HOSTNAME		((unsigned char)  12)
+#define TAG_BOOTSIZE		((unsigned char)  13)
+#define TAG_END			((unsigned char) 255)
+/* RFC1497 tags */
+#define	TAG_DUMPPATH		((unsigned char)  14)
+#define	TAG_DOMAINNAME		((unsigned char)  15)
+#define	TAG_SWAP_SERVER		((unsigned char)  16)
+#define	TAG_ROOTPATH		((unsigned char)  17)
+#define	TAG_EXTPATH		((unsigned char)  18)
+
+
+
+/*
+ * "vendor" data permitted for CMU bootp clients.
+ */
+
+struct cmu_vend {
+	unsigned char	v_magic[4];	/* magic number */
+	u_int32_t	v_flags;	/* flags/opcodes, etc. */
+	struct in_addr	v_smask;	/* Subnet mask */
+	struct in_addr	v_dgate;	/* Default gateway */
+	struct in_addr	v_dns1, v_dns2; /* Domain name servers */
+	struct in_addr	v_ins1, v_ins2; /* IEN-116 name servers */
+	struct in_addr	v_ts1, v_ts2;	/* Time servers */
+	unsigned char	v_unused[24];	/* currently unused */
+};
+
+
+/* v_flags values */
+#define VF_SMASK	1	/* Subnet mask field contains valid data */
diff --git a/tcpdump.tproj/bpf_dump.c b/tcpdump.tproj/bpf_dump.c
new file mode 100644
index 0000000..5c29e59
--- /dev/null
+++ b/tcpdump.tproj/bpf_dump.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/bpf_dump.c,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <pcap.h>
+#include <stdio.h>
+
+#include "interface.h"
+
+extern void bpf_dump(struct bpf_program *, int);
+
+void
+bpf_dump(struct bpf_program *p, int option)
+{
+	struct bpf_insn *insn;
+	int i;
+	int n = p->bf_len;
+
+	insn = p->bf_insns;
+	if (option > 2) {
+		printf("%d\n", n);
+		for (i = 0; i < n; ++insn, ++i) {
+			printf("%u %u %u %u\n", insn->code,
+			       insn->jt, insn->jf, insn->k);
+		}
+		return ;
+	}
+	if (option > 1) {
+		for (i = 0; i < n; ++insn, ++i)
+			printf("{ 0x%x, %d, %d, 0x%08x },\n",
+			       insn->code, insn->jt, insn->jf, insn->k);
+		return;
+	}
+	for (i = 0; i < n; ++insn, ++i) {
+#ifdef BDEBUG
+		extern int bids[];
+		printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1);
+#endif
+		puts(bpf_image(insn, i));
+	}
+}
diff --git a/tcpdump.tproj/decnet.h b/tcpdump.tproj/decnet.h
new file mode 100644
index 0000000..37a6127
--- /dev/null
+++ b/tcpdump.tproj/decnet.h
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1994, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/decnet.h,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL)
+ */
+
+typedef unsigned char byte[1];		/* single byte field */
+typedef unsigned char word[2];		/* 2 byte field */
+typedef unsigned char longword[4];	/* 4 bytes field */
+
+/*
+ * Definitions for DECNET Phase IV protocol headers
+ */
+union etheraddress {
+	unsigned char   dne_addr[6];		/* full ethernet address */
+	struct {
+		unsigned char dne_hiord[4];	/* DECnet HIORD prefix */
+		unsigned char dne_nodeaddr[2];	/* DECnet node address */
+	} dne_remote;
+};
+
+typedef union etheraddress etheraddr;	/* Ethernet address */
+
+#define HIORD 0x000400aa		/* high 32-bits of address (swapped) */
+
+#define AREAMASK	0176000		/* mask for area field */
+#define	AREASHIFT	10		/* bit-offset for area field */
+#define NODEMASK	01777		/* mask for node address field */
+
+#define DN_MAXADDL	20		/* max size of DECnet address */
+struct dn_naddr {
+	unsigned short	a_len;		/* length of address */
+	unsigned char a_addr[DN_MAXADDL]; /* address as bytes */
+};
+
+/*
+ * Define long and short header formats.
+ */
+struct shorthdr
+  {
+    byte	sh_flags;		/* route flags */
+    word	sh_dst;			/* destination node address */
+    word	sh_src;			/* source node address */
+    byte	sh_visits;		/* visit count */
+  };
+
+struct longhdr
+  {
+    byte	lg_flags;		/* route flags */
+    byte	lg_darea;		/* destination area (reserved) */
+    byte	lg_dsarea;		/* destination subarea (reserved) */
+    etheraddr	lg_dst;			/* destination id */
+    byte	lg_sarea;		/* source area (reserved) */
+    byte	lg_ssarea;		/* source subarea (reserved) */
+    etheraddr	lg_src;			/* source id */
+    byte	lg_nextl2;		/* next level 2 router (reserved) */
+    byte	lg_visits;		/* visit count */
+    byte	lg_service;		/* service class (reserved) */
+    byte	lg_pt;			/* protocol type (reserved) */
+  };
+
+union routehdr
+  {
+    struct shorthdr rh_short;		/* short route header */
+    struct longhdr rh_long;		/* long route header */
+  };
+
+/*
+ * Define the values of various fields in the protocol messages.
+ *
+ * 1. Data packet formats.
+ */
+#define RMF_MASK	7		/* mask for message type */
+#define RMF_SHORT	2		/* short message format */
+#define RMF_LONG	6		/* long message format */
+#ifndef RMF_RQR
+#define RMF_RQR		010		/* request return to sender */
+#define RMF_RTS		020		/* returning to sender */
+#define RMF_IE		040		/* intra-ethernet packet */
+#endif /* RMR_RQR */
+#define RMF_FVER	0100		/* future version flag */
+#define RMF_PAD		0200		/* pad field */
+#define RMF_PADMASK	0177		/* pad field mask */
+
+#define VIS_MASK	077		/* visit field mask */
+
+/*
+ * 2. Control packet formats.
+ */
+#define RMF_CTLMASK	017		/* mask for message type */
+#define RMF_CTLMSG	01		/* control message indicator */
+#define RMF_INIT	01		/* initialization message */
+#define RMF_VER		03		/* verification message */
+#define RMF_TEST	05		/* hello and test message */
+#define RMF_L1ROUT	07		/* level 1 routing message */
+#define RMF_L2ROUT	011		/* level 2 routing message */
+#define RMF_RHELLO	013		/* router hello message */
+#define RMF_EHELLO	015		/* endnode hello message */
+
+#define TI_L2ROUT	01		/* level 2 router */
+#define TI_L1ROUT	02		/* level 1 router */
+#define TI_ENDNODE	03		/* endnode */
+#define TI_VERIF	04		/* verification required */
+#define TI_BLOCK	010		/* blocking requested */
+
+#define VE_VERS		2		/* version number (2) */
+#define VE_ECO		0		/* ECO number */
+#define VE_UECO		0		/* user ECO number (0) */
+
+#define P3_VERS		1		/* phase III version number (1) */
+#define P3_ECO		3		/* ECO number (3) */
+#define P3_UECO		0		/* user ECO number (0) */
+
+#define II_L2ROUT	01		/* level 2 router */
+#define II_L1ROUT	02		/* level 1 router */
+#define II_ENDNODE	03		/* endnode */
+#define II_VERIF	04		/* verification required */
+#define II_NOMCAST	040		/* no multicast traffic accepted */
+#define II_BLOCK	0100		/* blocking requested */
+#define II_TYPEMASK	03		/* mask for node type */
+
+#define TESTDATA	0252		/* test data bytes */
+#define TESTLEN		1		/* length of transmitted test data */
+
+/*
+ * Define control message formats.
+ */
+struct initmsgIII			/* phase III initialization message */
+  {
+    byte	inIII_flags;		/* route flags */
+    word	inIII_src;		/* source node address */
+    byte	inIII_info;		/* routing layer information */
+    word	inIII_blksize;		/* maximum data link block size */
+    byte	inIII_vers;		/* version number */
+    byte	inIII_eco;		/* ECO number */
+    byte	inIII_ueco;		/* user ECO number */
+    byte	inIII_rsvd;		/* reserved image field */
+  };
+
+struct initmsg				/* initialization message */
+  {
+    byte	in_flags;		/* route flags */
+    word	in_src;			/* source node address */
+    byte	in_info;		/* routing layer information */
+    word	in_blksize;		/* maximum data link block size */
+    byte	in_vers;		/* version number */
+    byte	in_eco;			/* ECO number */
+    byte	in_ueco;		/* user ECO number */
+    word	in_hello;		/* hello timer */
+    byte	in_rsvd;		/* reserved image field */
+  };
+
+struct verifmsg				/* verification message */
+  {
+    byte	ve_flags;		/* route flags */
+    word	ve_src;			/* source node address */
+    byte	ve_fcnval;		/* function value image field */
+  };
+
+struct testmsg				/* hello and test message */
+  {
+    byte	te_flags;		/* route flags */
+    word	te_src;			/* source node address */
+    byte	te_data;		/* test data image field */
+  };
+
+struct l1rout				/* level 1 routing message */
+  {
+    byte	r1_flags;		/* route flags */
+    word	r1_src;			/* source node address */
+    byte	r1_rsvd;		/* reserved field */
+  };
+
+struct l2rout				/* level 2 routing message */
+  {
+    byte	r2_flags;		/* route flags */
+    word	r2_src;			/* source node address */
+    byte	r2_rsvd;		/* reserved field */
+  };
+
+struct rhellomsg			/* router hello message */
+  {
+    byte	rh_flags;		/* route flags */
+    byte	rh_vers;		/* version number */
+    byte	rh_eco;			/* ECO number */
+    byte	rh_ueco;		/* user ECO number */
+    etheraddr	rh_src;			/* source id */
+    byte	rh_info;		/* routing layer information */
+    word	rh_blksize;		/* maximum data link block size */
+    byte	rh_priority;		/* router's priority */
+    byte	rh_area;		/* reserved */
+    word	rh_hello;		/* hello timer */
+    byte	rh_mpd;			/* reserved */
+  };
+
+struct ehellomsg			/* endnode hello message */
+  {
+    byte	eh_flags;		/* route flags */
+    byte	eh_vers;		/* version number */
+    byte	eh_eco;			/* ECO number */
+    byte	eh_ueco;		/* user ECO number */
+    etheraddr	eh_src;			/* source id */
+    byte	eh_info;		/* routing layer information */
+    word	eh_blksize;		/* maximum data link block size */
+    byte	eh_area;		/* area (reserved) */
+    byte	eh_seed[8];		/* verification seed */
+    etheraddr	eh_router;		/* designated router */
+    word	eh_hello;		/* hello timer */
+    byte	eh_mpd;			/* (reserved) */
+    byte	eh_data;		/* test data image field */
+  };
+
+union controlmsg
+  {
+    struct initmsg	cm_init;	/* initialization message */
+    struct verifmsg	cm_ver;		/* verification message */
+    struct testmsg	cm_test;	/* hello and test message */
+    struct l1rout	cm_l1rou;	/* level 1 routing message */
+    struct l2rout	cm_l2rout;	/* level 2 routing message */
+    struct rhellomsg	cm_rhello;	/* router hello message */
+    struct ehellomsg	cm_ehello;	/* endnode hello message */
+  };
+
+/* Macros for decoding routing-info fields */
+#define	RI_COST(x)	((x)&0777)
+#define	RI_HOPS(x)	(((x)>>10)&037)
+
+/*
+ * NSP protocol fields and values.
+ */
+
+#define NSP_TYPEMASK 014		/* mask to isolate type code */
+#define NSP_SUBMASK 0160		/* mask to isolate subtype code */
+#define NSP_SUBSHFT 4			/* shift to move subtype code */
+
+#define MFT_DATA 0			/* data message */
+#define MFT_ACK  04			/* acknowledgement message */
+#define MFT_CTL  010			/* control message */
+
+#define MFS_ILS  020			/* data or I/LS indicator */
+#define MFS_BOM  040			/* beginning of message (data) */
+#define MFS_MOM  0			/* middle of message (data) */
+#define MFS_EOM  0100			/* end of message (data) */
+#define MFS_INT  040			/* interrupt message */
+
+#define MFS_DACK 0			/* data acknowledgement */
+#define MFS_IACK 020			/* I/LS acknowledgement */
+#define MFS_CACK 040			/* connect acknowledgement */
+
+#define MFS_NOP  0			/* no operation */
+#define MFS_CI   020			/* connect initiate */
+#define MFS_CC   040			/* connect confirm */
+#define MFS_DI   060			/* disconnect initiate */
+#define MFS_DC   0100			/* disconnect confirm */
+#define MFS_RCI  0140			/* retransmitted connect initiate */
+
+#define SGQ_ACK  0100000		/* ack */
+#define SGQ_NAK  0110000		/* negative ack */
+#define SGQ_OACK 0120000		/* other channel ack */
+#define SGQ_ONAK 0130000		/* other channel negative ack */
+#define SGQ_MASK 07777			/* mask to isolate seq # */
+#define SGQ_OTHER 020000		/* other channel qualifier */
+#define SGQ_DELAY 010000		/* ack delay flag */
+
+#define SGQ_EOM  0100000		/* pseudo flag for end-of-message */
+
+#define LSM_MASK 03			/* mask for modifier field */
+#define LSM_NOCHANGE 0			/* no change */
+#define LSM_DONOTSEND 1			/* do not send data */
+#define LSM_SEND 2			/* send data */
+
+#define LSI_MASK 014			/* mask for interpretation field */
+#define LSI_DATA 0			/* data segment or message count */
+#define LSI_INTR 4			/* interrupt request count */
+#define LSI_INTM 0377			/* funny marker for int. message */
+
+#define COS_MASK 014			/* mask for flow control field */
+#define COS_NONE 0			/* no flow control */
+#define COS_SEGMENT 04			/* segment flow control */
+#define COS_MESSAGE 010			/* message flow control */
+#define COS_CRYPTSER 020		/* cryptographic services requested */
+#define COS_DEFAULT 1			/* default value for field */
+
+#define COI_MASK 3			/* mask for version field */
+#define COI_32 0			/* version 3.2 */
+#define COI_31 1			/* version 3.1 */
+#define COI_40 2			/* version 4.0 */
+#define COI_41 3			/* version 4.1 */
+
+#define MNU_MASK 140			/* mask for session control version */
+#define MNU_10 000				/* session V1.0 */
+#define MNU_20 040				/* session V2.0 */
+#define MNU_ACCESS 1			/* access control present */
+#define MNU_USRDATA 2			/* user data field present */
+#define MNU_INVKPROXY 4			/* invoke proxy field present */
+#define MNU_UICPROXY 8			/* use uic-based proxy */
+
+#define DC_NORESOURCES 1		/* no resource reason code */
+#define DC_NOLINK 41			/* no link terminate reason code */
+#define DC_COMPLETE 42			/* disconnect complete reason code */
+
+#define DI_NOERROR 0			/* user disconnect */
+#define DI_SHUT 3			/* node is shutting down */
+#define DI_NOUSER 4			/* destination end user does not exist */
+#define DI_INVDEST 5			/* invalid end user destination */
+#define DI_REMRESRC 6			/* insufficient remote resources */
+#define DI_TPA 8			/* third party abort */
+#define DI_PROTOCOL 7			/* protocol error discovered */
+#define DI_ABORT 9			/* user abort */
+#define DI_LOCALRESRC 32		/* insufficient local resources */
+#define DI_REMUSERRESRC 33		/* insufficient remote user resources */
+#define DI_BADACCESS 34			/* bad access control information */
+#define DI_BADACCNT 36			/* bad ACCOUNT information */
+#define DI_CONNECTABORT 38		/* connect request cancelled */
+#define DI_TIMEDOUT 38			/* remote node or user crashed */
+#define DI_UNREACHABLE 39		/* local timers expired due to ... */
+#define DI_BADIMAGE 43			/* bad image data in connect */
+#define DI_SERVMISMATCH 54		/* cryptographic service mismatch */
+
+#define UC_OBJREJECT 0			/* object rejected connect */
+#define UC_USERDISCONNECT 0		/* user disconnect */
+#define UC_RESOURCES 1			/* insufficient resources (local or remote) */
+#define UC_NOSUCHNODE 2			/* unrecognized node name */
+#define UC_REMOTESHUT 3			/* remote node shutting down */
+#define UC_NOSUCHOBJ 4			/* unrecognized object */
+#define UC_INVOBJFORMAT 5		/* invalid object name format */
+#define UC_OBJTOOBUSY 6			/* object too busy */
+#define UC_NETWORKABORT 8		/* network abort */
+#define UC_USERABORT 9			/* user abort */
+#define UC_INVNODEFORMAT 10		/* invalid node name format */
+#define UC_LOCALSHUT 11			/* local node shutting down */
+#define UC_ACCESSREJECT 34		/* invalid access control information */
+#define UC_NORESPONSE 38		/* no response from object */
+#define UC_UNREACHABLE 39		/* node unreachable */
+
+/*
+ * NSP message formats.
+ */
+struct nsphdr				/* general nsp header */
+  {
+    byte	nh_flags;		/* message flags */
+    word	nh_dst;			/* destination link address */
+    word	nh_src;			/* source link address */
+  };
+
+struct seghdr				/* data segment header */
+  {
+    byte	sh_flags;		/* message flags */
+    word	sh_dst;			/* destination link address */
+    word	sh_src;			/* source link address */
+    word	sh_seq[3];		/* sequence numbers */
+  };
+
+struct minseghdr			/* minimum data segment header */
+  {
+    byte	ms_flags;		/* message flags */
+    word	ms_dst;			/* destination link address */
+    word	ms_src;			/* source link address */
+    word	ms_seq;			/* sequence number */
+  };
+
+struct lsmsg				/* link service message (after hdr) */
+  {
+    byte	ls_lsflags;		/* link service flags */
+    byte	ls_fcval;		/* flow control value */
+  };
+
+struct ackmsg				/* acknowledgement message */
+  {
+    byte	ak_flags;		/* message flags */
+    word	ak_dst;			/* destination link address */
+    word	ak_src;			/* source link address */
+    word	ak_acknum[2];		/* acknowledgement numbers */
+  };
+
+struct minackmsg			/* minimum acknowledgement message */
+  {
+    byte	mk_flags;		/* message flags */
+    word	mk_dst;			/* destination link address */
+    word	mk_src;			/* source link address */
+    word	mk_acknum;		/* acknowledgement number */
+  };
+
+struct ciackmsg				/* connect acknowledgement message */
+  {
+    byte	ck_flags;		/* message flags */
+    word	ck_dst;			/* destination link address */
+  };
+
+struct cimsg				/* connect initiate message */
+  {
+    byte	ci_flags;		/* message flags */
+    word	ci_dst;			/* destination link address (0) */
+    word	ci_src;			/* source link address */
+    byte	ci_services;		/* requested services */
+    byte	ci_info;		/* information */
+    word	ci_segsize;		/* maximum segment size */
+  };
+
+struct ccmsg				/* connect confirm message */
+  {
+    byte	cc_flags;		/* message flags */
+    word	cc_dst;			/* destination link address */
+    word	cc_src;			/* source link address */
+    byte	cc_services;		/* requested services */
+    byte	cc_info;		/* information */
+    word	cc_segsize;		/* maximum segment size */
+    byte	cc_optlen;		/* optional data length */
+  };
+
+struct cnmsg				/* generic connect message */
+  {
+    byte	cn_flags;		/* message flags */
+    word	cn_dst;			/* destination link address */
+    word	cn_src;			/* source link address */
+    byte	cn_services;		/* requested services */
+    byte	cn_info;		/* information */
+    word	cn_segsize;		/* maximum segment size */
+  };
+
+struct dimsg				/* disconnect initiate message */
+  {
+    byte	di_flags;		/* message flags */
+    word	di_dst;			/* destination link address */
+    word	di_src;			/* source link address */
+    word	di_reason;		/* reason code */
+    byte	di_optlen;		/* optional data length */
+  };
+
+struct dcmsg				/* disconnect confirm message */
+  {
+    byte	dc_flags;		/* message flags */
+    word	dc_dst;			/* destination link address */
+    word	dc_src;			/* source link address */
+    word	dc_reason;		/* reason code */
+  };
diff --git a/tcpdump.tproj/ethertype.h b/tcpdump.tproj/ethertype.h
new file mode 100644
index 0000000..43726ac
--- /dev/null
+++ b/tcpdump.tproj/ethertype.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1993, 1994, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/ethertype.h,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL)
+ */
+
+/* Types missing from some systems */
+
+#ifndef ETHERTYPE_NS
+#define ETHERTYPE_NS		0x0600
+#endif
+#ifndef	ETHERTYPE_SPRITE
+#define	ETHERTYPE_SPRITE	0x0500
+#endif
+#ifndef ETHERTYPE_TRAIL
+#define ETHERTYPE_TRAIL		0x1000
+#endif
+#ifndef	ETHERTYPE_MOPDL
+#define	ETHERTYPE_MOPDL		0x6001
+#endif
+#ifndef	ETHERTYPE_MOPRC
+#define	ETHERTYPE_MOPRC		0x6002
+#endif
+#ifndef	ETHERTYPE_DN
+#define	ETHERTYPE_DN		0x6003
+#endif
+#ifndef	ETHERTYPE_LAT
+#define	ETHERTYPE_LAT		0x6004
+#endif
+#ifndef ETHERTYPE_SCA
+#define ETHERTYPE_SCA		0x6007
+#endif
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP	0x8035
+#endif
+#ifndef	ETHERTYPE_LANBRIDGE
+#define	ETHERTYPE_LANBRIDGE	0x8038
+#endif
+#ifndef	ETHERTYPE_DECDNS
+#define	ETHERTYPE_DECDNS	0x803c
+#endif
+#ifndef	ETHERTYPE_DECDTS
+#define	ETHERTYPE_DECDTS	0x803e
+#endif
+#ifndef	ETHERTYPE_VEXP
+#define	ETHERTYPE_VEXP		0x805b
+#endif
+#ifndef	ETHERTYPE_VPROD
+#define	ETHERTYPE_VPROD		0x805c
+#endif
+#ifndef ETHERTYPE_ATALK
+#define ETHERTYPE_ATALK		0x809b
+#endif
+#ifndef ETHERTYPE_AARP
+#define ETHERTYPE_AARP		0x80f3
+#endif
+#ifndef	ETHERTYPE_LOOPBACK
+#define	ETHERTYPE_LOOPBACK	0x9000
+#endif
diff --git a/tcpdump.tproj/extract.h b/tcpdump.tproj/extract.h
new file mode 100644
index 0000000..f3213d4
--- /dev/null
+++ b/tcpdump.tproj/extract.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/extract.h,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL)
+ */
+
+/* Network to host order macros */
+
+#ifdef LBL_ALIGN
+#define EXTRACT_16BITS(p) \
+	((u_short)*((u_char *)(p) + 0) << 8 | \
+	(u_short)*((u_char *)(p) + 1))
+#define EXTRACT_32BITS(p) \
+	((u_int32_t)*((u_char *)(p) + 0) << 24 | \
+	(u_int32_t)*((u_char *)(p) + 1) << 16 | \
+	(u_int32_t)*((u_char *)(p) + 2) << 8 | \
+	(u_int32_t)*((u_char *)(p) + 3))
+#else
+#define EXTRACT_16BITS(p) \
+	((u_short)ntohs(*(u_short *)(p)))
+#define EXTRACT_32BITS(p) \
+	((u_int32_t)ntohl(*(u_int32_t *)(p)))
+#endif
+
+#define EXTRACT_24BITS(p) \
+	((u_int32_t)*((u_char *)(p) + 0) << 16 | \
+	(u_int32_t)*((u_char *)(p) + 1) << 8 | \
+	(u_int32_t)*((u_char *)(p) + 2))
+
+/* Little endian protocol host order macros */
+
+#define EXTRACT_LE_8BITS(p) (*(p))
+#define EXTRACT_LE_16BITS(p) \
+	((u_short)*((u_char *)(p) + 1) << 8 | \
+	(u_short)*((u_char *)(p) + 0))
+#define EXTRACT_LE_32BITS(p) \
+	((u_int32_t)*((u_char *)(p) + 3) << 24 | \
+	(u_int32_t)*((u_char *)(p) + 2) << 16 | \
+	(u_int32_t)*((u_char *)(p) + 1) << 8 | \
+	(u_int32_t)*((u_char *)(p) + 0))
diff --git a/tcpdump.tproj/fddi.h b/tcpdump.tproj/fddi.h
new file mode 100644
index 0000000..21920f4
--- /dev/null
+++ b/tcpdump.tproj/fddi.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/fddi.h,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL)
+ */
+
+/*
+ * Based on Ultrix if_fddi.h
+ */
+
+/*
+ * This stuff should come from a system header file, but there's no
+ * obviously portable way to do that and it's not really going
+ * to change from system to system (except for the padding business).
+ */
+
+struct fddi_header {
+	u_char  fddi_fc;		/* frame control */
+	u_char  fddi_dhost[6];
+	u_char  fddi_shost[6];
+};
+
+
+/* Useful values for fddi_fc (frame control) field */
+
+/*
+ * FDDI Frame Control bits
+ */
+#define	FDDIFC_C		0x80		/* Class bit */
+#define	FDDIFC_L		0x40		/* Address length bit */
+#define	FDDIFC_F		0x30		/* Frame format bits */
+#define	FDDIFC_Z		0x0f		/* Control bits */
+
+/*
+ * FDDI Frame Control values. (48-bit addressing only).
+ */
+#define	FDDIFC_VOID		0x40		/* Void frame */
+#define	FDDIFC_NRT		0x80		/* Nonrestricted token */
+#define	FDDIFC_RT		0xc0		/* Restricted token */
+#define	FDDIFC_SMT_INFO		0x41		/* SMT Info */
+#define	FDDIFC_SMT_NSA		0x4F		/* SMT Next station adrs */
+#define	FDDIFC_MAC_BEACON	0xc2		/* MAC Beacon frame */
+#define	FDDIFC_MAC_CLAIM	0xc3		/* MAC Claim frame */
+#define	FDDIFC_LLC_ASYNC	0x50		/* Async. LLC frame */
+#define	FDDIFC_LLC_SYNC		0xd0		/* Sync. LLC frame */
+#define	FDDIFC_IMP_ASYNC	0x60		/* Implementor Async. */
+#define	FDDIFC_IMP_SYNC		0xe0		/* Implementor Synch. */
+#define FDDIFC_SMT		0x40		/* SMT frame */
+#define FDDIFC_MAC		0xc0		/* MAC frame */
+
+#define	FDDIFC_CLFF		0xF0		/* Class/Length/Format bits */
+#define	FDDIFC_ZZZZ		0x0F		/* Control bits */
diff --git a/tcpdump.tproj/gnuc.h b/tcpdump.tproj/gnuc.h
new file mode 100644
index 0000000..a88d32c
--- /dev/null
+++ b/tcpdump.tproj/gnuc.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/gnuc.h,v 1.1.1.1 1999/05/02 03:58:31 wsanchez Exp $ (LBL) */
+
+/* Define __P() macro, if necessary */
+#ifndef __P
+#if __STDC__
+#define __P(protos) protos
+#else
+#define __P(protos) ()
+#endif
+#endif
+
+/* inline foo */
+#ifdef __GNUC__
+#define inline __inline
+#else
+#define inline
+#endif
+
+/*
+ * Handle new and old "dead" routine prototypes
+ *
+ * For example:
+ *
+ *	__dead void foo(void) __attribute__((volatile));
+ *
+ */
+#ifdef __GNUC__
+#ifndef __dead
+#define __dead volatile
+#endif
+#if __GNUC__ < 2  || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+#ifndef __attribute__
+#define __attribute__(args)
+#endif
+#endif
+#else
+#ifndef __dead
+#define __dead
+#endif
+#ifndef __attribute__
+#define __attribute__(args)
+#endif
+#endif
diff --git a/tcpdump.tproj/igrp.h b/tcpdump.tproj/igrp.h
new file mode 100644
index 0000000..ec55bdf
--- /dev/null
+++ b/tcpdump.tproj/igrp.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* Cisco IGRP definitions */
+
+/* IGRP Header */
+
+struct igrphdr {
+#ifdef WORDS_BIGENDIAN
+	u_char ig_v:4;		/* protocol version number */
+	u_char ig_op:4;		/* opcode */
+#else
+	u_char ig_op:4;		/* opcode */
+	u_char ig_v:4;		/* protocol version number */
+#endif
+	u_char ig_ed;		/* edition number */
+	u_short ig_as;		/* autonomous system number */
+	u_short ig_ni;		/* number of subnet in local net */
+	u_short ig_ns;		/* number of networks in AS */
+	u_short ig_nx;		/* number of networks ouside AS */
+	u_short ig_sum;		/* checksum of IGRP header & data */
+};
+
+#define IGRP_UPDATE	1
+#define IGRP_REQUEST	2
+
+/* IGRP routing entry */
+
+struct igrprte {
+	u_char igr_net[3];	/* 3 significant octets of IP address */
+	u_char igr_dly[3];	/* delay in tens of microseconds */
+	u_char igr_bw[3];	/* bandwidth in units of 1 kb/s */
+	u_char igr_mtu[2];	/* MTU in octets */
+	u_char igr_rel;		/* percent packets successfully tx/rx */
+	u_char igr_ld;		/* percent of channel occupied */
+	u_char igr_hct;		/* hop count */
+};
+
+#define IGRP_RTE_SIZE	14	/* don't believe sizeof ! */
diff --git a/tcpdump.tproj/interface.h b/tcpdump.tproj/interface.h
new file mode 100644
index 0000000..089c4dd
--- /dev/null
+++ b/tcpdump.tproj/interface.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/interface.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ (LBL)
+ */
+
+#ifndef tcpdump_interface_h
+#define tcpdump_interface_h
+#ifndef	IPPROTO_ND
+#define	IPPROTO_ND	77
+#endif
+
+
+#include "gnuc.h"
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+struct tok {
+	int v;			/* value */
+	char *s;		/* string */
+};
+
+extern int dflag;		/* print filter code */
+extern int eflag;		/* print ethernet header */
+extern int nflag;		/* leave addresses as numbers */
+extern int Nflag;		/* remove domains from printed host names */
+extern int qflag;		/* quick (shorter) output */
+extern int Sflag;		/* print raw TCP sequence numbers */
+extern int tflag;		/* print packet arrival time */
+extern int vflag;		/* verbose */
+extern int xflag;		/* print packet in hex */
+
+extern int packettype;		/* as specified by -T */
+#define PT_VAT		1	/* Visual Audio Tool */
+#define PT_WB		2	/* distributed White Board */
+#define PT_RPC		3	/* Remote Procedure Call */
+#define PT_RTP		4	/* Real-Time Applications protocol */
+#define PT_RTCP		5	/* Real-Time Applications control protocol */
+
+#ifndef min
+#define min(a,b) ((a)>(b)?(b):(a))
+#endif
+#ifndef max
+#define max(a,b) ((b)>(a)?(b):(a))
+#endif
+
+/*
+ * The default snapshot length.  This value allows most printers to print
+ * useful information while keeping the amount of unwanted data down.
+ * In particular, it allows for an ethernet header, tcp/ip header, and
+ * 14 bytes of data (assuming no ip options).
+ */
+#define DEFAULT_SNAPLEN 68
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234
+#endif
+
+#ifdef ETHER_HEADER_HAS_EA
+#define ESRC(ep) ((ep)->ether_shost.ether_addr_octet)
+#define EDST(ep) ((ep)->ether_dhost.ether_addr_octet)
+#else
+#define ESRC(ep) ((ep)->ether_shost)
+#define EDST(ep) ((ep)->ether_dhost)
+#endif
+
+#ifdef ETHER_ARP_HAS_X
+#define SHA(ap) ((ap)->arp_xsha)
+#define THA(ap) ((ap)->arp_xtha)
+#define SPA(ap) ((ap)->arp_xspa)
+#define TPA(ap) ((ap)->arp_xtpa)
+#else
+#ifdef ETHER_ARP_HAS_EA
+#define SHA(ap) ((ap)->arp_sha.ether_addr_octet)
+#define THA(ap) ((ap)->arp_tha.ether_addr_octet)
+#else
+#define SHA(ap) ((ap)->arp_sha)
+#define THA(ap) ((ap)->arp_tha)
+#endif
+#define SPA(ap) ((ap)->arp_spa)
+#define TPA(ap) ((ap)->arp_tpa)
+#endif
+
+#ifndef NTOHL
+#define NTOHL(x)	(x) = ntohl(x)
+#define NTOHS(x)	(x) = ntohs(x)
+#define HTONL(x)	(x) = htonl(x)
+#define HTONS(x)	(x) = htons(x)
+#endif
+#endif
+
+extern char *program_name;	/* used to generate self-identifying messages */
+
+extern int32_t thiszone;	/* seconds offset from gmt to local time */
+
+extern int snaplen;
+/* global pointers to beginning and end of current packet (during printing) */
+extern const u_char *packetp;
+extern const u_char *snapend;
+
+/* True if  "l" bytes of "var" were captured */
+#define TTEST2(var, l) ((u_char *)&(var) <= snapend - (l))
+
+/* True if "var" was captured */
+#define TTEST(var) TTEST2(var, sizeof(var))
+
+/* Bail if "l" bytes of "var" were not captured */
+#define TCHECK2(var, l) if (!TTEST2(var, l)) goto trunc
+
+/* Bail if "var" was not captured */
+#define TCHECK(var) TCHECK2(var, sizeof(var))
+
+#ifdef __STDC__
+struct timeval;
+#endif
+
+extern void ts_print(const struct timeval *);
+extern int32_t gmt2local(void);
+
+extern int fn_print(const u_char *, const u_char *);
+extern int fn_printn(const u_char *, u_int, const u_char *);
+extern const char *tok2str(const struct tok *, const char *, int);
+extern char *dnaddr_string(u_short);
+extern char *savestr(const char *);
+
+extern void wrapup(int);
+
+#if __STDC__
+extern __dead void error(const char *, ...)
+    __attribute__((volatile, format (printf, 1, 2)));
+extern void warning(const char *, ...) __attribute__ ((format (printf, 1, 2)));
+#endif
+
+extern char *read_infile(char *);
+extern char *copy_argv(char **);
+
+extern char *isonsap_string(const u_char *);
+extern char *llcsap_string(u_char);
+extern char *protoid_string(const u_char *);
+extern char *dnname_string(u_short);
+extern char *dnnum_string(u_short);
+
+/* The printer routines. */
+
+#ifdef __STDC__
+struct pcap_pkthdr;
+#endif
+
+extern int ether_encap_print(u_short, const u_char *, u_int, u_int);
+extern int llc_print(const u_char *, u_int, u_int, const u_char *,
+	const u_char *);
+extern void aarp_print(const u_char *, u_int);
+extern void arp_print(const u_char *, u_int, u_int);
+extern void atalk_print(const u_char *, u_int);
+extern void atm_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern void bootp_print(const u_char *, u_int, u_short, u_short);
+extern void decnet_print(const u_char *, u_int, u_int);
+extern void default_print(const u_char *, u_int);
+extern void default_print_unaligned(const u_char *, u_int);
+extern void dvmrp_print(const u_char *, u_int);
+extern void egp_print(const u_char *, u_int, const u_char *);
+extern void ether_if_print(u_char *, const struct pcap_pkthdr *,
+	const u_char *);
+extern void fddi_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern void gre_print(const u_char *, u_int);
+extern void icmp_print(const u_char *, const u_char *);
+extern void igrp_print(const u_char *, u_int, const u_char *);
+extern void ip_print(const u_char *, u_int);
+extern void ipx_print(const u_char *, u_int);
+extern void isoclns_print(const u_char *, u_int, u_int, const u_char *,
+	const u_char *);
+extern void krb_print(const u_char *, u_int);
+extern void nfsreply_print(const u_char *, u_int, const u_char *);
+extern void nfsreq_print(const u_char *, u_int, const u_char *);
+extern void ns_print(const u_char *, u_int);
+extern void ntp_print(const u_char *, u_int);
+extern void null_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern void ospf_print(const u_char *, u_int, const u_char *);
+extern void pim_print(const u_char *, u_int);
+extern void ppp_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern void rip_print(const u_char *, u_int);
+extern void sl_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern void snmp_print(const u_char *, u_int);
+extern void sunrpcrequest_print(const u_char *, u_int, const u_char *);
+extern void tcp_print(const u_char *, u_int, const u_char *);
+extern void tftp_print(const u_char *, u_int);
+extern void udp_print(const u_char *, u_int, const u_char *);
+extern void wb_print(const void *, u_int);
diff --git a/tcpdump.tproj/ipx.h b/tcpdump.tproj/ipx.h
new file mode 100644
index 0000000..e1dda81
--- /dev/null
+++ b/tcpdump.tproj/ipx.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * IPX protocol formats 
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/ipx.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $
+ */
+
+/* well-known sockets */
+#define	IPX_SKT_NCP		0x0451
+#define	IPX_SKT_SAP		0x0452
+#define	IPX_SKT_RIP		0x0453
+#define	IPX_SKT_NETBIOS		0x0455
+#define	IPX_SKT_DIAGNOSTICS	0x0456
+
+/* IPX transport header */
+struct ipxHdr {
+    u_short	cksum;		/* Checksum */
+    u_short	length;		/* Length, in bytes, including header */
+    u_char	tCtl;		/* Transport Control (i.e. hop count) */
+    u_char	pType;		/* Packet Type (i.e. level 2 protocol) */
+    u_short	dstNet[2];	/* destination net */
+    u_char	dstNode[6];	/* destination node */
+    u_short	dstSkt;		/* destination socket */
+    u_short	srcNet[2];	/* source net */
+    u_char	srcNode[6];	/* source node */
+    u_short	srcSkt;		/* source socket */
+} ipx_hdr_t;
+
+#define ipxSize	30
+
diff --git a/tcpdump.tproj/llc.h b/tcpdump.tproj/llc.h
new file mode 100644
index 0000000..4432514
--- /dev/null
+++ b/tcpdump.tproj/llc.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/llc.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ (LBL)
+ */
+
+/*
+ * This stuff should come from a system header file, but there's no
+ * obviously portable way to do that and it's not really going
+ * to change from system to system.
+ */
+
+/*
+ * A somewhat abstracted view of the LLC header
+ */
+
+struct llc {
+	u_char dsap;
+	u_char ssap;
+	union {
+		u_char u_ctl;
+		u_short is_ctl;
+		struct {
+			u_char snap_ui;
+			u_char snap_pi[5];
+		} snap;
+		struct {
+			u_char snap_ui;
+			u_char snap_orgcode[3];
+			u_char snap_ethertype[2];
+		} snap_ether;
+	} ctl;
+};
+
+#define	llcui		ctl.snap.snap_ui
+#define	llcpi		ctl.snap.snap_pi
+#define	orgcode		ctl.snap_ether.snap_orgcode
+#define	ethertype	ctl.snap_ether.snap_ethertype
+#define	llcis		ctl.is_ctl
+#define	llcu		ctl.u_ctl
+
+#define	LLC_U_FMT	3
+#define	LLC_GSAP	1
+#define LLC_S_FMT	1
+
+#define	LLC_U_POLL	0x10
+#define	LLC_IS_POLL	0x0001
+#define	LLC_XID_FI	0x81
+
+#define	LLC_U_CMD(u)	((u) & 0xef)
+#define	LLC_UI		0x03
+#define	LLC_UA		0x63
+#define	LLC_DISC	0x43
+#define	LLC_DM		0x0f
+#define	LLC_SABME	0x6f
+#define	LLC_TEST	0xe3
+#define	LLC_XID		0xaf
+#define	LLC_FRMR	0x87
+
+#define	LLC_S_CMD(is)	(((is) >> 10) & 0x03)
+#define	LLC_RR		0x0100
+#define	LLC_RNR		0x0500
+#define	LLC_REJ		0x0900
+
+#define LLC_IS_NR(is)	(((is) >> 9) & 0x7f)
+#define LLC_I_NS(is)	(((is) >> 1) & 0x7f)
+
+#ifndef LLCSAP_NULL
+#define	LLCSAP_NULL		0x00
+#endif
+#ifndef LLCSAP_GLOBAL
+#define	LLCSAP_GLOBAL		0xff
+#endif
+#ifndef LLCSAP_8021B
+#define	LLCSAP_8021B_I		0x02
+#endif
+#ifndef LLCSAP_8021B
+#define	LLCSAP_8021B_G		0x03
+#endif
+#ifndef LLCSAP_IP
+#define	LLCSAP_IP		0x06
+#endif
+#ifndef LLCSAP_PROWAYNM
+#define	LLCSAP_PROWAYNM		0x0e
+#endif
+#ifndef LLCSAP_8021D
+#define	LLCSAP_8021D		0x42
+#endif
+#ifndef LLCSAP_RS511
+#define	LLCSAP_RS511		0x4e
+#endif
+#ifndef LLCSAP_ISO8208
+#define	LLCSAP_ISO8208		0x7e
+#endif
+#ifndef LLCSAP_PROWAY
+#define	LLCSAP_PROWAY		0x8e
+#endif
+#ifndef LLCSAP_SNAP
+#define	LLCSAP_SNAP		0xaa
+#endif
+#ifndef LLCSAP_ISONS
+#define	LLCSAP_ISONS		0xfe
+#endif
diff --git a/tcpdump.tproj/machdep.c b/tcpdump.tproj/machdep.c
new file mode 100644
index 0000000..df136f4
--- /dev/null
+++ b/tcpdump.tproj/machdep.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/machdep.c,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#ifdef __osf__
+#include <sys/sysinfo.h>
+#include <sys/proc.h>
+#endif
+
+#include <pcap.h>
+
+#include "machdep.h"
+
+int
+abort_on_misalignment(char *ebuf)
+{
+#ifdef __osf__
+	static int buf[2] = { SSIN_UACPROC, UAC_SIGBUS };
+
+	if (setsysinfo(SSI_NVPAIRS, (caddr_t)buf, 1, 0, 0) < 0) {
+		(void)sprintf(ebuf, "setsysinfo: %s", pcap_strerror(errno));
+		return (-1);
+	}
+#endif
+	return (0);
+}
diff --git a/tcpdump.tproj/machdep.h b/tcpdump.tproj/machdep.h
new file mode 100644
index 0000000..7e8d45a
--- /dev/null
+++ b/tcpdump.tproj/machdep.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/machdep.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ (LBL)
+ */
+#ifndef tcpdump_machdep_h
+#define tcpdump_machdep_h
+
+int abort_on_misalignment(char *);
+#endif
diff --git a/tcpdump.tproj/mib.h b/tcpdump.tproj/mib.h
new file mode 100644
index 0000000..454d6b2
--- /dev/null
+++ b/tcpdump.tproj/mib.h
@@ -0,0 +1,1279 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * This file was generated by tcpdump/makemib on Wed Sep 26 12:12:31 EDT 1990
+ * You probably don't want to edit this by hand!
+ *
+ * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer
+};
+ */
+
+/* parse problem: new name "mib" for mgmt.mib(1) ignored */
+/* parse problem: no parent for 0.nullSpecific(0) */
+struct obj
+_proteon_obj = {
+	"proteon", 1, 0,
+	NULL, NULL
+},
+_ibm_obj = {
+	"ibm", 2, 0,
+	NULL, &_proteon_obj
+},
+_cmu_obj = {
+	"cmu", 3, 0,
+	NULL, &_ibm_obj
+},
+_unix_obj = {
+	"unix", 4, 0,
+	NULL, &_cmu_obj
+},
+_acc_obj = {
+	"acc", 5, 0,
+	NULL, &_unix_obj
+},
+_twg_obj = {
+	"twg", 6, 0,
+	NULL, &_acc_obj
+},
+_cayman_obj = {
+	"cayman", 7, 0,
+	NULL, &_twg_obj
+},
+_nysernet_obj = {
+	"nysernet", 8, 0,
+	NULL, &_cayman_obj
+},
+_cisco_obj = {
+	"cisco", 9, 0,
+	NULL, &_nysernet_obj
+},
+_nsc_obj = {
+	"nsc", 10, 0,
+	NULL, &_cisco_obj
+},
+_hp_obj = {
+	"hp", 11, 0,
+	NULL, &_nsc_obj
+},
+_epilogue_obj = {
+	"epilogue", 12, 0,
+	NULL, &_hp_obj
+},
+_utennessee_obj = {
+	"utennessee", 13, 0,
+	NULL, &_epilogue_obj
+},
+_bbn_obj = {
+	"bbn", 14, 0,
+	NULL, &_utennessee_obj
+},
+_xylogics_obj = {
+	"xylogics", 15, 0,
+	NULL, &_bbn_obj
+},
+_unisys_obj = {
+	"unisys", 16, 0,
+	NULL, &_xylogics_obj
+},
+_canstar_obj = {
+	"canstar", 17, 0,
+	NULL, &_unisys_obj
+},
+_wellfleet_obj = {
+	"wellfleet", 18, 0,
+	NULL, &_canstar_obj
+},
+_trw_obj = {
+	"trw", 19, 0,
+	NULL, &_wellfleet_obj
+},
+_mit_obj = {
+	"mit", 20, 0,
+	NULL, &_trw_obj
+},
+_eon_obj = {
+	"eon", 21, 0,
+	NULL, &_mit_obj
+},
+_spartacus_obj = {
+	"spartacus", 22, 0,
+	NULL, &_eon_obj
+},
+_excelan_obj = {
+	"excelan", 23, 0,
+	NULL, &_spartacus_obj
+},
+_spider_obj = {
+	"spider", 24, 0,
+	NULL, &_excelan_obj
+},
+_nsfnet_obj = {
+	"nsfnet", 25, 0,
+	NULL, &_spider_obj
+},
+_sytek_obj = {
+	"sytek", 26, 0,
+	NULL, &_nsfnet_obj
+},
+_intergraph_obj = {
+	"intergraph", 27, 0,
+	NULL, &_sytek_obj
+},
+_interlan_obj = {
+	"interlan", 28, 0,
+	NULL, &_intergraph_obj
+},
+_vitalink_obj = {
+	"vitalink", 29, 0,
+	NULL, &_interlan_obj
+},
+_ulana_obj = {
+	"ulana", 30, 0,
+	NULL, &_vitalink_obj
+},
+_nswc_obj = {
+	"nswc", 31, 0,
+	NULL, &_ulana_obj
+},
+_santacruzoperation_obj = {
+	"santacruzoperation", 32, 0,
+	NULL, &_nswc_obj
+},
+_xyplex_obj = {
+	"xyplex", 33, 0,
+	NULL, &_santacruzoperation_obj
+},
+_cray_obj = {
+	"cray", 34, 0,
+	NULL, &_xyplex_obj
+},
+_bellnorthernresearch_obj = {
+	"bellnorthernresearch", 35, 0,
+	NULL, &_cray_obj
+},
+_dec_obj = {
+	"dec", 36, 0,
+	NULL, &_bellnorthernresearch_obj
+},
+_touch_obj = {
+	"touch", 37, 0,
+	NULL, &_dec_obj
+},
+_networkresearchcorp_obj = {
+	"networkresearchcorp", 38, 0,
+	NULL, &_touch_obj
+},
+_baylor_obj = {
+	"baylor", 39, 0,
+	NULL, &_networkresearchcorp_obj
+},
+_nmfeccllnl_obj = {
+	"nmfeccllnl", 40, 0,
+	NULL, &_baylor_obj
+},
+_sri_obj = {
+	"sri", 41, 0,
+	NULL, &_nmfeccllnl_obj
+},
+_sun_obj = {
+	"sun", 42, 0,
+	NULL, &_sri_obj
+},
+_3com_obj = {
+	"3com", 43, 0,
+	NULL, &_sun_obj
+},
+_cmc_obj = {
+	"cmc", 44, 0,
+	NULL, &_3com_obj
+},
+_synoptics_obj = {
+	"synoptics", 45, 0,
+	NULL, &_cmc_obj
+},
+_cheyenne_obj = {
+	"cheyenne", 46, 0,
+	NULL, &_synoptics_obj
+},
+_prime_obj = {
+	"prime", 47, 0,
+	NULL, &_cheyenne_obj
+},
+_mcnc_obj = {
+	"mcnc", 48, 0,
+	NULL, &_prime_obj
+},
+_chipcom_obj = {
+	"chipcom", 49, 0,
+	NULL, &_mcnc_obj
+},
+_opticaldatasystems_obj = {
+	"opticaldatasystems", 50, 0,
+	NULL, &_chipcom_obj
+},
+_gated_obj = {
+	"gated", 51, 0,
+	NULL, &_opticaldatasystems_obj
+},
+_cabletron_obj = {
+	"cabletron", 52, 0,
+	NULL, &_gated_obj
+},
+_apollo_obj = {
+	"apollo", 53, 0,
+	NULL, &_cabletron_obj
+},
+_desktalksystems_obj = {
+	"desktalksystems", 54, 0,
+	NULL, &_apollo_obj
+},
+_ssds_obj = {
+	"ssds", 55, 0,
+	NULL, &_desktalksystems_obj
+},
+_castlerock_obj = {
+	"castlerock", 56, 0,
+	NULL, &_ssds_obj
+},
+_mips_obj = {
+	"mips", 57, 0,
+	NULL, &_castlerock_obj
+},
+_tgv_obj = {
+	"tgv", 58, 0,
+	NULL, &_mips_obj
+},
+_silicongraphics_obj = {
+	"silicongraphics", 59, 0,
+	NULL, &_tgv_obj
+},
+_ubc_obj = {
+	"ubc", 60, 0,
+	NULL, &_silicongraphics_obj
+},
+_merit_obj = {
+	"merit", 61, 0,
+	NULL, &_ubc_obj
+},
+_fibercom_obj = {
+	"fibercom", 62, 0,
+	NULL, &_merit_obj
+},
+_apple_obj = {
+	"apple", 63, 0,
+	NULL, &_fibercom_obj
+},
+_gandalf_obj = {
+	"gandalf", 64, 0,
+	NULL, &_apple_obj
+},
+_dartmouth_obj = {
+	"dartmouth", 65, 0,
+	NULL, &_gandalf_obj
+},
+_davidsystems_obj = {
+	"davidsystems", 66, 0,
+	NULL, &_dartmouth_obj
+},
+_reuter_obj = {
+	"reuter", 67, 0,
+	NULL, &_davidsystems_obj
+},
+_cornell_obj = {
+	"cornell", 68, 0,
+	NULL, &_reuter_obj
+},
+_tmac_obj = {
+	"tmac", 69, 0,
+	NULL, &_cornell_obj
+},
+_locus_obj = {
+	"locus", 70, 0,
+	NULL, &_tmac_obj
+},
+_nasa_obj = {
+	"nasa", 71, 0,
+	NULL, &_locus_obj
+},
+_retix_obj = {
+	"retix", 72, 0,
+	NULL, &_nasa_obj
+},
+_boeing_obj = {
+	"boeing", 73, 0,
+	NULL, &_retix_obj
+},
+_att_obj = {
+	"att", 74, 0,
+	NULL, &_boeing_obj
+},
+_ungermannbass_obj = {
+	"ungermannbass", 75, 0,
+	NULL, &_att_obj
+},
+_digitalanalysis_obj = {
+	"digitalanalysis", 76, 0,
+	NULL, &_ungermannbass_obj
+},
+_hplanman_obj = {
+	"hplanman", 77, 0,
+	NULL, &_digitalanalysis_obj
+},
+_netlabs_obj = {
+	"netlabs", 78, 0,
+	NULL, &_hplanman_obj
+},
+_icl_obj = {
+	"icl", 79, 0,
+	NULL, &_netlabs_obj
+},
+_auspex_obj = {
+	"auspex", 80, 0,
+	NULL, &_icl_obj
+},
+_lannet_obj = {
+	"lannet", 81, 0,
+	NULL, &_auspex_obj
+},
+_ncd_obj = {
+	"ncd", 82, 0,
+	NULL, &_lannet_obj
+},
+_raycom_obj = {
+	"raycom", 83, 0,
+	NULL, &_ncd_obj
+},
+_pirellifocom_obj = {
+	"pirellifocom", 84, 0,
+	NULL, &_raycom_obj
+},
+_datability_obj = {
+	"datability", 85, 0,
+	NULL, &_pirellifocom_obj
+},
+_networkappltech_obj = {
+	"networkappltech", 86, 0,
+	NULL, &_datability_obj
+},
+_link_obj = {
+	"link", 87, 0,
+	NULL, &_networkappltech_obj
+},
+_nyu_obj = {
+	"nyu", 88, 0,
+	NULL, &_link_obj
+},
+_rnd_obj = {
+	"rnd", 89, 0,
+	NULL, &_nyu_obj
+},
+_intercon_obj = {
+	"intercon", 90, 0,
+	NULL, &_rnd_obj
+},
+_learningtree_obj = {
+	"learningtree", 91, 0,
+	NULL, &_intercon_obj
+},
+_webstercomputer_obj = {
+	"webstercomputer", 92, 0,
+	NULL, &_learningtree_obj
+},
+_frontier_obj = {
+	"frontier", 93, 0,
+	NULL, &_webstercomputer_obj
+},
+_nokia_obj = {
+	"nokia", 94, 0,
+	NULL, &_frontier_obj
+},
+_allenbradley_obj = {
+	"allenbradley", 95, 0,
+	NULL, &_nokia_obj
+},
+_cern_obj = {
+	"cern", 96, 0,
+	NULL, &_allenbradley_obj
+},
+_sigma_obj = {
+	"sigma", 97, 0,
+	NULL, &_cern_obj
+},
+_emergingtech_obj = {
+	"emergingtech", 98, 0,
+	NULL, &_sigma_obj
+},
+_snmpresearch_obj = {
+	"snmpresearch", 99, 0,
+	NULL, &_emergingtech_obj
+},
+_ohiostate_obj = {
+	"ohiostate", 100, 0,
+	NULL, &_snmpresearch_obj
+},
+_ultra_obj = {
+	"ultra", 101, 0,
+	NULL, &_ohiostate_obj
+},
+_ccur_obj = {
+	"ccur", 136, 0,
+	NULL, &_ultra_obj
+},
+_enterprises_obj = {
+	"enterprises", 1, 0,
+	&_ccur_obj, NULL
+},
+_snmpInPkts_obj = {
+	"snmpInPkts", 1, 0,
+	NULL, NULL
+},
+_snmpOutPkts_obj = {
+	"snmpOutPkts", 2, 0,
+	NULL, &_snmpInPkts_obj
+},
+_snmpInBadVersions_obj = {
+	"snmpInBadVersions", 3, 0,
+	NULL, &_snmpOutPkts_obj
+},
+_snmpInBadCommunityNames_obj = {
+	"snmpInBadCommunityNames", 4, 0,
+	NULL, &_snmpInBadVersions_obj
+},
+_snmpInBadCommunityUses_obj = {
+	"snmpInBadCommunityUses", 5, 0,
+	NULL, &_snmpInBadCommunityNames_obj
+},
+_snmpInASNParseErrs_obj = {
+	"snmpInASNParseErrs", 6, 0,
+	NULL, &_snmpInBadCommunityUses_obj
+},
+_snmpInBadTypes_obj = {
+	"snmpInBadTypes", 7, 0,
+	NULL, &_snmpInASNParseErrs_obj
+},
+_snmpInTooBigs_obj = {
+	"snmpInTooBigs", 8, 0,
+	NULL, &_snmpInBadTypes_obj
+},
+_snmpInNoSuchNames_obj = {
+	"snmpInNoSuchNames", 9, 0,
+	NULL, &_snmpInTooBigs_obj
+},
+_snmpInBadValues_obj = {
+	"snmpInBadValues", 10, 0,
+	NULL, &_snmpInNoSuchNames_obj
+},
+_snmpInReadOnlys_obj = {
+	"snmpInReadOnlys", 11, 0,
+	NULL, &_snmpInBadValues_obj
+},
+_snmpInGenErrs_obj = {
+	"snmpInGenErrs", 12, 0,
+	NULL, &_snmpInReadOnlys_obj
+},
+_snmpInTotalReqVars_obj = {
+	"snmpInTotalReqVars", 13, 0,
+	NULL, &_snmpInGenErrs_obj
+},
+_snmpInTotalSetVars_obj = {
+	"snmpInTotalSetVars", 14, 0,
+	NULL, &_snmpInTotalReqVars_obj
+},
+_snmpInGetRequests_obj = {
+	"snmpInGetRequests", 15, 0,
+	NULL, &_snmpInTotalSetVars_obj
+},
+_snmpInGetNexts_obj = {
+	"snmpInGetNexts", 16, 0,
+	NULL, &_snmpInGetRequests_obj
+},
+_snmpInSetRequests_obj = {
+	"snmpInSetRequests", 17, 0,
+	NULL, &_snmpInGetNexts_obj
+},
+_snmpInGetResponses_obj = {
+	"snmpInGetResponses", 18, 0,
+	NULL, &_snmpInSetRequests_obj
+},
+_snmpInTraps_obj = {
+	"snmpInTraps", 19, 0,
+	NULL, &_snmpInGetResponses_obj
+},
+_snmpOutTooBigs_obj = {
+	"snmpOutTooBigs", 20, 0,
+	NULL, &_snmpInTraps_obj
+},
+_snmpOutNoSuchNames_obj = {
+	"snmpOutNoSuchNames", 21, 0,
+	NULL, &_snmpOutTooBigs_obj
+},
+_snmpOutBadValues_obj = {
+	"snmpOutBadValues", 22, 0,
+	NULL, &_snmpOutNoSuchNames_obj
+},
+_snmpOutReadOnlys_obj = {
+	"snmpOutReadOnlys", 23, 0,
+	NULL, &_snmpOutBadValues_obj
+},
+_snmpOutGenErrs_obj = {
+	"snmpOutGenErrs", 24, 0,
+	NULL, &_snmpOutReadOnlys_obj
+},
+_snmpOutGetRequests_obj = {
+	"snmpOutGetRequests", 25, 0,
+	NULL, &_snmpOutGenErrs_obj
+},
+_snmpOutGetNexts_obj = {
+	"snmpOutGetNexts", 26, 0,
+	NULL, &_snmpOutGetRequests_obj
+},
+_snmpOutSetRequests_obj = {
+	"snmpOutSetRequests", 27, 0,
+	NULL, &_snmpOutGetNexts_obj
+},
+_snmpOutGetResponses_obj = {
+	"snmpOutGetResponses", 28, 0,
+	NULL, &_snmpOutSetRequests_obj
+},
+_snmpOutTraps_obj = {
+	"snmpOutTraps", 29, 0,
+	NULL, &_snmpOutGetResponses_obj
+},
+_snmpEnableAuthTraps_obj = {
+	"snmpEnableAuthTraps", 30, 0,
+	NULL, &_snmpOutTraps_obj
+},
+_egpNeighState_obj = {
+	"egpNeighState", 1, 0,
+	NULL, NULL
+},
+_egpNeighAddr_obj = {
+	"egpNeighAddr", 2, 0,
+	NULL, &_egpNeighState_obj
+},
+_egpNeighAs_obj = {
+	"egpNeighAs", 3, 0,
+	NULL, &_egpNeighAddr_obj
+},
+_egpNeighInMsgs_obj = {
+	"egpNeighInMsgs", 4, 0,
+	NULL, &_egpNeighAs_obj
+},
+_egpNeighInErrs_obj = {
+	"egpNeighInErrs", 5, 0,
+	NULL, &_egpNeighInMsgs_obj
+},
+_egpNeighOutMsgs_obj = {
+	"egpNeighOutMsgs", 6, 0,
+	NULL, &_egpNeighInErrs_obj
+},
+_egpNeighOutErrs_obj = {
+	"egpNeighOutErrs", 7, 0,
+	NULL, &_egpNeighOutMsgs_obj
+},
+_egpNeighInErrMsgs_obj = {
+	"egpNeighInErrMsgs", 8, 0,
+	NULL, &_egpNeighOutErrs_obj
+},
+_egpNeighOutErrMsgs_obj = {
+	"egpNeighOutErrMsgs", 9, 0,
+	NULL, &_egpNeighInErrMsgs_obj
+},
+_egpNeighStateUps_obj = {
+	"egpNeighStateUps", 10, 0,
+	NULL, &_egpNeighOutErrMsgs_obj
+},
+_egpNeighStateDowns_obj = {
+	"egpNeighStateDowns", 11, 0,
+	NULL, &_egpNeighStateUps_obj
+},
+_egpNeighIntervalHello_obj = {
+	"egpNeighIntervalHello", 12, 0,
+	NULL, &_egpNeighStateDowns_obj
+},
+_egpNeighIntervalPoll_obj = {
+	"egpNeighIntervalPoll", 13, 0,
+	NULL, &_egpNeighIntervalHello_obj
+},
+_egpNeighMode_obj = {
+	"egpNeighMode", 14, 0,
+	NULL, &_egpNeighIntervalPoll_obj
+},
+_egpNeighEventTrigger_obj = {
+	"egpNeighEventTrigger", 15, 0,
+	NULL, &_egpNeighMode_obj
+},
+_egpNeighEntry_obj = {
+	"egpNeighEntry", 1, 0,
+	&_egpNeighEventTrigger_obj, NULL
+},
+_egpInMsgs_obj = {
+	"egpInMsgs", 1, 0,
+	NULL, NULL
+},
+_egpInErrors_obj = {
+	"egpInErrors", 2, 0,
+	NULL, &_egpInMsgs_obj
+},
+_egpOutMsgs_obj = {
+	"egpOutMsgs", 3, 0,
+	NULL, &_egpInErrors_obj
+},
+_egpOutErrors_obj = {
+	"egpOutErrors", 4, 0,
+	NULL, &_egpOutMsgs_obj
+},
+_egpNeighTable_obj = {
+	"egpNeighTable", 5, 0,
+	&_egpNeighEntry_obj, &_egpOutErrors_obj
+},
+_egpAs_obj = {
+	"egpAs", 6, 0,
+	NULL, &_egpNeighTable_obj
+},
+_udpLocalAddress_obj = {
+	"udpLocalAddress", 1, 0,
+	NULL, NULL
+},
+_udpLocalPort_obj = {
+	"udpLocalPort", 2, 0,
+	NULL, &_udpLocalAddress_obj
+},
+_udpEntry_obj = {
+	"udpEntry", 1, 0,
+	&_udpLocalPort_obj, NULL
+},
+_udpInDatagrams_obj = {
+	"udpInDatagrams", 1, 0,
+	NULL, NULL
+},
+_udpNoPorts_obj = {
+	"udpNoPorts", 2, 0,
+	NULL, &_udpInDatagrams_obj
+},
+_udpInErrors_obj = {
+	"udpInErrors", 3, 0,
+	NULL, &_udpNoPorts_obj
+},
+_udpOutDatagrams_obj = {
+	"udpOutDatagrams", 4, 0,
+	NULL, &_udpInErrors_obj
+},
+_udpTable_obj = {
+	"udpTable", 5, 0,
+	&_udpEntry_obj, &_udpOutDatagrams_obj
+},
+_tcpConnState_obj = {
+	"tcpConnState", 1, 0,
+	NULL, NULL
+},
+_tcpConnLocalAddress_obj = {
+	"tcpConnLocalAddress", 2, 0,
+	NULL, &_tcpConnState_obj
+},
+_tcpConnLocalPort_obj = {
+	"tcpConnLocalPort", 3, 0,
+	NULL, &_tcpConnLocalAddress_obj
+},
+_tcpConnRemAddress_obj = {
+	"tcpConnRemAddress", 4, 0,
+	NULL, &_tcpConnLocalPort_obj
+},
+_tcpConnRemPort_obj = {
+	"tcpConnRemPort", 5, 0,
+	NULL, &_tcpConnRemAddress_obj
+},
+_tcpConnEntry_obj = {
+	"tcpConnEntry", 1, 0,
+	&_tcpConnRemPort_obj, NULL
+},
+_tcpRtoAlgorithm_obj = {
+	"tcpRtoAlgorithm", 1, 0,
+	NULL, NULL
+},
+_tcpRtoMin_obj = {
+	"tcpRtoMin", 2, 0,
+	NULL, &_tcpRtoAlgorithm_obj
+},
+_tcpRtoMax_obj = {
+	"tcpRtoMax", 3, 0,
+	NULL, &_tcpRtoMin_obj
+},
+_tcpMaxConn_obj = {
+	"tcpMaxConn", 4, 0,
+	NULL, &_tcpRtoMax_obj
+},
+_tcpActiveOpens_obj = {
+	"tcpActiveOpens", 5, 0,
+	NULL, &_tcpMaxConn_obj
+},
+_tcpPassiveOpens_obj = {
+	"tcpPassiveOpens", 6, 0,
+	NULL, &_tcpActiveOpens_obj
+},
+_tcpAttemptFails_obj = {
+	"tcpAttemptFails", 7, 0,
+	NULL, &_tcpPassiveOpens_obj
+},
+_tcpEstabResets_obj = {
+	"tcpEstabResets", 8, 0,
+	NULL, &_tcpAttemptFails_obj
+},
+_tcpCurrEstab_obj = {
+	"tcpCurrEstab", 9, 0,
+	NULL, &_tcpEstabResets_obj
+},
+_tcpInSegs_obj = {
+	"tcpInSegs", 10, 0,
+	NULL, &_tcpCurrEstab_obj
+},
+_tcpOutSegs_obj = {
+	"tcpOutSegs", 11, 0,
+	NULL, &_tcpInSegs_obj
+},
+_tcpRetransSegs_obj = {
+	"tcpRetransSegs", 12, 0,
+	NULL, &_tcpOutSegs_obj
+},
+_tcpConnTable_obj = {
+	"tcpConnTable", 13, 0,
+	&_tcpConnEntry_obj, &_tcpRetransSegs_obj
+},
+_tcpInErrs_obj = {
+	"tcpInErrs", 14, 0,
+	NULL, &_tcpConnTable_obj
+},
+_tcpOutRsts_obj = {
+	"tcpOutRsts", 15, 0,
+	NULL, &_tcpInErrs_obj
+},
+_icmpInMsgs_obj = {
+	"icmpInMsgs", 1, 0,
+	NULL, NULL
+},
+_icmpInErrors_obj = {
+	"icmpInErrors", 2, 0,
+	NULL, &_icmpInMsgs_obj
+},
+_icmpInDestUnreachs_obj = {
+	"icmpInDestUnreachs", 3, 0,
+	NULL, &_icmpInErrors_obj
+},
+_icmpInTimeExcds_obj = {
+	"icmpInTimeExcds", 4, 0,
+	NULL, &_icmpInDestUnreachs_obj
+},
+_icmpInParmProbs_obj = {
+	"icmpInParmProbs", 5, 0,
+	NULL, &_icmpInTimeExcds_obj
+},
+_icmpInSrcQuenchs_obj = {
+	"icmpInSrcQuenchs", 6, 0,
+	NULL, &_icmpInParmProbs_obj
+},
+_icmpInRedirects_obj = {
+	"icmpInRedirects", 7, 0,
+	NULL, &_icmpInSrcQuenchs_obj
+},
+_icmpInEchos_obj = {
+	"icmpInEchos", 8, 0,
+	NULL, &_icmpInRedirects_obj
+},
+_icmpInEchoReps_obj = {
+	"icmpInEchoReps", 9, 0,
+	NULL, &_icmpInEchos_obj
+},
+_icmpInTimestamps_obj = {
+	"icmpInTimestamps", 10, 0,
+	NULL, &_icmpInEchoReps_obj
+},
+_icmpInTimestampReps_obj = {
+	"icmpInTimestampReps", 11, 0,
+	NULL, &_icmpInTimestamps_obj
+},
+_icmpInAddrMasks_obj = {
+	"icmpInAddrMasks", 12, 0,
+	NULL, &_icmpInTimestampReps_obj
+},
+_icmpInAddrMaskReps_obj = {
+	"icmpInAddrMaskReps", 13, 0,
+	NULL, &_icmpInAddrMasks_obj
+},
+_icmpOutMsgs_obj = {
+	"icmpOutMsgs", 14, 0,
+	NULL, &_icmpInAddrMaskReps_obj
+},
+_icmpOutErrors_obj = {
+	"icmpOutErrors", 15, 0,
+	NULL, &_icmpOutMsgs_obj
+},
+_icmpOutDestUnreachs_obj = {
+	"icmpOutDestUnreachs", 16, 0,
+	NULL, &_icmpOutErrors_obj
+},
+_icmpOutTimeExcds_obj = {
+	"icmpOutTimeExcds", 17, 0,
+	NULL, &_icmpOutDestUnreachs_obj
+},
+_icmpOutParmProbs_obj = {
+	"icmpOutParmProbs", 18, 0,
+	NULL, &_icmpOutTimeExcds_obj
+},
+_icmpOutSrcQuenchs_obj = {
+	"icmpOutSrcQuenchs", 19, 0,
+	NULL, &_icmpOutParmProbs_obj
+},
+_icmpOutRedirects_obj = {
+	"icmpOutRedirects", 20, 0,
+	NULL, &_icmpOutSrcQuenchs_obj
+},
+_icmpOutEchos_obj = {
+	"icmpOutEchos", 21, 0,
+	NULL, &_icmpOutRedirects_obj
+},
+_icmpOutEchoReps_obj = {
+	"icmpOutEchoReps", 22, 0,
+	NULL, &_icmpOutEchos_obj
+},
+_icmpOutTimestamps_obj = {
+	"icmpOutTimestamps", 23, 0,
+	NULL, &_icmpOutEchoReps_obj
+},
+_icmpOutTimestampReps_obj = {
+	"icmpOutTimestampReps", 24, 0,
+	NULL, &_icmpOutTimestamps_obj
+},
+_icmpOutAddrMasks_obj = {
+	"icmpOutAddrMasks", 25, 0,
+	NULL, &_icmpOutTimestampReps_obj
+},
+_icmpOutAddrMaskReps_obj = {
+	"icmpOutAddrMaskReps", 26, 0,
+	NULL, &_icmpOutAddrMasks_obj
+},
+_ipNetToMediaIfIndex_obj = {
+	"ipNetToMediaIfIndex", 1, 0,
+	NULL, NULL
+},
+_ipNetToMediaPhysAddress_obj = {
+	"ipNetToMediaPhysAddress", 2, 0,
+	NULL, &_ipNetToMediaIfIndex_obj
+},
+_ipNetToMediaNetAddress_obj = {
+	"ipNetToMediaNetAddress", 3, 0,
+	NULL, &_ipNetToMediaPhysAddress_obj
+},
+_ipNetToMediaType_obj = {
+	"ipNetToMediaType", 4, 0,
+	NULL, &_ipNetToMediaNetAddress_obj
+},
+_ipNetToMediaEntry_obj = {
+	"ipNetToMediaEntry", 1, 0,
+	&_ipNetToMediaType_obj, NULL
+},
+_ipRouteDest_obj = {
+	"ipRouteDest", 1, 0,
+	NULL, NULL
+},
+_ipRouteIfIndex_obj = {
+	"ipRouteIfIndex", 2, 0,
+	NULL, &_ipRouteDest_obj
+},
+_ipRouteMetric1_obj = {
+	"ipRouteMetric1", 3, 0,
+	NULL, &_ipRouteIfIndex_obj
+},
+_ipRouteMetric2_obj = {
+	"ipRouteMetric2", 4, 0,
+	NULL, &_ipRouteMetric1_obj
+},
+_ipRouteMetric3_obj = {
+	"ipRouteMetric3", 5, 0,
+	NULL, &_ipRouteMetric2_obj
+},
+_ipRouteMetric4_obj = {
+	"ipRouteMetric4", 6, 0,
+	NULL, &_ipRouteMetric3_obj
+},
+_ipRouteNextHop_obj = {
+	"ipRouteNextHop", 7, 0,
+	NULL, &_ipRouteMetric4_obj
+},
+_ipRouteType_obj = {
+	"ipRouteType", 8, 0,
+	NULL, &_ipRouteNextHop_obj
+},
+_ipRouteProto_obj = {
+	"ipRouteProto", 9, 0,
+	NULL, &_ipRouteType_obj
+},
+_ipRouteAge_obj = {
+	"ipRouteAge", 10, 0,
+	NULL, &_ipRouteProto_obj
+},
+_ipRouteMask_obj = {
+	"ipRouteMask", 11, 0,
+	NULL, &_ipRouteAge_obj
+},
+_ipRouteEntry_obj = {
+	"ipRouteEntry", 1, 0,
+	&_ipRouteMask_obj, NULL
+},
+_ipAdEntAddr_obj = {
+	"ipAdEntAddr", 1, 0,
+	NULL, NULL
+},
+_ipAdEntIfIndex_obj = {
+	"ipAdEntIfIndex", 2, 0,
+	NULL, &_ipAdEntAddr_obj
+},
+_ipAdEntNetMask_obj = {
+	"ipAdEntNetMask", 3, 0,
+	NULL, &_ipAdEntIfIndex_obj
+},
+_ipAdEntBcastAddr_obj = {
+	"ipAdEntBcastAddr", 4, 0,
+	NULL, &_ipAdEntNetMask_obj
+},
+_ipAdEntReasmMaxSize_obj = {
+	"ipAdEntReasmMaxSize", 5, 0,
+	NULL, &_ipAdEntBcastAddr_obj
+},
+_ipAddrEntry_obj = {
+	"ipAddrEntry", 1, 0,
+	&_ipAdEntReasmMaxSize_obj, NULL
+},
+_ipForwarding_obj = {
+	"ipForwarding", 1, 0,
+	NULL, NULL
+},
+_ipDefaultTTL_obj = {
+	"ipDefaultTTL", 2, 0,
+	NULL, &_ipForwarding_obj
+},
+_ipInReceives_obj = {
+	"ipInReceives", 3, 0,
+	NULL, &_ipDefaultTTL_obj
+},
+_ipInHdrErrors_obj = {
+	"ipInHdrErrors", 4, 0,
+	NULL, &_ipInReceives_obj
+},
+_ipInAddrErrors_obj = {
+	"ipInAddrErrors", 5, 0,
+	NULL, &_ipInHdrErrors_obj
+},
+_ipForwDatagrams_obj = {
+	"ipForwDatagrams", 6, 0,
+	NULL, &_ipInAddrErrors_obj
+},
+_ipInUnknownProtos_obj = {
+	"ipInUnknownProtos", 7, 0,
+	NULL, &_ipForwDatagrams_obj
+},
+_ipInDiscards_obj = {
+	"ipInDiscards", 8, 0,
+	NULL, &_ipInUnknownProtos_obj
+},
+_ipInDelivers_obj = {
+	"ipInDelivers", 9, 0,
+	NULL, &_ipInDiscards_obj
+},
+_ipOutRequests_obj = {
+	"ipOutRequests", 10, 0,
+	NULL, &_ipInDelivers_obj
+},
+_ipOutDiscards_obj = {
+	"ipOutDiscards", 11, 0,
+	NULL, &_ipOutRequests_obj
+},
+_ipOutNoRoutes_obj = {
+	"ipOutNoRoutes", 12, 0,
+	NULL, &_ipOutDiscards_obj
+},
+_ipReasmTimeout_obj = {
+	"ipReasmTimeout", 13, 0,
+	NULL, &_ipOutNoRoutes_obj
+},
+_ipReasmReqds_obj = {
+	"ipReasmReqds", 14, 0,
+	NULL, &_ipReasmTimeout_obj
+},
+_ipReasmOKs_obj = {
+	"ipReasmOKs", 15, 0,
+	NULL, &_ipReasmReqds_obj
+},
+_ipReasmFails_obj = {
+	"ipReasmFails", 16, 0,
+	NULL, &_ipReasmOKs_obj
+},
+_ipFragOKs_obj = {
+	"ipFragOKs", 17, 0,
+	NULL, &_ipReasmFails_obj
+},
+_ipFragFails_obj = {
+	"ipFragFails", 18, 0,
+	NULL, &_ipFragOKs_obj
+},
+_ipFragCreates_obj = {
+	"ipFragCreates", 19, 0,
+	NULL, &_ipFragFails_obj
+},
+_ipAddrTable_obj = {
+	"ipAddrTable", 20, 0,
+	&_ipAddrEntry_obj, &_ipFragCreates_obj
+},
+_ipRoutingTable_obj = {
+	"ipRoutingTable", 21, 0,
+	&_ipRouteEntry_obj, &_ipAddrTable_obj
+},
+_ipNetToMediaTable_obj = {
+	"ipNetToMediaTable", 22, 0,
+	&_ipNetToMediaEntry_obj, &_ipRoutingTable_obj
+},
+_atIfIndex_obj = {
+	"atIfIndex", 1, 0,
+	NULL, NULL
+},
+_atPhysAddress_obj = {
+	"atPhysAddress", 2, 0,
+	NULL, &_atIfIndex_obj
+},
+_atNetAddress_obj = {
+	"atNetAddress", 3, 0,
+	NULL, &_atPhysAddress_obj
+},
+_atEntry_obj = {
+	"atEntry", 1, 0,
+	&_atNetAddress_obj, NULL
+},
+_atTable_obj = {
+	"atTable", 1, 0,
+	&_atEntry_obj, NULL
+},
+_ifIndex_obj = {
+	"ifIndex", 1, 0,
+	NULL, NULL
+},
+_ifDescr_obj = {
+	"ifDescr", 2, 0,
+	NULL, &_ifIndex_obj
+},
+_ifType_obj = {
+	"ifType", 3, 0,
+	NULL, &_ifDescr_obj
+},
+_ifMtu_obj = {
+	"ifMtu", 4, 0,
+	NULL, &_ifType_obj
+},
+_ifSpeed_obj = {
+	"ifSpeed", 5, 0,
+	NULL, &_ifMtu_obj
+},
+_ifPhysAddress_obj = {
+	"ifPhysAddress", 6, 0,
+	NULL, &_ifSpeed_obj
+},
+_ifAdminStatus_obj = {
+	"ifAdminStatus", 7, 0,
+	NULL, &_ifPhysAddress_obj
+},
+_ifOperStatus_obj = {
+	"ifOperStatus", 8, 0,
+	NULL, &_ifAdminStatus_obj
+},
+_ifLastChange_obj = {
+	"ifLastChange", 9, 0,
+	NULL, &_ifOperStatus_obj
+},
+_ifInOctets_obj = {
+	"ifInOctets", 10, 0,
+	NULL, &_ifLastChange_obj
+},
+_ifInUcastPkts_obj = {
+	"ifInUcastPkts", 11, 0,
+	NULL, &_ifInOctets_obj
+},
+_ifInNUcastPkts_obj = {
+	"ifInNUcastPkts", 12, 0,
+	NULL, &_ifInUcastPkts_obj
+},
+_ifInDiscards_obj = {
+	"ifInDiscards", 13, 0,
+	NULL, &_ifInNUcastPkts_obj
+},
+_ifInErrors_obj = {
+	"ifInErrors", 14, 0,
+	NULL, &_ifInDiscards_obj
+},
+_ifInUnknownProtos_obj = {
+	"ifInUnknownProtos", 15, 0,
+	NULL, &_ifInErrors_obj
+},
+_ifOutOctets_obj = {
+	"ifOutOctets", 16, 0,
+	NULL, &_ifInUnknownProtos_obj
+},
+_ifOutUcastPkts_obj = {
+	"ifOutUcastPkts", 17, 0,
+	NULL, &_ifOutOctets_obj
+},
+_ifOutNUcastPkts_obj = {
+	"ifOutNUcastPkts", 18, 0,
+	NULL, &_ifOutUcastPkts_obj
+},
+_ifOutDiscards_obj = {
+	"ifOutDiscards", 19, 0,
+	NULL, &_ifOutNUcastPkts_obj
+},
+_ifOutErrors_obj = {
+	"ifOutErrors", 20, 0,
+	NULL, &_ifOutDiscards_obj
+},
+_ifOutQLen_obj = {
+	"ifOutQLen", 21, 0,
+	NULL, &_ifOutErrors_obj
+},
+_ifSpecific_obj = {
+	"ifSpecific", 22, 0,
+	NULL, &_ifOutQLen_obj
+},
+_ifEntry_obj = {
+	"ifEntry", 1, 0,
+	&_ifSpecific_obj, NULL
+},
+_ifNumber_obj = {
+	"ifNumber", 1, 0,
+	NULL, NULL
+},
+_ifTable_obj = {
+	"ifTable", 2, 0,
+	&_ifEntry_obj, &_ifNumber_obj
+},
+_sysDescr_obj = {
+	"sysDescr", 1, 0,
+	NULL, NULL
+},
+_sysObjectID_obj = {
+	"sysObjectID", 2, 0,
+	NULL, &_sysDescr_obj
+},
+_sysUpTime_obj = {
+	"sysUpTime", 3, 0,
+	NULL, &_sysObjectID_obj
+},
+_sysContact_obj = {
+	"sysContact", 4, 0,
+	NULL, &_sysUpTime_obj
+},
+_sysName_obj = {
+	"sysName", 5, 0,
+	NULL, &_sysContact_obj
+},
+_sysLocation_obj = {
+	"sysLocation", 6, 0,
+	NULL, &_sysName_obj
+},
+_sysServices_obj = {
+	"sysServices", 7, 0,
+	NULL, &_sysLocation_obj
+},
+_system_obj = {
+	"system", 1, 0,
+	&_sysServices_obj, NULL
+},
+_interfaces_obj = {
+	"interfaces", 2, 0,
+	&_ifTable_obj, &_system_obj
+},
+_at_obj = {
+	"at", 3, 0,
+	&_atTable_obj, &_interfaces_obj
+},
+_ip_obj = {
+	"ip", 4, 0,
+	&_ipNetToMediaTable_obj, &_at_obj
+},
+_icmp_obj = {
+	"icmp", 5, 0,
+	&_icmpOutAddrMaskReps_obj, &_ip_obj
+},
+_tcp_obj = {
+	"tcp", 6, 0,
+	&_tcpOutRsts_obj, &_icmp_obj
+},
+_udp_obj = {
+	"udp", 7, 0,
+	&_udpTable_obj, &_tcp_obj
+},
+_egp_obj = {
+	"egp", 8, 0,
+	&_egpAs_obj, &_udp_obj
+},
+_transmission_obj = {
+	"transmission", 10, 0,
+	NULL, &_egp_obj
+},
+_snmp_obj = {
+	"snmp", 11, 0,
+	&_snmpEnableAuthTraps_obj, &_transmission_obj
+},
+_mib_obj = {
+	"mib", 1, 0,
+	&_snmp_obj, NULL
+},
+_directory_obj = {
+	"directory", 1, 0,
+	NULL, NULL
+},
+_mgmt_obj = {
+	"mgmt", 2, 0,
+	&_mib_obj, &_directory_obj
+},
+_experimental_obj = {
+	"experimental", 3, 0,
+	NULL, &_mgmt_obj
+},
+_private_obj = {
+	"private", 4, 0,
+	&_enterprises_obj, &_experimental_obj
+},
+_internet_obj = {
+	"internet", 1, 0,
+	&_private_obj, NULL
+},
+_dod_obj = {
+	"dod", 6, 0,
+	&_internet_obj, NULL
+},
+_org_obj = {
+	"org", 3, 0,
+	&_dod_obj, NULL
+},
+_iso_obj = {
+	"iso", 1, 0,
+	&_org_obj, NULL
+},
+*mibroot = &_iso_obj;
diff --git a/tcpdump.tproj/netbios.h b/tcpdump.tproj/netbios.h
new file mode 100644
index 0000000..629e5a5
--- /dev/null
+++ b/tcpdump.tproj/netbios.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * NETBIOS protocol formats
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/netbios.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $
+ */
+
+struct p8022Hdr {
+    u_char	dsap;
+    u_char	ssap;
+    u_char	flags;
+};
+
+#define	p8022Size	3		/* min 802.2 header size */
+
+#define UI		0x03		/* 802.2 flags */
+
diff --git a/tcpdump.tproj/nfs.h b/tcpdump.tproj/nfs.h
new file mode 100644
index 0000000..a45e1ce
--- /dev/null
+++ b/tcpdump.tproj/nfs.h
@@ -0,0 +1,470 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: nfs.h,v 1.2 1996/07/13 11:01:12 mickey Exp $	*/
+/*	$NetBSD: nfs.h,v 1.1 1996/05/23 22:49:53 fvdl Exp $	*/
+
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)nfsproto.h	8.2 (Berkeley) 3/30/95
+ */
+
+/*
+ * nfs definitions as per the Version 2 and 3 specs
+ */
+
+/*
+ * Constants as defined in the Sun NFS Version 2 and 3 specs.
+ * "NFS: Network File System Protocol Specification" RFC1094
+ * and in the "NFS: Network File System Version 3 Protocol
+ * Specification"
+ */
+
+#define NFS_PORT	2049
+#define	NFS_PROG	100003
+#define NFS_VER2	2
+#define	NFS_VER3	3
+#define NFS_V2MAXDATA	8192
+#define	NFS_MAXDGRAMDATA 16384
+#define	NFS_MAXDATA	32768
+#define	NFS_MAXPATHLEN	1024
+#define	NFS_MAXNAMLEN	255
+#define	NFS_MAXPKTHDR	404
+#define NFS_MAXPACKET	(NFS_MAXPKTHDR + NFS_MAXDATA)
+#define	NFS_MINPACKET	20
+#define	NFS_FABLKSIZE	512	/* Size in bytes of a block wrt fa_blocks */
+
+/* Stat numbers for rpc returns (version 2 and 3) */
+#define	NFS_OK			0
+#define	NFSERR_PERM		1
+#define	NFSERR_NOENT		2
+#define	NFSERR_IO		5
+#define	NFSERR_NXIO		6
+#define	NFSERR_ACCES		13
+#define	NFSERR_EXIST		17
+#define	NFSERR_XDEV		18	/* Version 3 only */
+#define	NFSERR_NODEV		19
+#define	NFSERR_NOTDIR		20
+#define	NFSERR_ISDIR		21
+#define	NFSERR_INVAL		22	/* Version 3 only */
+#define	NFSERR_FBIG		27
+#define	NFSERR_NOSPC		28
+#define	NFSERR_ROFS		30
+#define	NFSERR_MLINK		31	/* Version 3 only */
+#define	NFSERR_NAMETOL		63
+#define	NFSERR_NOTEMPTY		66
+#define	NFSERR_DQUOT		69
+#define	NFSERR_STALE		70
+#define	NFSERR_REMOTE		71	/* Version 3 only */
+#define	NFSERR_WFLUSH		99	/* Version 2 only */
+#define	NFSERR_BADHANDLE	10001	/* The rest Version 3 only */
+#define	NFSERR_NOT_SYNC		10002
+#define	NFSERR_BAD_COOKIE	10003
+#define	NFSERR_NOTSUPP		10004
+#define	NFSERR_TOOSMALL		10005
+#define	NFSERR_SERVERFAULT	10006
+#define	NFSERR_BADTYPE		10007
+#define	NFSERR_JUKEBOX		10008
+#define NFSERR_TRYLATER		NFSERR_JUKEBOX
+#define	NFSERR_STALEWRITEVERF	30001	/* Fake return for nfs_commit() */
+
+#define NFSERR_RETVOID		0x20000000 /* Return void, not error */
+#define NFSERR_AUTHERR		0x40000000 /* Mark an authentication error */
+#define NFSERR_RETERR		0x80000000 /* Mark an error return for V3 */
+
+/* Sizes in bytes of various nfs rpc components */
+#define	NFSX_UNSIGNED	4
+
+/* specific to NFS Version 2 */
+#define	NFSX_V2FH	32
+#define	NFSX_V2FATTR	68
+#define	NFSX_V2SATTR	32
+#define	NFSX_V2COOKIE	4
+#define NFSX_V2STATFS	20
+
+/* specific to NFS Version 3 */
+#if 0
+#define NFSX_V3FH		(sizeof (fhandle_t)) /* size this server uses */
+#endif
+#define	NFSX_V3FHMAX		64	/* max. allowed by protocol */
+#define NFSX_V3FATTR		84
+#define NFSX_V3SATTR		60	/* max. all fields filled in */
+#define NFSX_V3SRVSATTR		(sizeof (struct nfsv3_sattr))
+#define NFSX_V3POSTOPATTR	(NFSX_V3FATTR + NFSX_UNSIGNED)
+#define NFSX_V3WCCDATA		(NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED)
+#define NFSX_V3COOKIEVERF 	8
+#define NFSX_V3WRITEVERF 	8
+#define NFSX_V3CREATEVERF	8
+#define NFSX_V3STATFS		52
+#define NFSX_V3FSINFO		48
+#define NFSX_V3PATHCONF		24
+
+/* variants for both versions */
+#define NFSX_FH(v3)		((v3) ? (NFSX_V3FHMAX + NFSX_UNSIGNED) : \
+					NFSX_V2FH)
+#define NFSX_SRVFH(v3)		((v3) ? NFSX_V3FH : NFSX_V2FH)
+#define	NFSX_FATTR(v3)		((v3) ? NFSX_V3FATTR : NFSX_V2FATTR)
+#define NFSX_PREOPATTR(v3)	((v3) ? (7 * NFSX_UNSIGNED) : 0)
+#define NFSX_POSTOPATTR(v3)	((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : 0)
+#define NFSX_POSTOPORFATTR(v3)	((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : \
+					NFSX_V2FATTR)
+#define NFSX_WCCDATA(v3)	((v3) ? NFSX_V3WCCDATA : 0)
+#define NFSX_WCCORFATTR(v3)	((v3) ? NFSX_V3WCCDATA : NFSX_V2FATTR)
+#define	NFSX_SATTR(v3)		((v3) ? NFSX_V3SATTR : NFSX_V2SATTR)
+#define	NFSX_COOKIEVERF(v3)	((v3) ? NFSX_V3COOKIEVERF : 0)
+#define	NFSX_WRITEVERF(v3)	((v3) ? NFSX_V3WRITEVERF : 0)
+#define NFSX_READDIR(v3)	((v3) ? (5 * NFSX_UNSIGNED) : \
+					(2 * NFSX_UNSIGNED))
+#define	NFSX_STATFS(v3)		((v3) ? NFSX_V3STATFS : NFSX_V2STATFS)
+
+/* nfs rpc procedure numbers (before version mapping) */
+#define	NFSPROC_NULL		0
+#define	NFSPROC_GETATTR		1
+#define	NFSPROC_SETATTR		2
+#define	NFSPROC_LOOKUP		3
+#define	NFSPROC_ACCESS		4
+#define	NFSPROC_READLINK	5
+#define	NFSPROC_READ		6
+#define	NFSPROC_WRITE		7
+#define	NFSPROC_CREATE		8
+#define	NFSPROC_MKDIR		9
+#define	NFSPROC_SYMLINK		10
+#define	NFSPROC_MKNOD		11
+#define	NFSPROC_REMOVE		12
+#define	NFSPROC_RMDIR		13
+#define	NFSPROC_RENAME		14
+#define	NFSPROC_LINK		15
+#define	NFSPROC_READDIR		16
+#define	NFSPROC_READDIRPLUS	17
+#define	NFSPROC_FSSTAT		18
+#define	NFSPROC_FSINFO		19
+#define	NFSPROC_PATHCONF	20
+#define	NFSPROC_COMMIT		21
+
+/* And leasing (nqnfs) procedure numbers (must be last) */
+#define	NQNFSPROC_GETLEASE	22
+#define	NQNFSPROC_VACATED	23
+#define	NQNFSPROC_EVICTED	24
+
+#define NFSPROC_NOOP		25
+#define	NFS_NPROCS		26
+
+/* Actual Version 2 procedure numbers */
+#define	NFSV2PROC_NULL		0
+#define	NFSV2PROC_GETATTR	1
+#define	NFSV2PROC_SETATTR	2
+#define	NFSV2PROC_NOOP		3
+#define	NFSV2PROC_ROOT		NFSV2PROC_NOOP	/* Obsolete */
+#define	NFSV2PROC_LOOKUP	4
+#define	NFSV2PROC_READLINK	5
+#define	NFSV2PROC_READ		6
+#define	NFSV2PROC_WRITECACHE	NFSV2PROC_NOOP	/* Obsolete */
+#define	NFSV2PROC_WRITE		8
+#define	NFSV2PROC_CREATE	9
+#define	NFSV2PROC_REMOVE	10
+#define	NFSV2PROC_RENAME	11
+#define	NFSV2PROC_LINK		12
+#define	NFSV2PROC_SYMLINK	13
+#define	NFSV2PROC_MKDIR		14
+#define	NFSV2PROC_RMDIR		15
+#define	NFSV2PROC_READDIR	16
+#define	NFSV2PROC_STATFS	17
+
+/*
+ * Constants used by the Version 3 protocol for various RPCs
+ */
+#define NFSV3SATTRTIME_DONTCHANGE	0
+#define NFSV3SATTRTIME_TOSERVER		1
+#define NFSV3SATTRTIME_TOCLIENT		2
+
+#define NFSV3ATTRTIME_NMODES		3
+
+#define NFSV3ACCESS_READ		0x01
+#define NFSV3ACCESS_LOOKUP		0x02
+#define NFSV3ACCESS_MODIFY		0x04
+#define NFSV3ACCESS_EXTEND		0x08
+#define NFSV3ACCESS_DELETE		0x10
+#define NFSV3ACCESS_EXECUTE		0x20
+
+#define NFSV3WRITE_UNSTABLE		0
+#define NFSV3WRITE_DATASYNC		1
+#define NFSV3WRITE_FILESYNC		2
+
+#define NFSV3WRITE_NMODES		3
+
+#define NFSV3CREATE_UNCHECKED		0
+#define NFSV3CREATE_GUARDED		1
+#define NFSV3CREATE_EXCLUSIVE		2
+
+#define NFSV3CREATE_NMODES		3
+
+#define NFSV3FSINFO_LINK		0x01
+#define NFSV3FSINFO_SYMLINK		0x02
+#define NFSV3FSINFO_HOMOGENEOUS		0x08
+#define NFSV3FSINFO_CANSETTIME		0x10
+
+/* Conversion macros */
+#define	vtonfsv2_mode(t,m) \
+		txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \
+				MAKEIMODE((t), (m)))
+#define vtonfsv3_mode(m)	txdr_unsigned((m) & 07777)
+#define	nfstov_mode(a)		(fxdr_unsigned(u_int16_t, (a))&07777)
+#define	vtonfsv2_type(a)	txdr_unsigned(nfsv2_type[((int32_t)(a))])
+#define	vtonfsv3_type(a)	txdr_unsigned(nfsv3_type[((int32_t)(a))])
+#define	nfsv2tov_type(a)	nv2tov_type[fxdr_unsigned(u_int32,(a))&0x7]
+#define	nfsv3tov_type(a)	nv3tov_type[fxdr_unsigned(u_int32,(a))&0x7]
+
+/* File types */
+typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5,
+	NFSOCK=6, NFFIFO=7 } nfstype;
+
+/* Structs for common parts of the rpc's */
+/*
+ * File Handle (32 bytes for version 2), variable up to 64 for version 3.
+ * File Handles of up to NFS_SMALLFH in size are stored directly in the
+ * nfs node, whereas larger ones are malloc'd. (This never happens when
+ * NFS_SMALLFH is set to 64.)
+ * NFS_SMALLFH should be in the range of 32 to 64 and be divisible by 4.
+ */
+#ifndef NFS_SMALLFH
+#define NFS_SMALLFH	64
+#endif
+union nfsfh {
+/*	fhandle_t fh_generic; */
+	u_char    fh_bytes[NFS_SMALLFH];
+};
+typedef union nfsfh nfsfh_t;
+
+struct nfsv2_time {
+	u_int32 nfsv2_sec;
+	u_int32 nfsv2_usec;
+};
+typedef struct nfsv2_time	nfstime2;
+
+struct nfsv3_time {
+	u_int32 nfsv3_sec;
+	u_int32 nfsv3_nsec;
+};
+typedef struct nfsv3_time	nfstime3;
+
+/*
+ * Quads are defined as arrays of 2 longs to ensure dense packing for the
+ * protocol and to facilitate xdr conversion.
+ */
+struct nfs_uquad {
+	u_int32 nfsuquad[2];
+};
+typedef	struct nfs_uquad	nfsuint64;
+
+/*
+ * Used to convert between two u_longs and a u_quad_t.
+ */
+union nfs_quadconvert {
+	u_int32 lval[2];
+	u_quad_t  qval;
+};
+typedef union nfs_quadconvert	nfsquad_t;
+
+/*
+ * NFS Version 3 special file number.
+ */
+struct nfsv3_spec {
+	u_int32 specdata1;
+	u_int32 specdata2;
+};
+typedef	struct nfsv3_spec	nfsv3spec;
+
+/*
+ * File attributes and setable attributes. These structures cover both
+ * NFS version 2 and the version 3 protocol. Note that the union is only
+ * used so that one pointer can refer to both variants. These structures
+ * go out on the wire and must be densely packed, so no quad data types
+ * are used. (all fields are longs or u_longs or structures of same)
+ * NB: You can't do sizeof(struct nfs_fattr), you must use the
+ *     NFSX_FATTR(v3) macro.
+ */
+struct nfs_fattr {
+	u_int32 fa_type;
+	u_int32 fa_mode;
+	u_int32 fa_nlink;
+	u_int32 fa_uid;
+	u_int32 fa_gid;
+	union {
+		struct {
+			u_int32 nfsv2fa_size;
+			u_int32 nfsv2fa_blocksize;
+			u_int32 nfsv2fa_rdev;
+			u_int32 nfsv2fa_blocks;
+			u_int32 nfsv2fa_fsid;
+			u_int32 nfsv2fa_fileid;
+			nfstime2  nfsv2fa_atime;
+			nfstime2  nfsv2fa_mtime;
+			nfstime2  nfsv2fa_ctime;
+		} fa_nfsv2;
+		struct {
+			nfsuint64 nfsv3fa_size;
+			nfsuint64 nfsv3fa_used;
+			nfsv3spec nfsv3fa_rdev;
+			nfsuint64 nfsv3fa_fsid;
+			nfsuint64 nfsv3fa_fileid;
+			nfstime3  nfsv3fa_atime;
+			nfstime3  nfsv3fa_mtime;
+			nfstime3  nfsv3fa_ctime;
+		} fa_nfsv3;
+	} fa_un;
+};
+
+/* and some ugly defines for accessing union components */
+#define	fa2_size		fa_un.fa_nfsv2.nfsv2fa_size
+#define	fa2_blocksize		fa_un.fa_nfsv2.nfsv2fa_blocksize
+#define	fa2_rdev		fa_un.fa_nfsv2.nfsv2fa_rdev
+#define	fa2_blocks		fa_un.fa_nfsv2.nfsv2fa_blocks
+#define	fa2_fsid		fa_un.fa_nfsv2.nfsv2fa_fsid
+#define	fa2_fileid		fa_un.fa_nfsv2.nfsv2fa_fileid
+#define	fa2_atime		fa_un.fa_nfsv2.nfsv2fa_atime
+#define	fa2_mtime		fa_un.fa_nfsv2.nfsv2fa_mtime
+#define	fa2_ctime		fa_un.fa_nfsv2.nfsv2fa_ctime
+#define	fa3_size		fa_un.fa_nfsv3.nfsv3fa_size
+#define	fa3_used		fa_un.fa_nfsv3.nfsv3fa_used
+#define	fa3_rdev		fa_un.fa_nfsv3.nfsv3fa_rdev
+#define	fa3_fsid		fa_un.fa_nfsv3.nfsv3fa_fsid
+#define	fa3_fileid		fa_un.fa_nfsv3.nfsv3fa_fileid
+#define	fa3_atime		fa_un.fa_nfsv3.nfsv3fa_atime
+#define	fa3_mtime		fa_un.fa_nfsv3.nfsv3fa_mtime
+#define	fa3_ctime		fa_un.fa_nfsv3.nfsv3fa_ctime
+
+struct nfsv2_sattr {
+	u_int32 sa_mode;
+	u_int32 sa_uid;
+	u_int32 sa_gid;
+	u_int32 sa_size;
+	nfstime2  sa_atime;
+	nfstime2  sa_mtime;
+};
+
+/*
+ * NFS Version 3 sattr structure for the new node creation case.
+ */
+struct nfsv3_sattr {
+	u_int32   sa_modeset;
+	u_int32   sa_mode;
+	u_int32   sa_uidset;
+	u_int32   sa_uid;
+	u_int32   sa_gidset;
+	u_int32   sa_gid;
+	u_int32   sa_sizeset;
+	u_int32   sa_size;
+	u_int32   sa_atimetype;
+	nfstime3  sa_atime;
+	u_int32   sa_mtimetype;
+	nfstime3  sa_mtime;
+};
+
+struct nfs_statfs {
+	union {
+		struct {
+			u_int32 nfsv2sf_tsize;
+			u_int32 nfsv2sf_bsize;
+			u_int32 nfsv2sf_blocks;
+			u_int32 nfsv2sf_bfree;
+			u_int32 nfsv2sf_bavail;
+		} sf_nfsv2;
+		struct {
+			nfsuint64 nfsv3sf_tbytes;
+			nfsuint64 nfsv3sf_fbytes;
+			nfsuint64 nfsv3sf_abytes;
+			nfsuint64 nfsv3sf_tfiles;
+			nfsuint64 nfsv3sf_ffiles;
+			nfsuint64 nfsv3sf_afiles;
+			u_int32 nfsv3sf_invarsec;
+		} sf_nfsv3;
+	} sf_un;
+};
+
+#define sf_tsize	sf_un.sf_nfsv2.nfsv2sf_tsize
+#define sf_bsize	sf_un.sf_nfsv2.nfsv2sf_bsize
+#define sf_blocks	sf_un.sf_nfsv2.nfsv2sf_blocks
+#define sf_bfree	sf_un.sf_nfsv2.nfsv2sf_bfree
+#define sf_bavail	sf_un.sf_nfsv2.nfsv2sf_bavail
+#define sf_tbytes	sf_un.sf_nfsv3.nfsv3sf_tbytes
+#define sf_fbytes	sf_un.sf_nfsv3.nfsv3sf_fbytes
+#define sf_abytes	sf_un.sf_nfsv3.nfsv3sf_abytes
+#define sf_tfiles	sf_un.sf_nfsv3.nfsv3sf_tfiles
+#define sf_ffiles	sf_un.sf_nfsv3.nfsv3sf_ffiles
+#define sf_afiles	sf_un.sf_nfsv3.nfsv3sf_afiles
+#define sf_invarsec	sf_un.sf_nfsv3.nfsv3sf_invarsec
+
+struct nfsv3_fsinfo {
+	u_int32 fs_rtmax;
+	u_int32 fs_rtpref;
+	u_int32 fs_rtmult;
+	u_int32 fs_wtmax;
+	u_int32 fs_wtpref;
+	u_int32 fs_wtmult;
+	u_int32 fs_dtpref;
+	nfsuint64 fs_maxfilesize;
+	nfstime3  fs_timedelta;
+	u_int32 fs_properties;
+};
+
+struct nfsv3_pathconf {
+	u_int32 pc_linkmax;
+	u_int32 pc_namemax;
+	u_int32 pc_notrunc;
+	u_int32 pc_chownrestricted;
+	u_int32 pc_caseinsensitive;
+	u_int32 pc_casepreserving;
+};
diff --git a/tcpdump.tproj/nfsfh.h b/tcpdump.tproj/nfsfh.h
new file mode 100644
index 0000000..f354eec
--- /dev/null
+++ b/tcpdump.tproj/nfsfh.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/nfsfh.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $
+ *
+ * nfsfh.h - NFS file handle definitions (for portable use)
+ *
+ * Jeffrey C. Mogul
+ * Digital Equipment Corporation
+ * Western Research Laboratory
+ */
+
+/*
+ * Internal representation of dev_t, because different NFS servers
+ * that we might be spying upon use different external representations.
+ */
+typedef struct {
+	u_int32_t Minor;	/* upper case to avoid clashing with macro names */
+	u_int32_t Major;
+} my_devt;
+
+#define	dev_eq(a,b)	((a.Minor == b.Minor) && (a.Major == b.Major))
+
+/*
+ * Many file servers now use a large file system ID.  This is
+ * our internal representation of that.
+ */
+typedef	struct {
+	my_devt	Fsid_dev;		/* XXX avoid name conflict with AIX */
+	u_int32_t fsid_code;
+} my_fsid;
+
+#define	fsid_eq(a,b)	((a.fsid_code == b.fsid_code) &&\
+			 dev_eq(a.fsid_dev, b.fsid_dev))
+
+extern void Parse_fh(caddr_t *, my_fsid *, ino_t *, char **, char **, int);
diff --git a/tcpdump.tproj/nfsv2.h b/tcpdump.tproj/nfsv2.h
new file mode 100644
index 0000000..d991ddc
--- /dev/null
+++ b/tcpdump.tproj/nfsv2.h
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)nfsv2.h	7.11 (Berkeley) 9/30/92
+ */
+
+/*
+ * nfs definitions as per the version 2 specs
+ */
+
+/*
+ * Constants as defined in the Sun NFS Version 2 spec.
+ * "NFS: Network File System Protocol Specification" RFC1094
+ */
+
+#define NFS_PORT	2049
+#define	NFS_PROG	100003
+#define NFS_VER2	2
+#define	NFS_MAXDGRAMDATA 8192
+#define	NFS_MAXDATA	32768
+#define	NFS_MAXPATHLEN	1024
+#define	NFS_MAXNAMLEN	255
+#define	NFS_FHSIZE	32
+#define	NFS_MAXPKTHDR	404
+#define NFS_MAXPACKET	(NFS_MAXPKTHDR+NFS_MAXDATA)
+#define	NFS_MINPACKET	20
+#define	NFS_FABLKSIZE	512	/* Size in bytes of a block wrt fa_blocks */
+
+/* Stat numbers for rpc returns */
+#define	NFS_OK		0
+#define	NFSERR_PERM	1
+#define	NFSERR_NOENT	2
+#define	NFSERR_IO	5
+#define	NFSERR_NXIO	6
+#define	NFSERR_ACCES	13
+#define	NFSERR_EXIST	17
+#define	NFSERR_NODEV	19
+#define	NFSERR_NOTDIR	20
+#define	NFSERR_ISDIR	21
+#define	NFSERR_FBIG	27
+#define	NFSERR_NOSPC	28
+#define	NFSERR_ROFS	30
+#define	NFSERR_NAMETOL	63
+#define	NFSERR_NOTEMPTY	66
+#define	NFSERR_DQUOT	69
+#define	NFSERR_STALE	70
+#define	NFSERR_WFLUSH	99
+
+/* Sizes in bytes of various nfs rpc components */
+#define	NFSX_FH		32
+#define	NFSX_UNSIGNED	4
+#define	NFSX_NFSFATTR	68
+#define	NFSX_NQFATTR	92
+#define	NFSX_NFSSATTR	32
+#define	NFSX_NQSATTR	44
+#define	NFSX_COOKIE	4
+#define NFSX_NFSSTATFS	20
+#define	NFSX_NQSTATFS	28
+#define	NFSX_FATTR(isnq)	((isnq) ? NFSX_NQFATTR : NFSX_NFSFATTR)
+#define	NFSX_SATTR(isnq)	((isnq) ? NFSX_NQSATTR : NFSX_NFSSATTR)
+#define	NFSX_STATFS(isnq)	((isnq) ? NFSX_NQSTATFS : NFSX_NFSSTATFS)
+
+/* nfs rpc procedure numbers */
+#define	NFSPROC_NULL		0
+#define	NFSPROC_GETATTR		1
+#define	NFSPROC_SETATTR		2
+#define	NFSPROC_NOOP		3
+#define	NFSPROC_ROOT		NFSPROC_NOOP	/* Obsolete */
+#define	NFSPROC_LOOKUP		4
+#define	NFSPROC_READLINK	5
+#define	NFSPROC_READ		6
+#define	NFSPROC_WRITECACHE	NFSPROC_NOOP	/* Obsolete */
+#define	NFSPROC_WRITE		8
+#define	NFSPROC_CREATE		9
+#define	NFSPROC_REMOVE		10
+#define	NFSPROC_RENAME		11
+#define	NFSPROC_LINK		12
+#define	NFSPROC_SYMLINK		13
+#define	NFSPROC_MKDIR		14
+#define	NFSPROC_RMDIR		15
+#define	NFSPROC_READDIR		16
+#define	NFSPROC_STATFS		17
+
+/* NQ nfs numbers */
+#define	NQNFSPROC_READDIRLOOK	18
+#define	NQNFSPROC_GETLEASE	19
+#define	NQNFSPROC_VACATED	20
+#define	NQNFSPROC_EVICTED	21
+#define	NQNFSPROC_ACCESS	22
+
+#define	NFS_NPROCS		23
+/* Conversion macros */
+extern int		vttoif_tab[];
+#define	vtonfs_mode(t,m) \
+		txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \
+				MAKEIMODE((t), (m)))
+#define	nfstov_mode(a)	(fxdr_unsigned(u_short, (a))&07777)
+#define	vtonfs_type(a)	txdr_unsigned(nfs_type[((int32_t)(a))])
+#define	nfstov_type(a)	ntov_type[fxdr_unsigned(u_int32_t,(a))&0x7]
+
+/* File types */
+typedef enum {
+    NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5
+} tcpdump_nfstype;
+
+/* Structs for common parts of the rpc's */
+struct nfsv2_time {
+	u_int32_t nfs_sec;
+	u_int32_t nfs_usec;
+};
+
+struct nqnfs_time {
+	u_int32_t nq_sec;
+	u_int32_t nq_nsec;
+};
+
+/*
+ * File attributes and setable attributes. These structures cover both
+ * NFS version 2 and the NQNFS protocol. Note that the union is only
+ * used to that one pointer can refer to both variants. These structures
+ * go out on the wire and must be densely packed, so no quad data types
+ * are used. (all fields are int32_t or u_int32_t's or structures of same)
+ * NB: You can't do sizeof(struct nfsv2_fattr), you must use the
+ *     NFSX_FATTR(isnq) macro.
+ */
+struct nfsv2_fattr {
+	u_int32_t fa_type;
+	u_int32_t fa_mode;
+	u_int32_t fa_nlink;
+	u_int32_t fa_uid;
+	u_int32_t fa_gid;
+	union {
+		struct {
+			u_int32_t nfsfa_size;
+			u_int32_t nfsfa_blocksize;
+			u_int32_t nfsfa_rdev;
+			u_int32_t nfsfa_blocks;
+			u_int32_t nfsfa_fsid;
+			u_int32_t nfsfa_fileid;
+			struct nfsv2_time nfsfa_atime;
+			struct nfsv2_time nfsfa_mtime;
+			struct nfsv2_time nfsfa_ctime;
+		} fa_nfsv2;
+		struct {
+			struct {
+				u_int32_t nqfa_qsize[2];
+			} nqfa_size;
+			u_int32_t nqfa_blocksize;
+			u_int32_t nqfa_rdev;
+			struct {
+				u_int32_t	nqfa_qbytes[2];
+			} nqfa_bytes;
+			u_int32_t nqfa_fsid;
+			u_int32_t nqfa_fileid;
+			struct nqnfs_time nqfa_atime;
+			struct nqnfs_time nqfa_mtime;
+			struct nqnfs_time nqfa_ctime;
+			u_int32_t nqfa_flags;
+			u_int32_t nqfa_gen;
+			struct {
+				u_int32_t nqfa_qfilerev[2];
+			} nqfa_filerev;
+		} fa_nqnfs;
+	} fa_un;
+};
+
+/* and some ugly defines for accessing union components */
+#define	fa_nfssize		fa_un.fa_nfsv2.nfsfa_size
+#define	fa_nfsblocksize		fa_un.fa_nfsv2.nfsfa_blocksize
+#define	fa_nfsrdev		fa_un.fa_nfsv2.nfsfa_rdev
+#define	fa_nfsblocks		fa_un.fa_nfsv2.nfsfa_blocks
+#define	fa_nfsfsid		fa_un.fa_nfsv2.nfsfa_fsid
+#define	fa_nfsfileid		fa_un.fa_nfsv2.nfsfa_fileid
+#define	fa_nfsatime		fa_un.fa_nfsv2.nfsfa_atime
+#define	fa_nfsmtime		fa_un.fa_nfsv2.nfsfa_mtime
+#define	fa_nfsctime		fa_un.fa_nfsv2.nfsfa_ctime
+#define	fa_nqsize		fa_un.fa_nqnfs.nqfa_size
+#define	fa_nqblocksize		fa_un.fa_nqnfs.nqfa_blocksize
+#define	fa_nqrdev		fa_un.fa_nqnfs.nqfa_rdev
+#define	fa_nqbytes		fa_un.fa_nqnfs.nqfa_bytes
+#define	fa_nqfsid		fa_un.fa_nqnfs.nqfa_fsid
+#define	fa_nqfileid		fa_un.fa_nqnfs.nqfa_fileid
+#define	fa_nqatime		fa_un.fa_nqnfs.nqfa_atime
+#define	fa_nqmtime		fa_un.fa_nqnfs.nqfa_mtime
+#define	fa_nqctime		fa_un.fa_nqnfs.nqfa_ctime
+#define	fa_nqflags		fa_un.fa_nqnfs.nqfa_flags
+#define	fa_nqgen		fa_un.fa_nqnfs.nqfa_gen
+#define	fa_nqfilerev		fa_un.fa_nqnfs.nqfa_filerev
+
+struct nfsv2_sattr {
+	u_int32_t sa_mode;
+	u_int32_t sa_uid;
+	u_int32_t sa_gid;
+	union {
+		struct {
+			u_int32_t nfssa_size;
+			struct nfsv2_time nfssa_atime;
+			struct nfsv2_time nfssa_mtime;
+		} sa_nfsv2;
+		struct {
+			struct {
+				u_int32_t nqsa_qsize[2];
+			} nqsa_size;
+			struct nqnfs_time nqsa_atime;
+			struct nqnfs_time nqsa_mtime;
+			u_int32_t nqsa_flags;
+			u_int32_t nqsa_rdev;
+		} sa_nqnfs;
+	} sa_un;
+};
+
+/* and some ugly defines for accessing the unions */
+#define	sa_nfssize		sa_un.sa_nfsv2.nfssa_size
+#define	sa_nfsatime		sa_un.sa_nfsv2.nfssa_atime
+#define	sa_nfsmtime		sa_un.sa_nfsv2.nfssa_mtime
+#define	sa_nqsize		sa_un.sa_nqnfs.nqsa_size
+#define	sa_nqatime		sa_un.sa_nqnfs.nqsa_atime
+#define	sa_nqmtime		sa_un.sa_nqnfs.nqsa_mtime
+#define	sa_nqflags		sa_un.sa_nqnfs.nqsa_flags
+#define	sa_nqrdev		sa_un.sa_nqnfs.nqsa_rdev
+
+struct nfsv2_statfs {
+	u_int32_t sf_tsize;
+	u_int32_t sf_bsize;
+	u_int32_t sf_blocks;
+	u_int32_t sf_bfree;
+	u_int32_t sf_bavail;
+	u_int32_t sf_files;	/* Nqnfs only */
+	u_int32_t sf_ffree;	/* ditto      */
+};
diff --git a/tcpdump.tproj/ntp.h b/tcpdump.tproj/ntp.h
new file mode 100644
index 0000000..dd69af9
--- /dev/null
+++ b/tcpdump.tproj/ntp.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/ntp.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ */
+
+/*
+ * Based on ntp.h from the U of MD implementation
+ *	This file is based on Version 2 of the NTP spec (RFC1119).
+ */
+
+/*
+ *  Definitions for the masses
+ */
+#define	JAN_1970	2208988800	/* 1970 - 1900 in seconds */
+
+/*
+ * Structure definitions for NTP fixed point values
+ *
+ *    0			  1		      2			  3
+ *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |			       Integer Part			     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |			       Fraction Part			     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *    0			  1		      2			  3
+ *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |		  Integer Part	     |	   Fraction Part	     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+struct l_fixedpt {
+	u_int32_t int_part;
+	u_int32_t fraction;
+};
+
+struct s_fixedpt {
+	u_short int_part;
+	u_short fraction;
+};
+
+/*  =================  Table 3.3. Packet Variables   ================= */
+/*
+ *    0			  1		      2			  3
+ *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |LI | VN  | Mode|	  Stratum    |	    Poll     |	 Precision   |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |			   Synchronizing Distance		     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |			  Synchronizing Dispersion		     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |			Reference Clock Identifier		     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |								     |
+ *   |		       Reference Timestamp (64 bits)		     |
+ *   |								     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |								     |
+ *   |		       Originate Timestamp (64 bits)		     |
+ *   |								     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |								     |
+ *   |			Receive Timestamp (64 bits)		     |
+ *   |								     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |								     |
+ *   |			Transmit Timestamp (64 bits)		     |
+ *   |								     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+struct ntpdata {
+	u_char status;		/* status of local clock and leap info */
+	u_char stratum;		/* Stratum level */
+	u_char ppoll;		/* poll value */
+	int precision:8;
+	struct s_fixedpt distance;
+	struct s_fixedpt dispersion;
+	u_int32_t refid;
+	struct l_fixedpt reftime;
+	struct l_fixedpt org;
+	struct l_fixedpt rec;
+	struct l_fixedpt xmt;
+};
+/*
+ *	Leap Second Codes (high order two bits)
+ */
+#define	NO_WARNING	0x00	/* no warning */
+#define	PLUS_SEC	0x40	/* add a second (61 seconds) */
+#define	MINUS_SEC	0x80	/* minus a second (59 seconds) */
+#define	ALARM		0xc0	/* alarm condition (clock unsynchronized) */
+
+/*
+ *	Clock Status Bits that Encode Version
+ */
+#define	NTPVERSION_1	0x08
+#define	VERSIONMASK	0x38
+#define LEAPMASK	0xc0
+#define	MODEMASK	0x07
+
+/*
+ *	Code values
+ */
+#define	MODE_UNSPEC	0	/* unspecified */
+#define	MODE_SYM_ACT	1	/* symmetric active */
+#define	MODE_SYM_PAS	2	/* symmetric passive */
+#define	MODE_CLIENT	3	/* client */
+#define	MODE_SERVER	4	/* server */
+#define	MODE_BROADCAST	5	/* broadcast */
+#define	MODE_RES1	6	/* reserved */
+#define	MODE_RES2	7	/* reserved */
+
+/*
+ *	Stratum Definitions
+ */
+#define	UNSPECIFIED	0
+#define	PRIM_REF	1	/* radio clock */
+#define	INFO_QUERY	62	/* **** THIS implementation dependent **** */
+#define	INFO_REPLY	63	/* **** THIS implementation dependent **** */
diff --git a/tcpdump.tproj/os-solaris2.h b/tcpdump.tproj/os-solaris2.h
new file mode 100644
index 0000000..440d65c
--- /dev/null
+++ b/tcpdump.tproj/os-solaris2.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/os-solaris2.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ (LBL)
+ */
+
+/* Prototypes missing in SunOS 5 */
+int	daemon(int, int);
+int	dn_expand(u_char *, u_char *, u_char *, u_char *, int);
+int	dn_skipname(u_char *, u_char *);
+int	flock(int, int);
+int	getdtablesize(void);
+int	gethostname(char *, int);
+int	getpagesize(void);
+char	*getusershell(void);
+char	*getwd(char *);
+int	iruserok(u_int, int, char *, char *);
+#ifdef __STDC__
+struct	utmp;
+void	login(struct utmp *);
+#endif
+int	logout(const char *);
+int	res_query(char *, int, int, u_char *, int);
+int	setenv(const char *, const char *, int);
+#if defined(_STDIO_H) && defined(HAVE_SETLINEBUF)
+int	setlinebuf(FILE *);
+#endif
+int	sigblock(int);
+int	sigsetmask(int);
+char    *strerror(int);
+int	snprintf(char *, size_t, const char *, ...);
+int	strcasecmp(const char *, const char *);
+void	unsetenv(const char *);
+#ifdef __STDC__
+struct	timeval;
+#endif
+int	utimes(const char *, struct timeval *);
diff --git a/tcpdump.tproj/os-sunos4.h b/tcpdump.tproj/os-sunos4.h
new file mode 100644
index 0000000..01389d1
--- /dev/null
+++ b/tcpdump.tproj/os-sunos4.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1990, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/os-sunos4.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ (LBL)
+ */
+
+/* Prototypes missing in SunOS 4 */
+#ifdef FILE
+int	_filbuf(FILE *);
+int	_flsbuf(u_char, FILE *);
+int	fclose(FILE *);
+int	fflush(FILE *);
+int	fgetc(FILE *);
+int	fprintf(FILE *, const char *, ...);
+int	fputc(int, FILE *);
+int	fputs(const char *, FILE *);
+u_int	fread(void *, u_int, u_int, FILE *);
+int	fseek(FILE *, long, int);
+u_int	fwrite(const void *, u_int, u_int, FILE *);
+int	pclose(FILE *);
+void	rewind(FILE *);
+void	setbuf(FILE *, char *);
+int	setlinebuf(FILE *);
+int	ungetc(int, FILE *);
+int	vfprintf(FILE *, const char *, ...);
+int	vprintf(const char *, ...);
+#endif
+
+#if __GNUC__ <= 1
+int	read(int, char *, u_int);
+int	write(int, char *, u_int);
+#endif
+
+long	a64l(const char *);
+#ifdef __STDC__
+struct	sockaddr;
+#endif
+int	accept(int, struct sockaddr *, int *);
+int	bind(int, struct sockaddr *, int);
+int	bcmp(const void *, const void *, u_int);
+void	bcopy(const void *, void *, u_int);
+void	bzero(void *, int);
+int	chroot(const char *);
+int	close(int);
+void	closelog(void);
+int	connect(int, struct sockaddr *, int);
+char	*crypt(const char *, const char *);
+int	daemon(int, int);
+int	fchmod(int, int);
+int	fchown(int, int, int);
+void	endgrent(void);
+void	endpwent(void);
+void	endservent(void);
+#ifdef __STDC__
+struct	ether_addr;
+#endif
+struct	ether_addr *ether_aton(const char *);
+int	flock(int, int);
+#ifdef __STDC__
+struct	stat;
+#endif
+int	fstat(int, struct stat *);
+#ifdef __STDC__
+struct statfs;
+#endif
+int	fstatfs(int, struct statfs *);
+int	fsync(int);
+#ifdef __STDC__
+struct timeb;
+#endif
+int	ftime(struct timeb *);
+int	ftruncate(int, off_t);
+int	getdtablesize(void);
+long	gethostid(void);
+int	gethostname(char *, int);
+int	getopt(int, char * const *, const char *);
+int	getpagesize(void);
+char	*getpass(char *);
+int	getpeername(int, struct sockaddr *, int *);
+int	getpriority(int, int);
+#ifdef __STDC__
+struct	rlimit;
+#endif
+int	getrlimit(int, struct rlimit *);
+int	getsockname(int, struct sockaddr *, int *);
+int	getsockopt(int, int, int, char *, int *);
+#ifdef __STDC__
+struct	timeval;
+struct	timezone;
+#endif
+int	gettimeofday(struct timeval *, struct timezone *);
+char	*getusershell(void);
+char	*getwd(char *);
+int	initgroups(const char *, int);
+int	ioctl(int, int, caddr_t);
+int	iruserok(u_long, int, char *, char *);
+int	isatty(int);
+int	killpg(int, int);
+int	listen(int, int);
+#ifdef __STDC__
+struct	utmp;
+#endif
+void	login(struct utmp *);
+int	logout(const char *);
+off_t	lseek(int, off_t, int);
+int	lstat(const char *, struct stat *);
+int	mkstemp(char *);
+char	*mktemp(char *);
+int	munmap(caddr_t, int);
+void	openlog(const char *, int, int);
+void	perror(const char *);
+int	printf(const char *, ...);
+int	puts(const char *);
+long	random(void);
+int	readlink(const char *, char *, int);
+#ifdef __STDC__
+struct	iovec;
+#endif
+int	readv(int, struct iovec *, int);
+int	recv(int, char *, u_int, int);
+int	recvfrom(int, char *, u_int, int, struct sockaddr *, int *);
+int	rename(const char *, const char *);
+int	rcmd(char **, u_short, char *, char *, char *, int *);
+int	rresvport(int *);
+int	send(int, char *, u_int, int);
+int	sendto(int, char *, u_int, int, struct sockaddr *, int);
+int	setenv(const char *, const char *, int);
+int	seteuid(int);
+int	setpriority(int, int, int);
+int	select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+int	setpgrp(int, int);
+void	setpwent(void);
+int	setrlimit(int, struct rlimit *);
+void	setservent(int);
+int	setsockopt(int, int, int, char *, int);
+int	shutdown(int, int);
+int	sigblock(int);
+void	(*signal (int, void (*) (int))) (int);
+int	sigpause(int);
+int	sigsetmask(int);
+#ifdef __STDC__
+struct	sigvec;
+#endif
+int	sigvec(int, struct sigvec *, struct sigvec*);
+int	snprintf(char *, size_t, const char *, ...);
+int	socket(int, int, int);
+int	socketpair(int, int, int, int *);
+int	symlink(const char *, const char *);
+void	srandom(int);
+int	sscanf(char *, const char *, ...);
+int	stat(const char *, struct stat *);
+int	statfs(char *, struct statfs *);
+char	*strerror(int);
+int	strcasecmp(const char *, const char *);
+#ifdef __STDC__
+struct	tm;
+#endif
+int	strftime(char *, int, char *, struct tm *);
+int	strncasecmp(const char *, const char *, int);
+long	strtol(const char *, char **, int);
+void	sync(void);
+void	syslog(int, const char *, ...);
+int	system(const char *);
+long	tell(int);
+time_t	time(time_t *);
+char	*timezone(int, int);
+int	tolower(int);
+int	toupper(int);
+int	truncate(char *, off_t);
+void	unsetenv(const char *);
+int	vfork(void);
+int	vsprintf(char *, const char *, ...);
+int	writev(int, struct iovec *, int);
+#ifdef __STDC__
+struct	rusage;
+#endif
+int	utimes(const char *, struct timeval *);
+#if __GNUC__ <= 1
+int	wait(int *);
+pid_t	wait3(int *, int, struct rusage *);
+#endif
+
+/* Ugly signal hacking */
+#ifdef SIG_ERR
+#undef SIG_ERR
+#define SIG_ERR		(void (*)(int))-1
+#undef SIG_DFL
+#define SIG_DFL		(void (*)(int))0
+#undef SIG_IGN
+#define SIG_IGN		(void (*)(int))1
+
+#ifdef KERNEL
+#undef SIG_CATCH
+#define SIG_CATCH	(void (*)(int))2
+#endif
+#undef SIG_HOLD
+#define SIG_HOLD	(void (*)(int))3
+#endif
diff --git a/tcpdump.tproj/os-ultrix4.h b/tcpdump.tproj/os-ultrix4.h
new file mode 100644
index 0000000..623d80a
--- /dev/null
+++ b/tcpdump.tproj/os-ultrix4.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/os-ultrix4.h,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ (LBL)
+ */
+
+/* Prototypes missing in Ultrix 4 */
+int	bcmp(const char *, const char *, u_int);
+void	bcopy(const void *, void *, u_int);
+void	bzero(void *, u_int);
+void	endservent(void);
+int	getopt(int, char * const *, const char *);
+#ifdef __STDC__
+struct timeval;
+struct timezone;
+#endif
+int	gettimeofday(struct timeval *, struct timezone *);
+int	ioctl(int, int, caddr_t);
+int	pfopen(char *, int);
+int	setlinebuf(FILE *);
+int	socket(int, int, int);
+int	strcasecmp(const char *, const char *);
diff --git a/tcpdump.tproj/ospf.h b/tcpdump.tproj/ospf.h
new file mode 100644
index 0000000..9be2236
--- /dev/null
+++ b/tcpdump.tproj/ospf.h
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1991, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
+ */
+#define	OSPF_TYPE_UMD	0	/* UMd's special monitoring packets */
+#define	OSPF_TYPE_HELLO	1	/* Hello */
+#define	OSPF_TYPE_DB	2	/* Database Description */
+#define	OSPF_TYPE_LSR	3	/* Link State Request */
+#define	OSPF_TYPE_LSU	4	/* Link State Update */
+#define	OSPF_TYPE_LSA	5	/* Link State Ack */
+#define	OSPF_TYPE_MAX	6
+
+/* Options *_options	*/
+#define OSPF_OPTION_T	0x01	/* T bit: TOS support	*/
+#define OSPF_OPTION_E	0x02	/* E bit: External routes advertised	*/
+#define	OSPF_OPTION_MC	0x04	/* MC bit: Multicast capable */
+
+/* ospf_authtype	*/
+#define	OSPF_AUTH_NONE		0	/* No auth-data */
+#define	OSPF_AUTH_SIMPLE	1	/* Simple password */
+
+/* db_flags	*/
+#define	OSPF_DB_INIT		0x04	    /*	*/
+#define	OSPF_DB_MORE		0x02
+#define	OSPF_DB_MASTER		0x01
+
+/* ls_type	*/
+#define	LS_TYPE_ROUTER		1   /* router link */
+#define	LS_TYPE_NETWORK		2   /* network link */
+#define	LS_TYPE_SUM_IP		3   /* summary link */
+#define	LS_TYPE_SUM_ABR		4   /* summary area link */
+#define	LS_TYPE_ASE		5   /* ASE  */
+#define	LS_TYPE_GROUP		6   /* Group membership (multicast */
+				    /* extensions 23 July 1991) */
+#define	LS_TYPE_MAX		7
+
+/*************************************************
+ *
+ * is the above a bug in the documentation?
+ *
+ *************************************************/
+
+
+/* rla_link.link_type	*/
+#define	RLA_TYPE_ROUTER		1   /* point-to-point to another router	*/
+#define	RLA_TYPE_TRANSIT	2   /* connection to transit network	*/
+#define	RLA_TYPE_STUB		3   /* connection to stub network	*/
+#define RLA_TYPE_VIRTUAL	4   /* virtual link			*/
+
+/* rla_flags	*/
+#define	RLA_FLAG_B	0x01
+#define	RLA_FLAG_E	0x02
+#define	RLA_FLAG_W1	0x04
+#define	RLA_FLAG_W2	0x08
+
+/* sla_tosmetric breakdown	*/
+#define	SLA_MASK_TOS		0x7f000000
+#define	SLA_MASK_METRIC		0x00ffffff
+#define SLA_SHIFT_TOS		24
+
+/* asla_tosmetric breakdown	*/
+#define	ASLA_FLAG_EXTERNAL	0x80000000
+#define	ASLA_MASK_TOS		0x7f000000
+#define	ASLA_SHIFT_TOS		24
+#define	ASLA_MASK_METRIC	0x00ffffff
+
+/* multicast vertex type */
+#define	MCLA_VERTEX_ROUTER	1
+#define	MCLA_VERTEX_NETWORK	2
+
+/* link state advertisement header */
+struct lsa_hdr {
+    u_short ls_age;
+    u_char ls_options;
+    u_char ls_type;
+    struct in_addr ls_stateid;
+    struct in_addr ls_router;
+    u_int32_t ls_seq;
+    u_short ls_chksum;
+    u_short ls_length;
+} ;
+
+/* link state advertisement */
+struct lsa {
+    struct lsa_hdr ls_hdr;
+
+    /* Link state types */
+    union {
+	/* Router links advertisements */
+	struct {
+	    u_char rla_flags;
+	    u_char rla_zero[1];
+	    u_short rla_count;
+	    struct rlalink {
+		struct in_addr link_id;
+		struct in_addr link_data;
+		u_char link_type;
+		u_char link_toscount;
+		u_short link_tos0metric;
+	    } rla_link[1];		/* may repeat	*/
+	} un_rla;
+
+	/* Network links advertisements */
+	struct {
+	    struct in_addr nla_mask;
+	    struct in_addr nla_router[1];	/* may repeat	*/
+	} un_nla;
+
+	/* Summary links advertisements */
+	struct {
+	    struct in_addr sla_mask;
+	    u_int32_t sla_tosmetric[1];	/* may repeat	*/
+	} un_sla;
+
+	/* AS external links advertisements */
+	struct {
+	    struct in_addr asla_mask;
+	    struct aslametric {
+		u_int32_t asla_tosmetric;
+		struct in_addr asla_forward;
+		struct in_addr asla_tag;
+	    } asla_metric[1];		/* may repeat	*/
+	} un_asla;
+
+	/* Multicast group membership */
+	struct mcla {
+	    u_int32_t mcla_vtype;
+	    struct in_addr mcla_vid;
+	} un_mcla[1];
+    } lsa_un;
+} ;
+
+
+/*
+ * TOS metric struct (will be 0 or more in router links update)
+ */
+struct tos_metric {
+    u_char tos_type;
+    u_char tos_zero;
+    u_short tos_metric;
+} ;
+
+#define	OSPF_AUTH_SIZE	8
+
+/*
+ * the main header
+ */
+struct ospfhdr {
+    u_char ospf_version;
+    u_char ospf_type;
+    u_short ospf_len;
+    struct in_addr ospf_routerid;
+    struct in_addr ospf_areaid;
+    u_short ospf_chksum;
+    u_short ospf_authtype;
+    u_char ospf_authdata[OSPF_AUTH_SIZE];
+    union {
+
+	/* Hello packet */
+	struct {
+	    struct in_addr hello_mask;
+	    u_short hello_helloint;
+	    u_char hello_options;
+	    u_char hello_priority;
+	    u_int32_t hello_deadint;
+	    struct in_addr hello_dr;
+	    struct in_addr hello_bdr;
+	    struct in_addr hello_neighbor[1]; /* may repeat	*/
+	} un_hello;
+
+	/* Database Description packet */
+	struct {
+	    u_char db_zero[2];
+	    u_char db_options;
+	    u_char db_flags;
+	    u_int32_t db_seq;
+	    struct lsa_hdr db_lshdr[1]; /* may repeat	*/
+	} un_db;
+
+	/* Link State Request */
+	struct lsr {
+	    u_int32_t ls_type;
+	    struct in_addr ls_stateid;
+	    struct in_addr ls_router;
+	} un_lsr[1];		/* may repeat	*/
+
+	/* Link State Update */
+	struct {
+	    u_int32_t lsu_count;
+	    struct lsa lsu_lsa[1]; /* may repeat	*/
+	} un_lsu;
+
+	/* Link State Acknowledgement */
+	struct {
+	    struct lsa_hdr lsa_lshdr[1]; /* may repeat	*/
+	} un_lsa ;
+    } ospf_un ;
+} ;
+
+#define	ospf_hello	ospf_un.un_hello
+#define	ospf_db		ospf_un.un_db
+#define	ospf_lsr	ospf_un.un_lsr
+#define	ospf_lsu	ospf_un.un_lsu
+#define	ospf_lsa	ospf_un.un_lsa
+
diff --git a/tcpdump.tproj/parsenfsfh.c b/tcpdump.tproj/parsenfsfh.c
new file mode 100644
index 0000000..bdfdf43
--- /dev/null
+++ b/tcpdump.tproj/parsenfsfh.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * parsenfsfh.c - portable parser for NFS file handles
+ *			uses all sorts of heuristics
+ *
+ * Jeffrey C. Mogul
+ * Digital Equipment Corporation
+ * Western Research Laboratory
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/parsenfsfh.c,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <memory.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "nfsfh.h"
+
+/*
+ * This routine attempts to parse a file handle (in network byte order),
+ * using heuristics to guess what kind of format it is in.  See the
+ * file "fhandle_layouts" for a detailed description of the various
+ * patterns we know about.
+ *
+ * The file handle is parsed into our internal representation of a
+ * file-system id, and an internal representation of an inode-number.
+ */
+
+#define	FHT_UNKNOWN	0
+#define	FHT_AUSPEX	1
+#define	FHT_DECOSF	2
+#define	FHT_IRIX4	3
+#define	FHT_IRIX5	4
+#define	FHT_SUNOS3	5
+#define	FHT_SUNOS4	6
+#define	FHT_ULTRIX	7
+#define	FHT_VMSUCX	8
+#define	FHT_SUNOS5	9
+#define	FHT_AIX32	10
+#define	FHT_HPUX9	11
+
+#ifdef	ultrix
+/* Nasty hack to keep the Ultrix C compiler from emitting bogus warnings */
+#define	XFF(x)	((u_int32_t)(x))
+#else
+#define	XFF(x)	(x)
+#endif
+
+#define	make_uint32(msb,b,c,lsb)\
+	(XFF(lsb) + (XFF(c)<<8) + (XFF(b)<<16) + (XFF(msb)<<24))
+
+#define	make_uint24(msb,b, lsb)\
+	(XFF(lsb) + (XFF(b)<<8) + (XFF(msb)<<16))
+
+#define	make_uint16(msb,lsb)\
+	(XFF(lsb) + (XFF(msb)<<8))
+
+#ifdef	__alpha
+	/* or other 64-bit systems */
+#define	make_uint48(msb,b,c,d,e,lsb)\
+	((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24) + ((b)<<32) + ((msb)<<40))
+#else
+	/* on 32-bit systems ignore high-order bits */
+#define	make_uint48(msb,b,c,d,e,lsb)\
+	((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24))
+#endif
+
+static int is_UCX(unsigned char *);
+
+void
+Parse_fh(fh, fsidp, inop, osnamep, fsnamep, ourself)
+register caddr_t *fh;
+my_fsid *fsidp;
+ino_t *inop;
+char **osnamep;		/* if non-NULL, return OS name here */
+char **fsnamep;		/* if non-NULL, return server fs name here (for VMS) */
+int ourself;		/* true if file handle was generated on this host */
+{
+	register unsigned char *fhp = (unsigned char *)fh;
+	u_int32_t temp;
+	int fhtype = FHT_UNKNOWN;
+
+	if (ourself) {
+	    /* File handle generated on this host, no need for guessing */
+#if	defined(IRIX40)
+	    fhtype = FHT_IRIX4;
+#endif
+#if	defined(IRIX50)
+	    fhtype = FHT_IRIX5;
+#endif
+#if	defined(IRIX51)
+	    fhtype = FHT_IRIX5;
+#endif
+#if	defined(SUNOS4)
+	    fhtype = FHT_SUNOS4;
+#endif
+#if	defined(SUNOS5)
+	    fhtype = FHT_SUNOS5;
+#endif
+#if	defined(ultrix)
+	    fhtype = FHT_ULTRIX;
+#endif
+#if	defined(__osf__)
+	    fhtype = FHT_DECOSF;
+#endif
+	}
+	/*
+	 * This is basically a big decision tree
+	 */
+	else if ((fhp[0] == 0) && (fhp[1] == 0)) {
+	    /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */
+	    /* probably rules out HP-UX, AIX unless they allow major=0 */
+	    if ((fhp[2] == 0) && (fhp[3] == 0)) {
+		/* bytes[2,3] == (0,0); must be Auspex */
+		/* XXX or could be Ultrix+MASSBUS "hp" disk? */
+		fhtype = FHT_AUSPEX;
+	    }
+	    else {
+		/*
+		 * bytes[2,3] != (0,0); rules out Auspex, could be
+		 * DECOSF, SUNOS4, or IRIX4
+		 */
+		if ((fhp[4] != 0) && (fhp[5] == 0) &&
+			(fhp[8] == 12) && (fhp[9] == 0)) {
+		    /* seems to be DECOSF, with minor == 0 */
+		    fhtype = FHT_DECOSF;
+		}
+		else {
+		    /* could be SUNOS4 or IRIX4 */
+		    /* XXX the test of fhp[5] == 8 could be wrong */
+		    if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) &&
+			(fhp[7] == 0)) {
+			/* looks like a length, not a file system typecode */
+			fhtype = FHT_IRIX4;
+		    }
+		    else {
+			/* by elimination */
+			fhtype = FHT_SUNOS4;
+		    }
+		}
+	    }
+	}
+	else {
+	    /*
+	     * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4
+	     * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5
+	     * could be AIX, HP-UX
+	     */
+	    if ((fhp[2] == 0) && (fhp[3] == 0)) {
+		/*
+		 * bytes[2,3] == (0,0); rules out OSF, probably not UCX
+		 * (unless the exported device name is just one letter!),
+		 * could be Ultrix, IRIX5, AIX, or SUNOS5
+		 * might be HP-UX (depends on their values for minor devs)
+		 */
+		/*XXX we probably only need to test of these two bytes */
+		if ((fhp[21] == 0) && (fhp[23] == 0)) {
+		    fhtype = FHT_ULTRIX;
+		}
+		else {
+		    /* Could be SUNOS5/IRIX5, maybe AIX */
+		    /* XXX no obvious difference between SUNOS5 and IRIX5 */
+		    if (fhp[9] == 10)
+			fhtype = FHT_SUNOS5;
+		    /* XXX what about AIX? */
+		}
+	    }
+	    else {
+		/*
+		 * bytes[2,3] != (0,0); rules out Ultrix, could be
+		 * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX
+		 */
+		if ((fhp[8] == 12) && (fhp[9] == 0)) {
+		    fhtype = FHT_DECOSF;
+		}
+		else if ((fhp[8] == 0) && (fhp[9] == 10)) {
+		    /* could be SUNOS5/IRIX5, AIX, HP-UX */
+		    if ((fhp[7] == 0) && (fhp[6] == 0) &&
+			(fhp[5] == 0) && (fhp[4] == 0)) {
+			/* XXX is this always true of HP-UX? */
+			fhtype = FHT_HPUX9;
+		    }
+		    else if (fhp[7] == 2) {
+			/* This would be MNT_NFS on AIX, which is impossible */
+			fhtype = FHT_SUNOS5;	/* or maybe IRIX5 */
+		    }
+		    else {
+			/*
+			 * XXX Could be SUNOS5/IRIX5 or AIX.  I don't
+			 * XXX see any way to disambiguate these, so
+			 * XXX I'm going with the more likely guess.
+			 * XXX Sorry, Big Blue.
+			 */
+			fhtype = FHT_SUNOS5;	/* or maybe IRIX5 */
+		    }
+	        }
+		else {
+		    if (is_UCX(fhp)) {
+			fhtype = FHT_VMSUCX;
+		    }
+		    else {
+			fhtype = FHT_UNKNOWN;
+		    }
+		}
+	    }
+	}
+
+	/* XXX still needs to handle SUNOS3 */
+
+	switch (fhtype) {
+	case FHT_AUSPEX:
+	    fsidp->Fsid_dev.Minor = fhp[7];
+	    fsidp->Fsid_dev.Major = fhp[6];
+	    fsidp->fsid_code = 0;
+
+	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+	    *inop = temp;
+
+	    if (osnamep)
+		*osnamep = "Auspex";
+	    break;
+
+	case FHT_DECOSF:
+	    fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]);
+			/* XXX could ignore 3 high-order bytes */
+
+	    temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]);
+	    fsidp->Fsid_dev.Minor = temp & 0xFFFFF;
+	    fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF;
+
+	    temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]);
+	    *inop = temp;
+	    if (osnamep)
+		*osnamep = "OSF";
+	    break;
+
+	case FHT_IRIX4:
+	    fsidp->Fsid_dev.Minor = fhp[3];
+	    fsidp->Fsid_dev.Major = fhp[2];
+	    fsidp->fsid_code = 0;
+
+	    temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]);
+	    *inop = temp;
+
+	    if (osnamep)
+		*osnamep = "IRIX4";
+	    break;
+
+	case FHT_IRIX5:
+	    fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]);
+	    fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]);
+	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+	    *inop = temp;
+
+	    if (osnamep)
+		*osnamep = "IRIX5";
+	    break;
+
+	case FHT_SUNOS3:
+	    if (osnamep)
+		*osnamep = "SUNOS3";
+	    break;
+
+	case FHT_SUNOS4:
+	    fsidp->Fsid_dev.Minor = fhp[3];
+	    fsidp->Fsid_dev.Major = fhp[2];
+	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+	    *inop = temp;
+
+	    if (osnamep)
+		*osnamep = "SUNOS4";
+	    break;
+
+	case FHT_SUNOS5:
+	    temp = make_uint16(fhp[0], fhp[1]);
+	    fsidp->Fsid_dev.Major = (temp>>2) &  0x3FFF;
+	    temp = make_uint24(fhp[1], fhp[2], fhp[3]);
+	    fsidp->Fsid_dev.Minor = temp & 0x3FFFF;
+	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+	    *inop = temp;
+
+	    if (osnamep)
+		*osnamep = "SUNOS5";
+	    break;
+
+	case FHT_ULTRIX:
+	    fsidp->fsid_code = 0;
+	    fsidp->Fsid_dev.Minor = fhp[0];
+	    fsidp->Fsid_dev.Major = fhp[1];
+
+	    temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]);
+	    *inop = temp;
+	    if (osnamep)
+		*osnamep = "Ultrix";
+	    break;
+
+	case FHT_VMSUCX:
+	    /* No numeric file system ID, so hash on the device-name */
+	    if (sizeof(*fsidp) >= 14) {
+		if (sizeof(*fsidp) > 14)
+		    memset((char *)fsidp, 0, sizeof(*fsidp));
+		memcpy((char *)fsidp, fh, 14);	/* just use the whole thing */
+	    }
+	    else {
+		u_int32_t tempa[4];	/* at least 16 bytes, maybe more */
+
+		memset((char *)tempa, 0, sizeof(tempa));
+		memcpy((char *)tempa, fh, 14);	/* ensure alignment */
+		fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1);
+		fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1);
+		fsidp->fsid_code = 0;
+	    }
+
+	    /* VMS file ID is: (RVN, FidHi, FidLo) */
+	    *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]);
+
+	    /* Caller must save (and null-terminate?) this value */
+	    if (fsnamep)
+		*fsnamep = (char *)&(fhp[1]);
+
+	    if (osnamep)
+		*osnamep = "VMS";
+	    break;
+
+	case FHT_AIX32:
+	    fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]);
+	    fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]);
+	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+	    *inop = temp;
+
+	    if (osnamep)
+		*osnamep = "AIX32";
+	    break;
+
+	case FHT_HPUX9:
+	    fsidp->Fsid_dev.Major = fhp[0];
+	    temp = make_uint24(fhp[1], fhp[2], fhp[3]);
+	    fsidp->Fsid_dev.Minor = temp;
+	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+	    *inop = temp;
+
+	    if (osnamep)
+		*osnamep = "HPUX9";
+	    break;
+
+	case FHT_UNKNOWN:
+#ifdef DEBUG
+	    {
+		/* XXX debugging */
+		int i;
+		for (i = 0; i < 32; i++)
+			(void)fprintf(stderr, "%x.", fhp[i]);
+		(void)fprintf(stderr, "\n");
+	    }
+#endif
+	    /* XXX for now, give "bogus" values to aid debugging */
+	    fsidp->fsid_code = 0;
+	    fsidp->Fsid_dev.Minor = 257;
+	    fsidp->Fsid_dev.Major = 257;
+	    *inop = 1;
+
+	    /* display will show this string instead of (257,257) */
+	    if (fsnamep)
+		*fsnamep = "Unknown";
+
+	    if (osnamep)
+		*osnamep = "Unknown";
+	    break;
+
+	}
+}
+
+/*
+ * Is this a VMS UCX file handle?
+ *	Check for:
+ *	(1) leading code byte	[XXX not yet]
+ *	(2) followed by string of printing chars & spaces
+ *	(3) followed by string of nulls
+ */
+static int
+is_UCX(fhp)
+unsigned char *fhp;
+{
+	register int i;
+	int seen_null = 0;
+
+	for (i = 1; i < 14; i++) {
+	    if (isprint(fhp[i])) {
+		if (seen_null)
+		   return(0);
+		else
+		   continue;
+	    }
+	    else if (fhp[i] == 0) {
+		seen_null = 1;
+		continue;
+	    }
+	    else
+		return(0);
+	}
+
+	return(1);
+}
diff --git a/tcpdump.tproj/print-arp.c b/tcpdump.tproj/print-arp.c
new file mode 100644
index 0000000..0fe851b
--- /dev/null
+++ b/tcpdump.tproj/print-arp.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-arp.c,v 1.1.1.1 1999/05/02 03:58:32 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "extract.h"			/* must come after interface.h */
+
+/* Compatibility */
+#ifndef REVARP_REQUEST
+#define REVARP_REQUEST		3
+#endif
+#ifndef REVARP_REPLY
+#define REVARP_REPLY		4
+#endif
+
+static u_char ezero[6];
+
+void
+arp_print(register const u_char *bp, u_int length, u_int caplen)
+{
+	register const struct ether_arp *ap;
+	register const struct ether_header *eh;
+	register u_short pro, hrd, op;
+
+	ap = (struct ether_arp *)bp;
+	if ((u_char *)(ap + 1) > snapend) {
+		printf("[|arp]");
+		return;
+	}
+	if (length < sizeof(struct ether_arp)) {
+		(void)printf("truncated-arp");
+		default_print((u_char *)ap, length);
+		return;
+	}
+
+	pro = EXTRACT_16BITS(&ap->arp_pro);
+	hrd = EXTRACT_16BITS(&ap->arp_hrd);
+	op = EXTRACT_16BITS(&ap->arp_op);
+
+	if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+	    || ap->arp_hln != sizeof(SHA(ap))
+	    || ap->arp_pln != sizeof(SPA(ap))) {
+		(void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)",
+				op, pro, ap->arp_pln,
+				hrd, ap->arp_hln);
+		return;
+	}
+	if (pro == ETHERTYPE_TRAIL)
+		(void)printf("trailer-");
+	eh = (struct ether_header *)packetp;
+	switch (op) {
+
+	case ARPOP_REQUEST:
+		(void)printf("arp who-has %s", ipaddr_string(TPA(ap)));
+		if (memcmp((char *)ezero, (char *)THA(ap), 6) != 0)
+			(void)printf(" (%s)", etheraddr_string(THA(ap)));
+		(void)printf(" tell %s", ipaddr_string(SPA(ap)));
+		if (memcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0)
+			(void)printf(" (%s)", etheraddr_string(SHA(ap)));
+		break;
+
+	case ARPOP_REPLY:
+		(void)printf("arp reply %s", ipaddr_string(SPA(ap)));
+		if (memcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0)
+			(void)printf(" (%s)", etheraddr_string(SHA(ap)));
+		(void)printf(" is-at %s", etheraddr_string(SHA(ap)));
+		if (memcmp((char *)EDST(eh), (char *)THA(ap), 6) != 0)
+			(void)printf(" (%s)", etheraddr_string(THA(ap)));
+		break;
+
+	case REVARP_REQUEST:
+		(void)printf("rarp who-is %s tell %s",
+			etheraddr_string(THA(ap)),
+			etheraddr_string(SHA(ap)));
+		break;
+
+	case REVARP_REPLY:
+		(void)printf("rarp reply %s at %s",
+			etheraddr_string(THA(ap)),
+			ipaddr_string(TPA(ap)));
+		break;
+
+	default:
+		(void)printf("arp-#%d", op);
+		default_print((u_char *)ap, caplen);
+		return;
+	}
+	if (hrd != ARPHRD_ETHER)
+		printf(" hardware #%d", hrd);
+}
diff --git a/tcpdump.tproj/print-atalk.c b/tcpdump.tproj/print-atalk.c
new file mode 100644
index 0000000..f939466
--- /dev/null
+++ b/tcpdump.tproj/print-atalk.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print AppleTalk packets.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-atalk.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "extract.h"			/* must come after interface.h */
+#include "appletalk.h"
+
+static struct tok type2str[] = {
+	{ ddpRTMP,		"rtmp" },
+	{ ddpRTMPrequest,	"rtmpReq" },
+	{ ddpECHO,		"echo" },
+	{ ddpIP,		"IP" },
+	{ ddpARP,		"ARP" },
+	{ ddpKLAP,		"KLAP" },
+	{ 0,			NULL }
+};
+
+struct aarp {
+	u_short htype, ptype;
+	u_char	halen, palen;
+	u_short op;
+	u_char	hsaddr[6];
+	u_char	psaddr[4];
+	u_char	hdaddr[6];
+	u_char	pdaddr[4];
+};
+
+static char tstr[] = "[|atalk]";
+
+static void atp_print(const struct atATP *, u_int);
+static void atp_bitmap_print(u_char);
+static void nbp_print(const struct atNBP *, u_int, u_short, u_char, u_char);
+static const char *print_cstring(const char *, const u_char *);
+static const struct atNBPtuple *nbp_tuple_print(const struct atNBPtuple *,
+						const u_char *,
+						u_short, u_char, u_char);
+static const struct atNBPtuple *nbp_name_print(const struct atNBPtuple *,
+					       const u_char *);
+static const char *ataddr_string(u_short, u_char);
+static void ddp_print(const u_char *, u_int, int, u_short, u_char, u_char);
+static const char *ddpskt_string(int);
+
+/*
+ * Print AppleTalk Datagram Delivery Protocol packets.
+ */
+void
+atalk_print(register const u_char *bp, u_int length)
+{
+	register const struct LAP *lp;
+	register const struct atDDP *dp;
+	register const struct atShortDDP *sdp;
+	u_short snet;
+
+	lp = (struct LAP *)bp;
+	bp += sizeof(*lp);
+	length -= sizeof(*lp);
+	switch (lp->type) {
+
+	case lapShortDDP:
+		if (length < ddpSSize) {
+			(void)printf(" [|sddp %d]", length);
+			return;
+		}
+		sdp = (const struct atShortDDP *)bp;
+		printf("%s.%s",
+		    ataddr_string(0, lp->src), ddpskt_string(sdp->srcSkt));
+		printf(" > %s.%s:",
+		    ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt));
+		bp += ddpSSize;
+		length -= ddpSSize;
+		ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt);
+		break;
+
+	case lapDDP:
+		if (length < ddpSize) {
+			(void)printf(" [|ddp %d]", length);
+			return;
+		}
+		dp = (const struct atDDP *)bp;
+		snet = EXTRACT_16BITS(&dp->srcNet);
+		printf("%s.%s", ataddr_string(snet, dp->srcNode),
+		    ddpskt_string(dp->srcSkt));
+		printf(" > %s.%s:",
+		    ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
+		    ddpskt_string(dp->dstSkt));
+		bp += ddpSize;
+		length -= ddpSize;
+		ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
+		break;
+
+#ifdef notdef
+	case lapKLAP:
+		klap_print(bp, length);
+		break;
+#endif
+
+	default:
+		printf("%d > %d at-lap#%d %d",
+		    lp->src, lp->dst, lp->type, length);
+		break;
+	}
+}
+
+/* XXX should probably pass in the snap header and do checks like arp_print() */
+void
+aarp_print(register const u_char *bp, u_int length)
+{
+	register const struct aarp *ap;
+
+#define AT(member) ataddr_string((ap->member[1]<<8)|ap->member[2],ap->member[3])
+
+	printf("aarp ");
+	ap = (const struct aarp *)bp;
+	if (ap->htype == 1 && ap->ptype == ETHERTYPE_ATALK &&
+	    ap->halen == 6 && ap->palen == 4 )
+		switch (ap->op) {
+
+		case 1:				/* request */
+			(void)printf("who-has %s tell %s",
+			    AT(pdaddr), AT(psaddr));
+			return;
+
+		case 2:				/* response */
+			(void)printf("reply %s is-at %s",
+			    AT(pdaddr), etheraddr_string(ap->hdaddr));
+			return;
+
+		case 3:				/* probe (oy!) */
+			(void)printf("probe %s tell %s",
+			    AT(pdaddr), AT(psaddr));
+			return;
+		}
+	(void)printf("len %d op %d htype %d ptype %#x halen %d palen %d",
+	    length, ap->op, ap->htype, ap->ptype, ap->halen, ap->palen );
+}
+
+static void
+ddp_print(register const u_char *bp, register u_int length, register int t,
+	  register u_short snet, register u_char snode, u_char skt)
+{
+
+	switch (t) {
+
+	case ddpNBP:
+		nbp_print((const struct atNBP *)bp, length, snet, snode, skt);
+		break;
+
+	case ddpATP:
+		atp_print((const struct atATP *)bp, length);
+		break;
+
+	default:
+		(void)printf(" at-%s %d", tok2str(type2str, NULL, t), length);
+		break;
+	}
+}
+
+static void
+atp_print(register const struct atATP *ap, u_int length)
+{
+	char c;
+	u_int32_t data;
+
+	if ((const u_char *)(ap + 1) > snapend) {
+		/* Just bail if we don't have the whole chunk. */
+		fputs(tstr, stdout);
+		return;
+	}
+	length -= sizeof(*ap);
+	switch (ap->control & 0xc0) {
+
+	case atpReqCode:
+		(void)printf(" atp-req%s %d",
+			     ap->control & atpXO? " " : "*",
+			     EXTRACT_16BITS(&ap->transID));
+
+		atp_bitmap_print(ap->bitmap);
+
+		if (length != 0)
+			(void)printf(" [len=%d]", length);
+
+		switch (ap->control & (atpEOM|atpSTS)) {
+		case atpEOM:
+			(void)printf(" [EOM]");
+			break;
+		case atpSTS:
+			(void)printf(" [STS]");
+			break;
+		case atpEOM|atpSTS:
+			(void)printf(" [EOM,STS]");
+			break;
+		}
+		break;
+
+	case atpRspCode:
+		(void)printf(" atp-resp%s%d:%d (%d)",
+			     ap->control & atpEOM? "*" : " ",
+			     EXTRACT_16BITS(&ap->transID), ap->bitmap, length);
+		switch (ap->control & (atpXO|atpSTS)) {
+		case atpXO:
+			(void)printf(" [XO]");
+			break;
+		case atpSTS:
+			(void)printf(" [STS]");
+			break;
+		case atpXO|atpSTS:
+			(void)printf(" [XO,STS]");
+			break;
+		}
+		break;
+
+	case atpRelCode:
+		(void)printf(" atp-rel  %d", EXTRACT_16BITS(&ap->transID));
+
+		atp_bitmap_print(ap->bitmap);
+
+		/* length should be zero */
+		if (length)
+			(void)printf(" [len=%d]", length);
+
+		/* there shouldn't be any control flags */
+		if (ap->control & (atpXO|atpEOM|atpSTS)) {
+			c = '[';
+			if (ap->control & atpXO) {
+				(void)printf("%cXO", c);
+				c = ',';
+			}
+			if (ap->control & atpEOM) {
+				(void)printf("%cEOM", c);
+				c = ',';
+			}
+			if (ap->control & atpSTS) {
+				(void)printf("%cSTS", c);
+				c = ',';
+			}
+			(void)printf("]");
+		}
+		break;
+
+	default:
+		(void)printf(" atp-0x%x  %d (%d)", ap->control,
+			     EXTRACT_16BITS(&ap->transID), length);
+		break;
+	}
+	data = EXTRACT_32BITS(&ap->userData);
+	if (data != 0)
+		(void)printf(" 0x%x", data);
+}
+
+static void
+atp_bitmap_print(register u_char bm)
+{
+	register char c;
+	register int i;
+
+	/*
+	 * The '& 0xff' below is needed for compilers that want to sign
+	 * extend a u_char, which is the case with the Ultrix compiler.
+	 * (gcc is smart enough to eliminate it, at least on the Sparc).
+	 */
+	if ((bm + 1) & (bm & 0xff)) {
+		c = '<';
+		for (i = 0; bm; ++i) {
+			if (bm & 1) {
+				(void)printf("%c%d", c, i);
+				c = ',';
+			}
+			bm >>= 1;
+		}
+		(void)printf(">");
+	} else {
+		for (i = 0; bm; ++i)
+			bm >>= 1;
+		if (i > 1)
+			(void)printf("<0-%d>", i - 1);
+		else
+			(void)printf("<0>");
+	}
+}
+
+static void
+nbp_print(register const struct atNBP *np, u_int length, register u_short snet,
+	  register u_char snode, register u_char skt)
+{
+	register const struct atNBPtuple *tp =
+			(struct atNBPtuple *)((u_char *)np + nbpHeaderSize);
+	int i;
+	const u_char *ep;
+
+	length -= nbpHeaderSize;
+	if (length < 8) {
+		/* must be room for at least one tuple */
+		(void)printf(" truncated-nbp %d", length + nbpHeaderSize);
+		return;
+	}
+	/* ep points to end of available data */
+	ep = snapend;
+	if ((const u_char *)tp > ep) {
+		fputs(tstr, stdout);
+		return;
+	}
+	switch (i = np->control & 0xf0) {
+
+	case nbpBrRq:
+	case nbpLkUp:
+		(void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:",
+			     np->id);
+		if ((const u_char *)(tp + 1) > ep) {
+			fputs(tstr, stdout);
+			return;
+		}
+		(void)nbp_name_print(tp, ep);
+		/*
+		 * look for anomalies: the spec says there can only
+		 * be one tuple, the address must match the source
+		 * address and the enumerator should be zero.
+		 */
+		if ((np->control & 0xf) != 1)
+			(void)printf(" [ntup=%d]", np->control & 0xf);
+		if (tp->enumerator)
+			(void)printf(" [enum=%d]", tp->enumerator);
+		if (EXTRACT_16BITS(&tp->net) != snet ||
+		    tp->node != snode || tp->skt != skt)
+			(void)printf(" [addr=%s.%d]",
+			    ataddr_string(EXTRACT_16BITS(&tp->net),
+			    tp->node), tp->skt);
+		break;
+
+	case nbpLkUpReply:
+		(void)printf(" nbp-reply %d:", np->id);
+
+		/* print each of the tuples in the reply */
+		for (i = np->control & 0xf; --i >= 0 && tp; )
+			tp = nbp_tuple_print(tp, ep, snet, snode, skt);
+		break;
+
+	default:
+		(void)printf(" nbp-0x%x  %d (%d)", np->control, np->id,
+				length);
+		break;
+	}
+}
+
+/* print a counted string */
+static const char *
+print_cstring(register const char *cp, register const u_char *ep)
+{
+	register u_int length;
+
+	if (cp >= (const char *)ep) {
+		fputs(tstr, stdout);
+		return (0);
+	}
+	length = *cp++;
+
+	/* Spec says string can be at most 32 bytes long */
+	if (length < 0 || length > 32) {
+		(void)printf("[len=%d]", length);
+		return (0);
+	}
+	while (--length >= 0) {
+		if (cp >= (char *)ep) {
+			fputs(tstr, stdout);
+			return (0);
+		}
+		putchar(*cp++);
+	}
+	return (cp);
+}
+
+static const struct atNBPtuple *
+nbp_tuple_print(register const struct atNBPtuple *tp,
+		register const u_char *ep,
+		register u_short snet, register u_char snode,
+		register u_char skt)
+{
+	register const struct atNBPtuple *tpn;
+
+	if ((const u_char *)(tp + 1) > ep) {
+		fputs(tstr, stdout);
+		return 0;
+	}
+	tpn = nbp_name_print(tp, ep);
+
+	/* if the enumerator isn't 1, print it */
+	if (tp->enumerator != 1)
+		(void)printf("(%d)", tp->enumerator);
+
+	/* if the socket doesn't match the src socket, print it */
+	if (tp->skt != skt)
+		(void)printf(" %d", tp->skt);
+
+	/* if the address doesn't match the src address, it's an anomaly */
+	if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode)
+		(void)printf(" [addr=%s]",
+		    ataddr_string(EXTRACT_16BITS(&tp->net), tp->node));
+
+	return (tpn);
+}
+
+static const struct atNBPtuple *
+nbp_name_print(const struct atNBPtuple *tp, register const u_char *ep)
+{
+	register const char *cp = (const char *)tp + nbpTupleSize;
+
+	putchar(' ');
+
+	/* Object */
+	putchar('"');
+	if ((cp = print_cstring(cp, ep)) != NULL) {
+		/* Type */
+		putchar(':');
+		if ((cp = print_cstring(cp, ep)) != NULL) {
+			/* Zone */
+			putchar('@');
+			if ((cp = print_cstring(cp, ep)) != NULL)
+				putchar('"');
+		}
+	}
+	return ((const struct atNBPtuple *)cp);
+}
+
+
+#define HASHNAMESIZE 4096
+
+struct hnamemem {
+	int addr;
+	char *name;
+	struct hnamemem *nxt;
+};
+
+static struct hnamemem hnametable[HASHNAMESIZE];
+
+static const char *
+ataddr_string(u_short atnet, u_char athost)
+{
+	register struct hnamemem *tp, *tp2;
+	register int i = (atnet << 8) | athost;
+	char nambuf[256];
+	static int first = 1;
+	FILE *fp;
+
+	/*
+	 * if this is the first call, see if there's an AppleTalk
+	 * number to name map file.
+	 */
+	if (first && (first = 0, !nflag)
+	    && (fp = fopen("/etc/atalk.names", "r"))) {
+		char line[256];
+		int i1, i2, i3;
+
+		while (fgets(line, sizeof(line), fp)) {
+			if (line[0] == '\n' || line[0] == 0 || line[0] == '#')
+				continue;
+			if (sscanf(line, "%d.%d.%d %s", &i1, &i2, &i3,
+				     nambuf) == 4)
+				/* got a hostname. */
+				i3 |= ((i1 << 8) | i2) << 8;
+			else if (sscanf(line, "%d.%d %s", &i1, &i2,
+					nambuf) == 3)
+				/* got a net name */
+				i3 = (((i1 << 8) | i2) << 8) | 255;
+			else
+				continue;
+
+			for (tp = &hnametable[i3 & (HASHNAMESIZE-1)];
+			     tp->nxt; tp = tp->nxt)
+				;
+			tp->addr = i3;
+			tp->nxt = newhnamemem();
+			tp->name = savestr(nambuf);
+		}
+		fclose(fp);
+	}
+
+	for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+		if (tp->addr == i)
+			return (tp->name);
+
+	/* didn't have the node name -- see if we've got the net name */
+	i |= 255;
+	for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt)
+		if (tp2->addr == i) {
+			tp->addr = (atnet << 8) | athost;
+			tp->nxt = newhnamemem();
+			(void)sprintf(nambuf, "%s.%d", tp2->name, athost);
+			tp->name = savestr(nambuf);
+			return (tp->name);
+		}
+
+	tp->addr = (atnet << 8) | athost;
+	tp->nxt = newhnamemem();
+	if (athost != 255)
+		(void)sprintf(nambuf, "%d.%d.%d",
+		    atnet >> 8, atnet & 0xff, athost);
+	else
+		(void)sprintf(nambuf, "%d.%d", atnet >> 8, atnet & 0xff);
+	tp->name = savestr(nambuf);
+
+	return (tp->name);
+}
+
+static struct tok skt2str[] = {
+	{ rtmpSkt,	"rtmp" },	/* routing table maintenance */
+	{ nbpSkt,	"nis" },	/* name info socket */
+	{ echoSkt,	"echo" },	/* AppleTalk echo protocol */
+	{ zipSkt,	"zip" },	/* zone info protocol */
+	{ 0,		NULL }
+};
+
+static const char *
+ddpskt_string(register int skt)
+{
+	static char buf[8];
+
+	if (nflag) {
+		(void)sprintf(buf, "%d", skt);
+		return (buf);
+	}
+	return (tok2str(skt2str, "%d", skt));
+}
diff --git a/tcpdump.tproj/print-atm.c b/tcpdump.tproj/print-atm.c
new file mode 100644
index 0000000..4abe2ad
--- /dev/null
+++ b/tcpdump.tproj/print-atm.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-atm.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "interface.h"
+
+/*
+ * This is the top level routine of the printer.  'p' is the points
+ * to the LLC/SNAP header of the packet, 'tvp' is the timestamp,
+ * 'length' is the length of the packet off the wire, and 'caplen'
+ * is the number of bytes actually captured.
+ */
+void
+atm_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+	u_int caplen = h->caplen;
+	u_int length = h->len;
+	u_short ethertype;
+
+	ts_print(&h->ts);
+
+	if (caplen < 8) {
+		printf("[|atm]");
+		goto out;
+	}
+	if (p[0] != 0xaa || p[1] != 0xaa || p[2] != 0x03) {
+		/*XXX assume 802.6 MAC header from fore driver */
+		if (eflag)
+			printf("%04x%04x %04x%04x ",
+			       p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3],
+			       p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7],
+			       p[8] << 24 | p[9] << 16 | p[10] << 8 | p[11],
+			       p[12] << 24 | p[13] << 16 | p[14] << 8 | p[15]);
+		p += 20;
+		length -= 20;
+		caplen -= 20;
+	}
+	ethertype = p[6] << 8 | p[7];
+	if (eflag)
+		printf("%02x %02x %02x %02x-%02x-%02x %04x: ",
+		       p[0], p[1], p[2], /* dsap/ssap/ctrl */
+		       p[3], p[4], p[5], /* manufacturer's code */
+		       ethertype);
+
+	/*
+	 * Some printers want to get back at the ethernet addresses,
+	 * and/or check that they're not walking off the end of the packet.
+	 * Rather than pass them all the way down, we set these globals.
+	 */
+	packetp = p;
+	snapend = p + caplen;
+
+	length -= 8;
+	caplen -= 8;
+	p += 8;
+
+	switch (ethertype) {
+
+	case ETHERTYPE_IP:
+		ip_print(p, length);
+		break;
+
+		/*XXX this probably isn't right */
+	case ETHERTYPE_ARP:
+	case ETHERTYPE_REVARP:
+		arp_print(p, length, caplen);
+		break;
+#ifdef notyet
+	case ETHERTYPE_DN:
+		decnet_print(p, length, caplen);
+		break;
+
+	case ETHERTYPE_ATALK:
+		if (vflag)
+			fputs("et1 ", stdout);
+		atalk_print(p, length);
+		break;
+
+	case ETHERTYPE_AARP:
+		aarp_print(p, length);
+		break;
+
+	case ETHERTYPE_LAT:
+	case ETHERTYPE_MOPRC:
+	case ETHERTYPE_MOPDL:
+		/* default_print for now */
+#endif
+	default:
+		/* ether_type not known, print raw packet */
+		if (!eflag)
+			printf("%02x %02x %02x %02x-%02x-%02x %04x: ",
+			       p[0], p[1], p[2], /* dsap/ssap/ctrl */
+			       p[3], p[4], p[5], /* manufacturer's code */
+			       ethertype);
+		if (!xflag && !qflag)
+			default_print(p, caplen);
+	}
+	if (xflag)
+		default_print(p, caplen);
+ out:
+	putchar('\n');
+}
diff --git a/tcpdump.tproj/print-bootp.c b/tcpdump.tproj/print-bootp.c
new file mode 100644
index 0000000..c938728
--- /dev/null
+++ b/tcpdump.tproj/print-bootp.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print bootp packets.
+ */
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-bootp.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "bootp.h"
+
+static void rfc1048_print(const u_char *, u_int);
+static void cmu_print(const u_char *, u_int);
+
+static char tstr[] = " [|bootp]";
+
+/*
+ * Print bootp requests
+ */
+void
+bootp_print(register const u_char *cp, u_int length,
+	    u_short sport, u_short dport)
+{
+	register const struct bootp *bp;
+	static u_char vm_cmu[4] = VM_CMU;
+	static u_char vm_rfc1048[4] = VM_RFC1048;
+
+	bp = (struct bootp *)cp;
+	TCHECK(bp->bp_op);
+	switch (bp->bp_op) {
+
+	case BOOTREQUEST:
+		/* Usually, a request goes from a client to a server */
+		if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS)
+			printf(" (request)");
+		break;
+
+	case BOOTREPLY:
+		/* Usually, a reply goes from a server to a client */
+		if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC)
+			printf(" (reply)");
+		break;
+
+	default:
+		printf(" bootp-#%d", bp->bp_op);
+	}
+
+	TCHECK(bp->bp_secs);
+
+	/* The usual hardware address type is 1 (10Mb Ethernet) */
+	if (bp->bp_htype != 1)
+		printf(" htype-#%d", bp->bp_htype);
+
+	/* The usual length for 10Mb Ethernet address is 6 bytes */
+	if (bp->bp_htype != 1 || bp->bp_hlen != 6)
+		printf(" hlen:%d", bp->bp_hlen);
+
+	/* Only print interesting fields */
+	if (bp->bp_hops)
+		printf(" hops:%d", bp->bp_hops);
+	if (bp->bp_xid)
+		printf(" xid:0x%x", (u_int32_t)ntohl(bp->bp_xid));
+	if (bp->bp_secs)
+		printf(" secs:%d", ntohs(bp->bp_secs));
+
+	/* Client's ip address */
+	TCHECK(bp->bp_ciaddr);
+	if (bp->bp_ciaddr.s_addr)
+		printf(" C:%s", ipaddr_string(&bp->bp_ciaddr));
+
+	/* 'your' ip address (bootp client) */
+	TCHECK(bp->bp_yiaddr);
+	if (bp->bp_yiaddr.s_addr)
+		printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr));
+
+	/* Server's ip address */
+	TCHECK(bp->bp_siaddr);
+	if (bp->bp_siaddr.s_addr)
+		printf(" S:%s", ipaddr_string(&bp->bp_siaddr));
+
+	/* Gateway's ip address */
+	TCHECK(bp->bp_giaddr);
+	if (bp->bp_giaddr.s_addr)
+		printf(" G:%s", ipaddr_string(&bp->bp_giaddr));
+
+	/* Client's Ethernet address */
+	if (bp->bp_htype == 1 && bp->bp_hlen == 6) {
+		register const struct ether_header *eh;
+		register const char *e;
+
+		TCHECK2(bp->bp_chaddr[0], 6);
+		eh = (struct ether_header *)packetp;
+		if (bp->bp_op == BOOTREQUEST)
+			e = (const char *)ESRC(eh);
+		else if (bp->bp_op == BOOTREPLY)
+			e = (const char *)EDST(eh);
+		else
+			e = 0;
+		if (e == 0 || memcmp((char *)bp->bp_chaddr, e, 6) != 0)
+			printf(" ether %s", etheraddr_string(bp->bp_chaddr));
+	}
+
+	TCHECK2(bp->bp_sname[0], 1);		/* check first char only */
+	if (*bp->bp_sname) {
+		printf(" sname \"");
+		if (fn_print(bp->bp_sname, snapend)) {
+			putchar('"');
+			fputs(tstr + 1, stdout);
+			return;
+		}
+	}
+	TCHECK2(bp->bp_sname[0], 1);		/* check first char only */
+	if (*bp->bp_file) {
+		printf(" file \"");
+		if (fn_print(bp->bp_file, snapend)) {
+			putchar('"');
+			fputs(tstr + 1, stdout);
+			return;
+		}
+	}
+
+	/* Decode the vendor buffer */
+	TCHECK(bp->bp_vend[0]);
+	length -= sizeof(*bp) - sizeof(bp->bp_vend);
+	if (memcmp((char *)bp->bp_vend, (char *)vm_rfc1048,
+		 sizeof(u_int32_t)) == 0)
+		rfc1048_print(bp->bp_vend, length);
+	else if (memcmp((char *)bp->bp_vend, (char *)vm_cmu,
+		      sizeof(u_int32_t)) == 0)
+		cmu_print(bp->bp_vend, length);
+	else {
+		u_int32_t ul;
+
+		memcpy((char *)&ul, (char *)bp->bp_vend, sizeof(ul));
+		if (ul != 0)
+			printf("vend-#0x%x", ul);
+	}
+
+	return;
+trunc:
+	fputs(tstr, stdout);
+}
+
+/* The first character specifies the format to print */
+static struct tok tag2str[] = {
+/* RFC1048 tags */
+	{ TAG_PAD,		" PAD" },
+	{ TAG_SUBNET_MASK,	"iSM" },	/* subnet mask (RFC950) */
+	{ TAG_TIME_OFFSET,	"lTZ" },	/* seconds from UTC */
+	{ TAG_GATEWAY,		"iDG" },	/* default gateway */
+	{ TAG_TIME_SERVER,	"iTS" },	/* time servers (RFC868) */
+	{ TAG_NAME_SERVER,	"iIEN" },	/* IEN name servers (IEN116) */
+	{ TAG_DOMAIN_SERVER,	"iNS" },	/* domain name (RFC1035) */
+	{ TAG_LOG_SERVER,	"iLOG" },	/* MIT log servers */
+	{ TAG_COOKIE_SERVER,	"iCS" },	/* cookie servers (RFC865) */
+	{ TAG_LPR_SERVER,	"iLPR" },	/* lpr server (RFC1179) */
+	{ TAG_IMPRESS_SERVER,	"iIM" },	/* impress servers (Imagen) */
+	{ TAG_RLP_SERVER,	"iRL" },	/* resource location (RFC887) */
+	{ TAG_HOSTNAME,		"aHN" },	/* ascii hostname */
+	{ TAG_BOOTSIZE,		"sBS" },	/* 512 byte blocks */
+	{ TAG_END,		" END" },
+/* RFC1497 tags */
+	{ TAG_DUMPPATH,		"aDP" },
+	{ TAG_DOMAINNAME,	"aDN" },
+	{ TAG_SWAP_SERVER,	"iSS" },
+	{ TAG_ROOTPATH,		"aRP" },
+	{ TAG_EXTPATH,		"aEP" },
+	{ 0,			NULL }
+};
+
+static void
+rfc1048_print(register const u_char *bp, register u_int length)
+{
+	register u_char tag;
+	register u_int len, size;
+	register const char *cp;
+	register char c;
+	int first;
+	u_int32_t ul;
+	u_short us;
+
+	printf(" vend-rfc1048");
+
+	/* Step over magic cookie */
+	bp += sizeof(int32_t);
+
+	/* Loop while we there is a tag left in the buffer */
+	while (bp + 1 < snapend) {
+		tag = *bp++;
+		if (tag == TAG_PAD)
+			continue;
+		if (tag == TAG_END)
+			return;
+		cp = tok2str(tag2str, "?T%d", tag);
+		c = *cp++;
+		printf(" %s:", cp);
+
+		/* Get the length; check for truncation */
+		if (bp + 1 >= snapend) {
+			fputs(tstr, stdout);
+			return;
+		}
+		len = *bp++;
+		if (bp + len >= snapend) {
+			fputs(tstr, stdout);
+			return;
+		}
+
+		/* Print data */
+		size = len;
+		if (c == '?') {
+			/* Base default formats for unknown tags on data size */
+			if (size & 1)
+				c = 'b';
+			else if (size & 2)
+				c = 's';
+			else
+				c = 'l';
+		}
+		first = 1;
+		switch (c) {
+
+		case 'a':
+			/* ascii strings */
+			putchar('"');
+			(void)fn_printn(bp, size, NULL);
+			putchar('"');
+			bp += size;
+			size = 0;
+			break;
+
+		case 'i':
+		case 'l':
+			/* ip addresses/32-bit words */
+			while (size >= sizeof(ul)) {
+				if (!first)
+					putchar(',');
+				memcpy((char *)&ul, (char *)bp, sizeof(ul));
+				if (c == 'i')
+					printf("%s", ipaddr_string(&ul));
+				else
+					printf("%u", ul);
+				bp += sizeof(ul);
+				size -= sizeof(ul);
+				first = 0;
+			}
+			break;
+
+		case 's':
+			/* shorts */
+			while (size >= sizeof(us)) {
+				if (!first)
+					putchar(',');
+				memcpy((char *)&us, (char *)bp, sizeof(us));
+				printf("%d", us);
+				bp += sizeof(us);
+				size -= sizeof(us);
+				first = 0;
+			}
+			break;
+
+		case 'b':
+		default:
+			/* Bytes */
+			while (size > 0) {
+				if (!first)
+					putchar('.');
+				printf("%d", *bp);
+				++bp;
+				--size;
+				first = 0;
+			}
+			break;
+		}
+		/* Data left over? */
+		if (size)
+			printf("[len %d]", len);
+	}
+}
+
+static void
+cmu_print(register const u_char *bp, register u_int length)
+{
+	register const struct cmu_vend *cmu;
+	char *fmt = " %s:%s";
+
+#define PRINTCMUADDR(m, s) { TCHECK(cmu->m); \
+    if (cmu->m.s_addr != 0) \
+	printf(fmt, s, ipaddr_string(&cmu->m.s_addr)); }
+
+	printf(" vend-cmu");
+	cmu = (struct cmu_vend *)bp;
+
+	/* Only print if there are unknown bits */
+	TCHECK(cmu->v_flags);
+	if ((cmu->v_flags & ~(VF_SMASK)) != 0)
+		printf(" F:0x%x", cmu->v_flags);
+	PRINTCMUADDR(v_dgate, "DG");
+	PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*");
+	PRINTCMUADDR(v_dns1, "NS1");
+	PRINTCMUADDR(v_dns2, "NS2");
+	PRINTCMUADDR(v_ins1, "IEN1");
+	PRINTCMUADDR(v_ins2, "IEN2");
+	PRINTCMUADDR(v_ts1, "TS1");
+	PRINTCMUADDR(v_ts2, "TS2");
+	return;
+
+trunc:
+	fputs(tstr, stdout);
+#undef PRINTCMUADDR
+}
diff --git a/tcpdump.tproj/print-decnet.c b/tcpdump.tproj/print-decnet.c
new file mode 100644
index 0000000..a65152e
--- /dev/null
+++ b/tcpdump.tproj/print-decnet.c
@@ -0,0 +1,798 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-decnet.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#ifdef	HAVE_LIBDNET
+#include <netdnet/dnetdb.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "decnet.h"
+#include "extract.h"
+#include "interface.h"
+#include "addrtoname.h"
+
+/* Forwards */
+static void print_decnet_ctlmsg(const union routehdr *, u_int);
+static void print_t_info(int);
+static void print_l1_routes(const char *, u_int);
+static void print_l2_routes(const char *, u_int);
+static void print_i_info(int);
+static void print_elist(const char *, u_int);
+static void print_nsp(const u_char *, u_int);
+static void print_reason(int);
+#ifdef	PRINT_NSPDATA
+static void pdata(u_char *, int);
+#endif
+
+#ifdef	HAVE_LIBDNET
+extern char *dnet_htoa(struct dn_naddr *);
+#endif
+
+void
+decnet_print(register const u_char *ap, register u_int length,
+	     register u_int caplen)
+{
+	static union routehdr rhcopy;
+	register union routehdr *rhp = &rhcopy;
+	register int mflags;
+	int dst, src, hops;
+	u_int rhlen, nsplen, pktlen;
+	const u_char *nspp;
+
+	if (length < sizeof(struct shorthdr)) {
+		(void)printf("[|decnet]");
+		return;
+	}
+
+	pktlen = EXTRACT_LE_16BITS(ap);
+
+	rhlen = min(length, caplen);
+	rhlen = min(rhlen, sizeof(*rhp));
+	memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
+
+	mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
+
+	if (mflags & RMF_PAD) {
+	    /* pad bytes of some sort in front of message */
+	    u_int padlen = mflags & RMF_PADMASK;
+	    if (vflag)
+		(void) printf("[pad:%d] ", padlen);
+	    ap += padlen;
+	    length -= padlen;
+	    caplen -= padlen;
+	    rhlen = min(length, caplen);
+	    rhlen = min(rhlen, sizeof(*rhp));
+	    memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
+	    mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
+	}
+
+	if (mflags & RMF_FVER) {
+		(void) printf("future-version-decnet");
+		default_print(ap, length);
+		return;
+	}
+
+	/* is it a control message? */
+	if (mflags & RMF_CTLMSG) {
+		print_decnet_ctlmsg(rhp, min(length, caplen));
+		return;
+	}
+
+	switch (mflags & RMF_MASK) {
+	case RMF_LONG:
+	    dst =
+		EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
+	    src =
+		EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
+	    hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits);
+	    nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
+	    nsplen = min((length - sizeof(struct longhdr)),
+			 (caplen - sizeof(struct longhdr)));
+	    break;
+	case RMF_SHORT:
+	    dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst);
+	    src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src);
+	    hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
+	    nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
+	    nsplen = min((length - sizeof(struct shorthdr)),
+			 (caplen - sizeof(struct shorthdr)));
+	    break;
+	default:
+	    (void) printf("unknown message flags under mask");
+	    default_print((u_char *)ap, length);
+	    return;
+	}
+
+	(void)printf("%s > %s %d ",
+			dnaddr_string(src), dnaddr_string(dst), pktlen);
+	if (vflag) {
+	    if (mflags & RMF_RQR)
+		(void)printf("RQR ");
+	    if (mflags & RMF_RTS)
+		(void)printf("RTS ");
+	    if (mflags & RMF_IE)
+		(void)printf("IE ");
+	    (void)printf("%d hops ", hops);
+	}
+
+	print_nsp(nspp, nsplen);
+}
+
+static void
+print_decnet_ctlmsg(register const union routehdr *rhp, u_int length)
+{
+	int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
+	register union controlmsg *cmp = (union controlmsg *)rhp;
+	int src, dst, info, blksize, eco, ueco, hello, other, vers;
+	etheraddr srcea, rtea;
+	int priority;
+	char *rhpx = (char *)rhp;
+
+	switch (mflags & RMF_CTLMASK) {
+	case RMF_INIT:
+	    (void)printf("init ");
+	    src = EXTRACT_LE_16BITS(cmp->cm_init.in_src);
+	    info = EXTRACT_LE_8BITS(cmp->cm_init.in_info);
+	    blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize);
+	    vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers);
+	    eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco);
+	    ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco);
+	    hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello);
+	    print_t_info(info);
+	    (void)printf(
+		"src %sblksize %d vers %d eco %d ueco %d hello %d",
+			dnaddr_string(src), blksize, vers, eco, ueco,
+			hello);
+	    break;
+	case RMF_VER:
+	    (void)printf("verification ");
+	    src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src);
+	    other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval);
+	    (void)printf("src %s fcnval %o", dnaddr_string(src), other);
+	    break;
+	case RMF_TEST:
+	    (void)printf("test ");
+	    src = EXTRACT_LE_16BITS(cmp->cm_test.te_src);
+	    other = EXTRACT_LE_8BITS(cmp->cm_test.te_data);
+	    (void)printf("src %s data %o", dnaddr_string(src), other);
+	    break;
+	case RMF_L1ROUT:
+	    (void)printf("lev-1-routing ");
+	    src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src);
+	    (void)printf("src %s ", dnaddr_string(src));
+	    print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
+				length - sizeof(struct l1rout));
+	    break;
+	case RMF_L2ROUT:
+	    (void)printf("lev-2-routing ");
+	    src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src);
+	    (void)printf("src %s ", dnaddr_string(src));
+	    print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
+				length - sizeof(struct l2rout));
+	    break;
+	case RMF_RHELLO:
+	    (void)printf("router-hello ");
+	    vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers);
+	    eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco);
+	    ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco);
+	    memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src),
+		sizeof(srcea));
+	    src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
+	    info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info);
+	    blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize);
+	    priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority);
+	    hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello);
+	    print_i_info(info);
+	    (void)printf(
+	    "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
+			vers, eco, ueco, dnaddr_string(src),
+			blksize, priority, hello);
+	    print_elist(&(rhpx[sizeof(struct rhellomsg)]),
+				length - sizeof(struct rhellomsg));
+	    break;
+	case RMF_EHELLO:
+	    (void)printf("endnode-hello ");
+	    vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers);
+	    eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco);
+	    ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco);
+	    memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src),
+		sizeof(srcea));
+	    src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
+	    info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info);
+	    blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize);
+	    /*seed*/
+	    memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router),
+		sizeof(rtea));
+	    dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr);
+	    hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello);
+	    other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data);
+	    print_i_info(info);
+	    (void)printf(
+	"vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
+			vers, eco, ueco, dnaddr_string(src),
+			blksize, dnaddr_string(dst), hello, other);
+	    break;
+
+	default:
+	    (void)printf("unknown control message");
+	    default_print((u_char *)rhp, length);
+	    break;
+	}
+}
+
+static void
+print_t_info(int info)
+{
+	int ntype = info & 3;
+	switch (ntype) {
+	case 0: (void)printf("reserved-ntype? "); break;
+	case TI_L2ROUT: (void)printf("l2rout "); break;
+	case TI_L1ROUT: (void)printf("l1rout "); break;
+	case TI_ENDNODE: (void)printf("endnode "); break;
+	}
+	if (info & TI_VERIF)
+	    (void)printf("verif ");
+	if (info & TI_BLOCK)
+	    (void)printf("blo ");
+}
+
+static void
+print_l1_routes(const char *rp, u_int len)
+{
+	int count;
+	int id;
+	int info;
+
+	/* The last short is a checksum */
+	while (len > (3 * sizeof(short))) {
+	    count = EXTRACT_LE_16BITS(rp);
+	    if (count > 1024)
+		return;	/* seems to be bogus from here on */
+	    rp += sizeof(short);
+	    len -= sizeof(short);
+	    id = EXTRACT_LE_16BITS(rp);
+	    rp += sizeof(short);
+	    len -= sizeof(short);
+	    info = EXTRACT_LE_16BITS(rp);
+	    rp += sizeof(short);
+	    len -= sizeof(short);
+	    (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
+			    RI_COST(info), RI_HOPS(info));
+	}
+}
+
+static void
+print_l2_routes(const char *rp, u_int len)
+{
+	int count;
+	int area;
+	int info;
+
+	/* The last short is a checksum */
+	while (len > (3 * sizeof(short))) {
+	    count = EXTRACT_LE_16BITS(rp);
+	    if (count > 1024)
+		return;	/* seems to be bogus from here on */
+	    rp += sizeof(short);
+	    len -= sizeof(short);
+	    area = EXTRACT_LE_16BITS(rp);
+	    rp += sizeof(short);
+	    len -= sizeof(short);
+	    info = EXTRACT_LE_16BITS(rp);
+	    rp += sizeof(short);
+	    len -= sizeof(short);
+	    (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
+			    RI_COST(info), RI_HOPS(info));
+	}
+}
+
+static void
+print_i_info(int info)
+{
+	int ntype = info & II_TYPEMASK;
+	switch (ntype) {
+	case 0: (void)printf("reserved-ntype? "); break;
+	case II_L2ROUT: (void)printf("l2rout "); break;
+	case II_L1ROUT: (void)printf("l1rout "); break;
+	case II_ENDNODE: (void)printf("endnode "); break;
+	}
+	if (info & II_VERIF)
+	    (void)printf("verif ");
+	if (info & II_NOMCAST)
+	    (void)printf("nomcast ");
+	if (info & II_BLOCK)
+	    (void)printf("blo ");
+}
+
+static void
+print_elist(const char *elp, u_int len)
+{
+	/* Not enough examples available for me to debug this */
+}
+
+static void
+print_nsp(const u_char *nspp, u_int nsplen)
+{
+	const struct nsphdr *nsphp = (struct nsphdr *)nspp;
+	int dst, src, flags;
+
+	flags = EXTRACT_LE_8BITS(nsphp->nh_flags);
+	dst = EXTRACT_LE_16BITS(nsphp->nh_dst);
+	src = EXTRACT_LE_16BITS(nsphp->nh_src);
+
+	switch (flags & NSP_TYPEMASK) {
+	case MFT_DATA:
+	    switch (flags & NSP_SUBMASK) {
+	    case MFS_BOM:
+	    case MFS_MOM:
+	    case MFS_EOM:
+	    case MFS_BOM+MFS_EOM:
+		printf("data %d>%d ", src, dst);
+		{
+		    struct seghdr *shp = (struct seghdr *)nspp;
+		    int ack;
+#ifdef	PRINT_NSPDATA
+		    u_char *dp;
+#endif
+		    u_int data_off = sizeof(struct minseghdr);
+
+		    ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
+		    if (ack & SGQ_ACK) {	/* acknum field */
+			if ((ack & SGQ_NAK) == SGQ_NAK)
+			    (void)printf("nak %d ", ack & SGQ_MASK);
+			else
+			    (void)printf("ack %d ", ack & SGQ_MASK);
+		        ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
+			data_off += sizeof(short);
+			if (ack & SGQ_OACK) {	/* ackoth field */
+			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
+				(void)printf("onak %d ", ack & SGQ_MASK);
+			    else
+				(void)printf("oack %d ", ack & SGQ_MASK);
+			    ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
+			    data_off += sizeof(short);
+			}
+		    }
+		    (void)printf("seg %d ", ack & SGQ_MASK);
+#ifdef	PRINT_NSPDATA
+		    dp = &(nspp[data_off]);
+		    pdata(dp, 10);
+#endif
+		}
+		break;
+	    case MFS_ILS+MFS_INT:
+		printf("intr ");
+		{
+		    struct seghdr *shp = (struct seghdr *)nspp;
+		    int ack;
+#ifdef	PRINT_NSPDATA
+		    u_char *dp;
+#endif
+		    u_int data_off = sizeof(struct minseghdr);
+
+		    ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
+		    if (ack & SGQ_ACK) {	/* acknum field */
+			if ((ack & SGQ_NAK) == SGQ_NAK)
+			    (void)printf("nak %d ", ack & SGQ_MASK);
+			else
+			    (void)printf("ack %d ", ack & SGQ_MASK);
+		        ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
+			data_off += sizeof(short);
+			if (ack & SGQ_OACK) {	/* ackdat field */
+			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
+				(void)printf("nakdat %d ", ack & SGQ_MASK);
+			    else
+				(void)printf("ackdat %d ", ack & SGQ_MASK);
+			    ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
+			    data_off += sizeof(short);
+			}
+		    }
+		    (void)printf("seg %d ", ack & SGQ_MASK);
+#ifdef	PRINT_NSPDATA
+		    dp = &(nspp[data_off]);
+		    pdata(dp, 10);
+#endif
+		}
+		break;
+	    case MFS_ILS:
+		(void)printf("link-service %d>%d ", src, dst);
+		{
+		    struct seghdr *shp = (struct seghdr *)nspp;
+		    struct lsmsg *lsmp =
+			(struct lsmsg *)&(nspp[sizeof(struct seghdr)]);
+		    int ack;
+		    int lsflags, fcval;
+
+		    ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
+		    if (ack & SGQ_ACK) {	/* acknum field */
+			if ((ack & SGQ_NAK) == SGQ_NAK)
+			    (void)printf("nak %d ", ack & SGQ_MASK);
+			else
+			    (void)printf("ack %d ", ack & SGQ_MASK);
+		        ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
+			if (ack & SGQ_OACK) {	/* ackdat field */
+			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
+				(void)printf("nakdat %d ", ack & SGQ_MASK);
+			    else
+				(void)printf("ackdat %d ", ack & SGQ_MASK);
+			    ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
+			}
+		    }
+		    (void)printf("seg %d ", ack & SGQ_MASK);
+		    lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags);
+		    fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval);
+		    switch (lsflags & LSI_MASK) {
+		    case LSI_DATA:
+			(void)printf("dat seg count %d ", fcval);
+			switch (lsflags & LSM_MASK) {
+			case LSM_NOCHANGE:
+			    break;
+			case LSM_DONOTSEND:
+			    (void)printf("donotsend-data ");
+			    break;
+			case LSM_SEND:
+			    (void)printf("send-data ");
+			    break;
+			default:
+			    (void)printf("reserved-fcmod? %x", lsflags);
+			    break;
+			}
+			break;
+		    case LSI_INTR:
+			(void)printf("intr req count %d ", fcval);
+			break;
+		    default:
+			(void)printf("reserved-fcval-int? %x", lsflags);
+			break;
+		    }
+		}
+		break;
+	    default:
+		(void)printf("reserved-subtype? %x %d > %d", flags, src, dst);
+		break;
+	    }
+	    break;
+	case MFT_ACK:
+	    switch (flags & NSP_SUBMASK) {
+	    case MFS_DACK:
+		(void)printf("data-ack %d>%d ", src, dst);
+		{
+		    struct ackmsg *amp = (struct ackmsg *)nspp;
+		    int ack;
+
+		    ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
+		    if (ack & SGQ_ACK) {	/* acknum field */
+			if ((ack & SGQ_NAK) == SGQ_NAK)
+			    (void)printf("nak %d ", ack & SGQ_MASK);
+			else
+			    (void)printf("ack %d ", ack & SGQ_MASK);
+		        ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
+			if (ack & SGQ_OACK) {	/* ackoth field */
+			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
+				(void)printf("onak %d ", ack & SGQ_MASK);
+			    else
+				(void)printf("oack %d ", ack & SGQ_MASK);
+			}
+		    }
+		}
+		break;
+	    case MFS_IACK:
+		(void)printf("ils-ack %d>%d ", src, dst);
+		{
+		    struct ackmsg *amp = (struct ackmsg *)nspp;
+		    int ack;
+
+		    ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
+		    if (ack & SGQ_ACK) {	/* acknum field */
+			if ((ack & SGQ_NAK) == SGQ_NAK)
+			    (void)printf("nak %d ", ack & SGQ_MASK);
+			else
+			    (void)printf("ack %d ", ack & SGQ_MASK);
+		        ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
+			if (ack & SGQ_OACK) {	/* ackdat field */
+			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
+				(void)printf("nakdat %d ", ack & SGQ_MASK);
+			    else
+				(void)printf("ackdat %d ", ack & SGQ_MASK);
+			}
+		    }
+		}
+		break;
+	    case MFS_CACK:
+		(void)printf("conn-ack %d", dst);
+		break;
+	    default:
+		(void)printf("reserved-acktype? %x %d > %d", flags, src, dst);
+		break;
+	    }
+	    break;
+	case MFT_CTL:
+	    switch (flags & NSP_SUBMASK) {
+	    case MFS_CI:
+	    case MFS_RCI:
+		if ((flags & NSP_SUBMASK) == MFS_CI)
+		    (void)printf("conn-initiate ");
+		else
+		    (void)printf("retrans-conn-initiate ");
+		(void)printf("%d>%d ", src, dst);
+		{
+		    struct cimsg *cimp = (struct cimsg *)nspp;
+		    int services, info, segsize;
+#ifdef	PRINT_NSPDATA
+		    u_char *dp;
+#endif
+
+		    services = EXTRACT_LE_8BITS(cimp->ci_services);
+		    info = EXTRACT_LE_8BITS(cimp->ci_info);
+		    segsize = EXTRACT_LE_16BITS(cimp->ci_segsize);
+
+		    switch (services & COS_MASK) {
+		    case COS_NONE:
+			break;
+		    case COS_SEGMENT:
+			(void)printf("seg ");
+			break;
+		    case COS_MESSAGE:
+			(void)printf("msg ");
+			break;
+		    case COS_CRYPTSER:
+			(void)printf("crypt ");
+			break;
+		    }
+		    switch (info & COI_MASK) {
+		    case COI_32:
+			(void)printf("ver 3.2 ");
+			break;
+		    case COI_31:
+			(void)printf("ver 3.1 ");
+			break;
+		    case COI_40:
+			(void)printf("ver 4.0 ");
+			break;
+		    case COI_41:
+			(void)printf("ver 4.1 ");
+			break;
+		    }
+		    (void)printf("segsize %d ", segsize);
+#ifdef	PRINT_NSPDATA
+		    dp = &(nspp[sizeof(struct cimsg)]);
+		    pdata(dp, nsplen - sizeof(struct cimsg));
+#endif
+		}
+		break;
+	    case MFS_CC:
+		(void)printf("conn-confirm %d>%d ", src, dst);
+		{
+		    struct ccmsg *ccmp = (struct ccmsg *)nspp;
+		    int services, info;
+		    u_int segsize, optlen;
+#ifdef	PRINT_NSPDATA
+		    u_char *dp;
+#endif
+
+		    services = EXTRACT_LE_8BITS(ccmp->cc_services);
+		    info = EXTRACT_LE_8BITS(ccmp->cc_info);
+		    segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize);
+		    optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen);
+
+		    switch (services & COS_MASK) {
+		    case COS_NONE:
+			break;
+		    case COS_SEGMENT:
+			(void)printf("seg ");
+			break;
+		    case COS_MESSAGE:
+			(void)printf("msg ");
+			break;
+		    case COS_CRYPTSER:
+			(void)printf("crypt ");
+			break;
+		    }
+		    switch (info & COI_MASK) {
+		    case COI_32:
+			(void)printf("ver 3.2 ");
+			break;
+		    case COI_31:
+			(void)printf("ver 3.1 ");
+			break;
+		    case COI_40:
+			(void)printf("ver 4.0 ");
+			break;
+		    case COI_41:
+			(void)printf("ver 4.1 ");
+			break;
+		    }
+		    (void)printf("segsize %d ", segsize);
+		    if (optlen) {
+			(void)printf("optlen %d ", optlen);
+#ifdef	PRINT_NSPDATA
+			optlen = min(optlen, nsplen - sizeof(struct ccmsg));
+			dp = &(nspp[sizeof(struct ccmsg)]);
+			pdata(dp, optlen);
+#endif
+		    }
+		}
+		break;
+	    case MFS_DI:
+		(void)printf("disconn-initiate %d>%d ", src, dst);
+		{
+		    struct dimsg *dimp = (struct dimsg *)nspp;
+		    int reason;
+		    u_int optlen;
+#ifdef	PRINT_NSPDATA
+		    u_char *dp;
+#endif
+
+		    reason = EXTRACT_LE_16BITS(dimp->di_reason);
+		    optlen = EXTRACT_LE_8BITS(dimp->di_optlen);
+
+		    print_reason(reason);
+		    if (optlen) {
+			(void)printf("optlen %d ", optlen);
+#ifdef	PRINT_NSPDATA
+			optlen = min(optlen, nsplen - sizeof(struct dimsg));
+			dp = &(nspp[sizeof(struct dimsg)]);
+			pdata(dp, optlen);
+#endif
+		    }
+		}
+		break;
+	    case MFS_DC:
+		(void)printf("disconn-confirm %d>%d ", src, dst);
+		{
+		    struct dcmsg *dcmp = (struct dcmsg *)nspp;
+		    int reason;
+
+		    reason = EXTRACT_LE_16BITS(dcmp->dc_reason);
+
+		    print_reason(reason);
+		}
+		break;
+	    default:
+		(void)printf("reserved-ctltype? %x %d > %d", flags, src, dst);
+		break;
+	    }
+	    break;
+	default:
+	    (void)printf("reserved-type? %x %d > %d", flags, src, dst);
+	    break;
+	}
+}
+
+static struct tok reason2str[] = {
+	{ UC_OBJREJECT,		"object rejected connect" },
+	{ UC_RESOURCES,		"insufficient resources" },
+	{ UC_NOSUCHNODE,	"unrecognized node name" },
+	{ DI_SHUT,		"node is shutting down" },
+	{ UC_NOSUCHOBJ,		"unrecognized object" },
+	{ UC_INVOBJFORMAT,	"invalid object name format" },
+	{ UC_OBJTOOBUSY,	"object too busy" },
+	{ DI_PROTOCOL,		"protocol error discovered" },
+	{ DI_TPA,		"third party abort" },
+	{ UC_USERABORT,		"user abort" },
+	{ UC_INVNODEFORMAT,	"invalid node name format" },
+	{ UC_LOCALSHUT,		"local node shutting down" },
+	{ DI_LOCALRESRC,	"insufficient local resources" },
+	{ DI_REMUSERRESRC,	"insufficient remote user resources" },
+	{ UC_ACCESSREJECT,	"invalid access control information" },
+	{ DI_BADACCNT,		"bad ACCOUNT information" },
+	{ UC_NORESPONSE,	"no response from object" },
+	{ UC_UNREACHABLE,	"node unreachable" },
+	{ DC_NOLINK,		"no link terminate" },
+	{ DC_COMPLETE,		"disconnect complete" },
+	{ DI_BADIMAGE,		"bad image data in connect" },
+	{ DI_SERVMISMATCH,	"cryptographic service mismatch" },
+	{ 0,			NULL }
+};
+
+static void
+print_reason(register int reason)
+{
+	printf("%s ", tok2str(reason2str, "reason-%d", reason));
+}
+
+char *
+dnnum_string(u_short dnaddr)
+{
+	char *str;
+	int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT;
+	int node = dnaddr & NODEMASK;
+
+	str = (char *)malloc(sizeof("00.0000"));
+	if (str == NULL)
+		error("dnnum_string: malloc");
+	sprintf(str, "%d.%d", area, node);
+	return(str);
+}
+
+char *
+dnname_string(u_short dnaddr)
+{
+#ifdef	HAVE_LIBDNET
+	struct dn_naddr dna;
+
+	dna.a_len = sizeof(short);
+	memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short));
+	return (savestr(dnet_htoa(&dna)));
+#else
+	return(dnnum_string(dnaddr));	/* punt */
+#endif
+}
+
+#ifdef	PRINT_NSPDATA
+static void
+pdata(u_char *dp, u_int maxlen)
+{
+	char c;
+	u_int x = maxlen;
+
+	while (x-- > 0) {
+	    c = *dp++;
+	    if (isprint(c))
+		putchar(c);
+	    else
+		printf("\\%o", c & 0xFF);
+	}
+}
+#endif
diff --git a/tcpdump.tproj/print-domain.c b/tcpdump.tproj/print-domain.c
new file mode 100644
index 0000000..c6175ae
--- /dev/null
+++ b/tcpdump.tproj/print-domain.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-domain.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#undef NOERROR					/* Solaris sucks */
+#undef T_UNSPEC					/* SINIX does too */
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"                    /* must come after interface.h */
+
+/* Compatibility */
+#ifndef T_TXT
+#define T_TXT		16		/* text strings */
+#endif
+#ifndef T_RP
+#define T_RP		17		/* responsible person */
+#endif
+#ifndef T_AFSDB
+#define T_AFSDB		18		/* AFS cell database */
+#endif
+#ifndef T_X25
+#define T_X25		19		/* X_25 calling address */
+#endif
+#ifndef T_ISDN
+#define T_ISDN		20		/* ISDN calling address */
+#endif
+#ifndef T_RT
+#define T_RT		21		/* router */
+#endif
+#ifndef T_NSAP
+#define T_NSAP		22		/* NSAP address */
+#endif
+#ifndef T_NSAP_PTR
+#define T_NSAP_PTR	23		/* reverse NSAP lookup (deprecated) */
+#endif
+#ifndef T_SIG
+#define T_SIG		24		/* security signature */
+#endif
+#ifndef T_KEY
+#define T_KEY		25		/* security key */
+#endif
+#ifndef T_PX
+#define T_PX		26		/* X.400 mail mapping */
+#endif
+#ifndef T_GPOS
+#define T_GPOS		27		/* geographical position (withdrawn) */
+#endif
+#ifndef T_AAAA
+#define T_AAAA		28		/* IP6 Address */
+#endif
+#ifndef T_LOC
+#define T_LOC		29		/* Location Information */
+#endif
+
+#ifndef T_UNSPEC
+#define T_UNSPEC	103		/* Unspecified format (binary data) */
+#endif
+#ifndef T_UNSPECA
+#define T_UNSPECA	104		/* "unspecified ascii". Ugly MIT hack */
+#endif
+
+#ifndef C_CHAOS
+#define C_CHAOS		3		/* for chaos net (MIT) */
+#endif
+#ifndef C_HS
+#define C_HS		4		/* for Hesiod name server (MIT) (XXX) */
+#endif
+
+static char *ns_ops[] = {
+	"", " inv_q", " stat", " op3", " notify", " op5", " op6", " op7",
+	" op8", " updataA", " updateD", " updateDA",
+	" updateM", " updateMA", " zoneInit", " zoneRef",
+};
+
+static char *ns_resp[] = {
+	"", " FormErr", " ServFail", " NXDomain",
+	" NotImp", " Refused", " Resp6", " Resp7",
+	" Resp8", " Resp9", " Resp10", " Resp11",
+	" Resp12", " Resp13", " Resp14", " NoChange",
+};
+
+/* skip over a domain name */
+static const u_char *
+ns_nskip(register const u_char *cp, register const u_char *bp)
+{
+	register u_char i;
+
+	if (((i = *cp++) & INDIR_MASK) == INDIR_MASK)
+		return (cp + 1);
+	while (i && cp < snapend) {
+		cp += i;
+		i = *cp++;
+	}
+	return (cp);
+}
+
+/* print a <domain-name> */
+static const u_char *
+ns_nprint(register const u_char *cp, register const u_char *bp)
+{
+	register u_int i;
+	register const u_char *rp;
+	register int compress;
+
+	i = *cp++;
+	rp = cp + i;
+	if ((i & INDIR_MASK) == INDIR_MASK) {
+		rp = cp + 1;
+		compress = 1;
+	} else
+		compress = 0;
+	if (i != 0)
+		while (i && cp < snapend) {
+			if ((i & INDIR_MASK) == INDIR_MASK) {
+				cp = bp + (((i << 8) | *cp) & 0x3fff);
+				i = *cp++;
+				continue;
+			}
+			if (fn_printn(cp, i, snapend))
+				break;
+			cp += i;
+			putchar('.');
+			i = *cp++;
+			if (!compress)
+				rp += i + 1;
+		}
+	else
+		putchar('.');
+	return (rp);
+}
+
+/* print a <character-string> */
+static const u_char *
+ns_cprint(register const u_char *cp, register const u_char *bp)
+{
+	register u_int i;
+
+	i = *cp++;
+	(void)fn_printn(cp, i, snapend);
+	return (cp + i);
+}
+
+static struct tok type2str[] = {
+	{ T_A,		"A" },
+	{ T_NS,		"NS" },
+	{ T_MD,		"MD" },
+	{ T_MF,		"MF" },
+	{ T_CNAME,	"CNAME" },
+	{ T_SOA,	"SOA" },
+	{ T_MB,		"MB" },
+	{ T_MG,		"MG" },
+	{ T_MR,		"MR" },
+	{ T_NULL,	"NULL" },
+	{ T_WKS,	"WKS" },
+	{ T_PTR,	"PTR" },
+	{ T_HINFO,	"HINFO" },
+	{ T_MINFO,	"MINFO" },
+	{ T_MX,		"MX" },
+	{ T_TXT,	"TXT" },
+	{ T_RP,		"RP" },
+	{ T_AFSDB,	"AFSDB" },
+	{ T_X25,	"X25" },
+	{ T_ISDN,	"ISDN" },
+	{ T_RT,		"RT" },
+	{ T_NSAP,	"NSAP" },
+	{ T_NSAP_PTR,	"NSAP_PTR" },
+	{ T_SIG,	"SIG" },
+	{ T_KEY,	"KEY" },
+	{ T_PX,		"PX" },
+	{ T_GPOS,	"GPOS" },
+	{ T_AAAA,	"AAAA" },
+	{ T_LOC ,	"LOC " },
+	{ T_UINFO,	"UINFO" },
+	{ T_UID,	"UID" },
+	{ T_GID,	"GID" },
+	{ T_UNSPEC,	"UNSPEC" },
+	{ T_UNSPECA,	"UNSPECA" },
+	{ T_AXFR,	"AXFR" },
+	{ T_MAILB,	"MAILB" },
+	{ T_MAILA,	"MAILA" },
+	{ T_ANY,	"ANY" },
+	{ 0,		NULL }
+};
+
+static struct tok class2str[] = {
+	{ C_IN,		"IN" },		/* Not used */
+	{ C_CHAOS,	"CHAOS)" },
+	{ C_HS,		"HS" },
+	{ C_ANY,	"ANY" },
+	{ 0,		NULL }
+};
+
+/* print a query */
+static void
+ns_qprint(register const u_char *cp, register const u_char *bp)
+{
+	register const u_char *np = cp;
+	register u_int i;
+
+	cp = ns_nskip(cp, bp);
+
+	if (cp + 4 > snapend)
+		return;
+
+	/* print the qtype and qclass (if it's not IN) */
+	i = *cp++ << 8;
+	i |= *cp++;
+	printf(" %s", tok2str(type2str, "Type%d", i));
+	i = *cp++ << 8;
+	i |= *cp++;
+	if (i != C_IN)
+		printf(" %s", tok2str(class2str, "(Class %d)", i));
+
+	fputs("? ", stdout);
+	ns_nprint(np, bp);
+}
+
+/* print a reply */
+static const u_char *
+ns_rprint(register const u_char *cp, register const u_char *bp)
+{
+	register u_int i;
+	register u_short typ, len;
+	register const u_char *rp;
+
+	if (vflag) {
+		putchar(' ');
+		cp = ns_nprint(cp, bp);
+	} else
+		cp = ns_nskip(cp, bp);
+
+	if (cp + 10 > snapend)
+		return (snapend);
+
+	/* print the type/qtype and class (if it's not IN) */
+	typ = *cp++ << 8;
+	typ |= *cp++;
+	i = *cp++ << 8;
+	i |= *cp++;
+	if (i != C_IN)
+		printf(" %s", tok2str(class2str, "(Class %d)", i));
+
+	/* ignore ttl */
+	cp += 4;
+
+	len = *cp++ << 8;
+	len |= *cp++;
+
+	rp = cp + len;
+
+	printf(" %s", tok2str(type2str, "Type%d", typ));
+	switch (typ) {
+
+	case T_A:
+		printf(" %s", ipaddr_string(cp));
+		break;
+
+	case T_NS:
+	case T_CNAME:
+	case T_PTR:
+		putchar(' ');
+		(void)ns_nprint(cp, bp);
+		break;
+
+	case T_MX:
+		putchar(' ');
+		(void)ns_nprint(cp + 2, bp);
+		printf(" %d", EXTRACT_16BITS(cp));
+		break;
+
+	case T_TXT:
+		putchar(' ');
+		(void)ns_cprint(cp, bp);
+		break;
+
+	case T_UNSPECA:		/* One long string */
+	        printf(" %.*s", len, cp);
+		break;
+	}
+	return (rp);		/* XXX This isn't always right */
+}
+
+void
+ns_print(register const u_char *bp, u_int length)
+{
+	register const HEADER *np;
+	register int qdcount, ancount, nscount, arcount;
+	register const u_char *cp;
+
+	np = (const HEADER *)bp;
+	/* get the byte-order right */
+	qdcount = ntohs(np->qdcount);
+	ancount = ntohs(np->ancount);
+	nscount = ntohs(np->nscount);
+	arcount = ntohs(np->arcount);
+
+	if (np->qr) {
+		/* this is a response */
+		printf(" %d%s%s%s%s%s",
+			ntohs(np->id),
+			ns_ops[np->opcode],
+			ns_resp[np->rcode],
+			np->aa? "*" : "",
+			np->ra? "" : "-",
+			np->tc? "|" : "");
+		if (qdcount != 1)
+			printf(" [%dq]", qdcount);
+		/* Print QUESTION section on -vv */
+		if (vflag > 1) {
+		            fputs(" q: ", stdout);
+			    cp = ns_nprint((const u_char *)(np + 1), bp);
+		} else
+			    cp = ns_nskip((const u_char *)(np + 1), bp);
+		printf(" %d/%d/%d", ancount, nscount, arcount);
+		if (ancount--) {
+			cp = ns_rprint(cp + 4, bp);
+			while (ancount-- && cp < snapend) {
+				putchar(',');
+				cp = ns_rprint(cp, bp);
+			}
+		}
+	}
+	else {
+		/* this is a request */
+		printf(" %d%s%s",
+		        ntohs(np->id),
+			ns_ops[np->opcode],
+			np->rd? "+" : "");
+
+		/* any weirdness? */
+		if (*(((u_short *)np)+1) & htons(0x6ff))
+			printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1)));
+
+		if (np->opcode == IQUERY) {
+			if (qdcount)
+				printf(" [%dq]", qdcount);
+			if (ancount != 1)
+				printf(" [%da]", ancount);
+		}
+		else {
+			if (ancount)
+				printf(" [%da]", ancount);
+			if (qdcount != 1)
+				printf(" [%dq]", qdcount);
+		}
+		if (nscount)
+			printf(" [%dn]", nscount);
+		if (arcount)
+			printf(" [%dau]", arcount);
+
+		ns_qprint((const u_char *)(np + 1), (const u_char *)np);
+	}
+	printf(" (%d)", length);
+}
diff --git a/tcpdump.tproj/print-dvmrp.c b/tcpdump.tproj/print-dvmrp.c
new file mode 100644
index 0000000..a396cf9
--- /dev/null
+++ b/tcpdump.tproj/print-dvmrp.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-dvmrp.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/*
+ * DVMRP message types and flag values shamelessly stolen from
+ * mrouted/dvmrp.h.
+ */
+#define DVMRP_PROBE		1	/* for finding neighbors */
+#define DVMRP_REPORT		2	/* for reporting some or all routes */
+#define DVMRP_ASK_NEIGHBORS	3	/* sent by mapper, asking for a list */
+					/*
+					 * of this router's neighbors
+					 */
+#define DVMRP_NEIGHBORS		4	/* response to such a request */
+#define DVMRP_ASK_NEIGHBORS2	5	/* as above, want new format reply */
+#define DVMRP_NEIGHBORS2	6
+#define DVMRP_PRUNE		7	/* prune message */
+#define DVMRP_GRAFT		8	/* graft message */
+#define DVMRP_GRAFT_ACK		9	/* graft acknowledgement */
+
+/*
+ * 'flags' byte values in DVMRP_NEIGHBORS2 reply.
+ */
+#define DVMRP_NF_TUNNEL		0x01	/* neighbors reached via tunnel */
+#define DVMRP_NF_SRCRT		0x02	/* tunnel uses IP source routing */
+#define DVMRP_NF_DOWN		0x10	/* kernel state of interface */
+#define DVMRP_NF_DISABLED	0x20	/* administratively disabled */
+#define DVMRP_NF_QUERIER	0x40	/* I am the subnet's querier */
+
+static void print_probe(const u_char *, const u_char *, u_int);
+static void print_report(const u_char *, const u_char *, u_int);
+static void print_neighbors(const u_char *, const u_char *, u_int);
+static void print_neighbors2(const u_char *, const u_char *, u_int);
+static void print_prune(const u_char *, const u_char *, u_int);
+static void print_graft(const u_char *, const u_char *, u_int);
+static void print_graft_ack(const u_char *, const u_char *, u_int);
+
+static u_int32_t target_level;
+
+void
+dvmrp_print(register const u_char *bp, register u_int len)
+{
+	register const u_char *ep;
+	register u_char type;
+
+	ep = (const u_char *)snapend;
+	if (bp >= ep)
+		return;
+
+	type = bp[1];
+	bp += 8;
+	/*
+	 * Skip IGMP header
+	 */
+
+	len -= 8;
+
+	switch (type) {
+
+	case DVMRP_PROBE:
+		printf(" Probe");
+		if (vflag)
+			print_probe(bp, ep, len);
+		break;
+
+	case DVMRP_REPORT:
+		printf(" Report");
+		if (vflag)
+			print_report(bp, ep, len);
+		break;
+
+	case DVMRP_ASK_NEIGHBORS:
+		printf(" Ask-neighbors(old)");
+		break;
+
+	case DVMRP_NEIGHBORS:
+		printf(" Neighbors(old)");
+		print_neighbors(bp, ep, len);
+		break;
+
+	case DVMRP_ASK_NEIGHBORS2:
+		printf(" Ask-neighbors2");
+		break;
+
+	case DVMRP_NEIGHBORS2:
+		printf(" Neighbors2");
+		/*
+		 * extract version and capabilities from IGMP group
+		 * address field
+		 */
+		bp -= 4;
+		target_level = (bp[0] << 24) | (bp[1] << 16) |
+		    (bp[2] << 8) | bp[3];
+		bp += 4;
+		print_neighbors2(bp, ep, len);
+		break;
+
+	case DVMRP_PRUNE:
+		printf(" Prune");
+		print_prune(bp, ep, len);
+		break;
+
+	case DVMRP_GRAFT:
+		printf(" Graft");
+		print_graft(bp, ep, len);
+		break;
+
+	case DVMRP_GRAFT_ACK:
+		printf(" Graft-ACK");
+		print_graft_ack(bp, ep, len);
+		break;
+
+	default:
+		printf(" [type %d]", type);
+		break;
+	}
+}
+
+static void
+print_report(register const u_char *bp, register const u_char *ep,
+    register u_int len)
+{
+	register u_int32_t mask, origin;
+	register int metric, i, width, done;
+
+	while (len > 0) {
+		if (len < 3) {
+			printf(" [|]");
+			return;
+		}
+		mask = (u_int32_t)0xff << 24 | bp[0] << 16 | bp[1] << 8 | bp[2];
+		width = 1;
+		if (bp[0])
+			width = 2;
+		if (bp[1])
+			width = 3;
+		if (bp[2])
+			width = 4;
+
+		printf("\n\tMask %s", intoa(htonl(mask)));
+		bp += 3;
+		len -= 3;
+		do {
+			if (bp + width + 1 > ep) {
+				printf(" [|]");
+				return;
+			}
+			if (len < width + 1) {
+				printf("\n\t  [Truncated Report]");
+				return;
+			}
+			origin = 0;
+			for (i = 0; i < width; ++i)
+				origin = origin << 8 | *bp++;
+			for ( ; i < 4; ++i)
+				origin <<= 8;
+
+			metric = *bp++;
+			done = metric & 0x80;
+			metric &= 0x7f;
+			printf("\n\t  %s metric %d", intoa(htonl(origin)),
+				metric);
+			len -= width + 1;
+		} while (!done);
+	}
+}
+
+#define GET_ADDR(to) (memcpy((char *)to, (char *)bp, 4), bp += 4)
+
+static void
+print_probe(register const u_char *bp, register const u_char *ep,
+    register u_int len)
+{
+	register u_int32_t genid;
+	u_char neighbor[4];
+
+	if ((len < 4) || ((bp + 4) > ep)) {
+		/* { (ctags) */
+		printf(" [|}");
+		return;
+	}
+	genid = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3];
+	bp += 4;
+	len -= 4;
+	printf("\n\tgenid %u", genid);
+
+	while ((len > 0) && (bp < ep)) {
+		if ((len < 4) || ((bp + 4) > ep)) {
+			printf(" [|]");
+			return;
+		}
+		GET_ADDR(neighbor);
+		len -= 4;
+		printf("\n\tneighbor %s", ipaddr_string(neighbor));
+	}
+}
+
+static void
+print_neighbors(register const u_char *bp, register const u_char *ep,
+    register u_int len)
+{
+	u_char laddr[4], neighbor[4];
+	register u_char metric;
+	register u_char thresh;
+	register int ncount;
+
+	while (len > 0 && bp < ep) {
+		if (len < 7 || (bp + 7) >= ep) {
+			printf(" [|]");
+			return;
+		}
+		GET_ADDR(laddr);
+		metric = *bp++;
+		thresh = *bp++;
+		ncount = *bp++;
+		len -= 7;
+		while (--ncount >= 0 && (len >= 4) && (bp + 4) < ep) {
+			GET_ADDR(neighbor);
+			printf(" [%s ->", ipaddr_string(laddr));
+			printf(" %s, (%d/%d)]",
+				   ipaddr_string(neighbor), metric, thresh);
+			len -= 4;
+		}
+	}
+}
+
+static void
+print_neighbors2(register const u_char *bp, register const u_char *ep,
+    register u_int len)
+{
+	u_char laddr[4], neighbor[4];
+	register u_char metric, thresh, flags;
+	register int ncount;
+
+	printf(" (v %d.%d):",
+	       (int)target_level & 0xff,
+	       (int)(target_level >> 8) & 0xff);
+
+	while (len > 0 && bp < ep) {
+		if (len < 8 || (bp + 8) >= ep) {
+			printf(" [|]");
+			return;
+		}
+		GET_ADDR(laddr);
+		metric = *bp++;
+		thresh = *bp++;
+		flags = *bp++;
+		ncount = *bp++;
+		len -= 8;
+		while (--ncount >= 0 && (len >= 4) && (bp + 4) <= ep) {
+			GET_ADDR(neighbor);
+			printf(" [%s -> ", ipaddr_string(laddr));
+			printf("%s (%d/%d", ipaddr_string(neighbor),
+				     metric, thresh);
+			if (flags & DVMRP_NF_TUNNEL)
+				printf("/tunnel");
+			if (flags & DVMRP_NF_SRCRT)
+				printf("/srcrt");
+			if (flags & DVMRP_NF_QUERIER)
+				printf("/querier");
+			if (flags & DVMRP_NF_DISABLED)
+				printf("/disabled");
+			if (flags & DVMRP_NF_DOWN)
+				printf("/down");
+			printf(")]");
+			len -= 4;
+		}
+		if (ncount != -1) {
+			printf(" [|]");
+			return;
+		}
+	}
+}
+
+static void
+print_prune(register const u_char *bp, register const u_char *ep,
+    register u_int len)
+{
+	union a {
+		u_char b[4];
+		u_int32_t i;
+	} prune_timer;
+
+	if (len < 12 || (bp + 12) > ep) {
+		printf(" [|]");
+		return;
+	}
+	printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
+	bp += 8;
+	GET_ADDR(prune_timer.b);
+	printf(" timer %d", (int)ntohl(prune_timer.i));
+}
+
+static void
+print_graft(register const u_char *bp, register const u_char *ep,
+    register u_int len)
+{
+
+	if (len < 8 || (bp + 8) > ep) {
+		printf(" [|]");
+		return;
+	}
+	printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
+}
+
+static void
+print_graft_ack(register const u_char *bp, register const u_char *ep,
+    register u_int len)
+{
+
+	if (len < 8 || (bp + 8) > ep) {
+		printf(" [|]");
+		return;
+	}
+	printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
+}
diff --git a/tcpdump.tproj/print-egp.c b/tcpdump.tproj/print-egp.c
new file mode 100644
index 0000000..092c2b5
--- /dev/null
+++ b/tcpdump.tproj/print-egp.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996
+ *	The 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, Lawrence Berkeley Laboratory,
+ * Berkeley, CA.  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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU).
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-egp.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <netdb.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+struct egp_packet {
+	u_char  egp_version;
+#define	EGP_VERSION	2
+	u_char  egp_type;
+#define  EGPT_ACQUIRE	3
+#define  EGPT_REACH	5
+#define  EGPT_POLL	2
+#define  EGPT_UPDATE	1
+#define  EGPT_ERROR	8
+	u_char  egp_code;
+#define  EGPC_REQUEST	0
+#define  EGPC_CONFIRM	1
+#define  EGPC_REFUSE	2
+#define  EGPC_CEASE	3
+#define  EGPC_CEASEACK	4
+#define  EGPC_HELLO	0
+#define  EGPC_HEARDU	1
+	u_char  egp_status;
+#define  EGPS_UNSPEC	0
+#define  EGPS_ACTIVE	1
+#define  EGPS_PASSIVE	2
+#define  EGPS_NORES	3
+#define  EGPS_ADMIN	4
+#define  EGPS_GODOWN	5
+#define  EGPS_PARAM	6
+#define  EGPS_PROTO	7
+#define  EGPS_INDET	0
+#define  EGPS_UP	1
+#define  EGPS_DOWN	2
+#define  EGPS_UNSOL	0x80
+	u_short  egp_checksum;
+	u_short  egp_as;
+	u_short  egp_sequence;
+	union {
+		u_short  egpu_hello;
+		u_char egpu_gws[2];
+		u_short  egpu_reason;
+#define  EGPR_UNSPEC	0
+#define  EGPR_BADHEAD	1
+#define  EGPR_BADDATA	2
+#define  EGPR_NOREACH	3
+#define  EGPR_XSPOLL	4
+#define  EGPR_NORESP	5
+#define  EGPR_UVERSION	6
+	} egp_handg;
+#define  egp_hello  egp_handg.egpu_hello
+#define  egp_intgw  egp_handg.egpu_gws[0]
+#define  egp_extgw  egp_handg.egpu_gws[1]
+#define  egp_reason  egp_handg.egpu_reason
+	union {
+		u_short  egpu_poll;
+		u_int32_t egpu_sourcenet;
+	} egp_pands;
+#define  egp_poll  egp_pands.egpu_poll
+#define  egp_sourcenet  egp_pands.egpu_sourcenet
+};
+
+char *egp_acquire_codes[] = {
+	"request",
+	"confirm",
+	"refuse",
+	"cease",
+	"cease_ack"
+};
+
+char *egp_acquire_status[] = {
+	"unspecified",
+	"active_mode",
+	"passive_mode",
+	"insufficient_resources",
+	"administratively_prohibited",
+	"going_down",
+	"parameter_violation",
+	"protocol_violation"
+};
+
+char *egp_reach_codes[] = {
+	"hello",
+	"i-h-u"
+};
+
+char *egp_status_updown[] = {
+	"indeterminate",
+	"up",
+	"down"
+};
+
+char *egp_reasons[] = {
+	"unspecified",
+	"bad_EGP_header_format",
+	"bad_EGP_data_field_format",
+	"reachability_info_unavailable",
+	"excessive_polling_rate",
+	"no_response",
+	"unsupported_version"
+};
+
+static void
+egpnrprint(register const struct egp_packet *egp, register u_int length)
+{
+	register const u_char *cp;
+	u_int32_t addr;
+	register u_int32_t net;
+	register u_int netlen;
+	int gateways, distances, networks;
+	int t_gateways;
+	char *comma;
+
+	addr = egp->egp_sourcenet;
+	if (IN_CLASSA(addr)) {
+		net = addr & IN_CLASSA_NET;
+		netlen = 1;
+	} else if (IN_CLASSB(addr)) {
+		net = addr & IN_CLASSB_NET;
+		netlen = 2;
+	} else if (IN_CLASSC(addr)) {
+		net = addr & IN_CLASSC_NET;
+		netlen = 3;
+	} else {
+		net = 0;
+		netlen = 0;
+	}
+	cp = (u_char *)(egp + 1);
+
+	t_gateways = egp->egp_intgw + egp->egp_extgw;
+	for (gateways = 0; gateways < t_gateways; ++gateways) {
+		/* Pickup host part of gateway address */
+		addr = 0;
+		TCHECK2(cp[0], 4 - netlen);
+		switch (netlen) {
+
+		case 1:
+			addr = *cp++;
+			/* fall through */
+		case 2:
+			addr = (addr << 8) | *cp++;
+			/* fall through */
+		case 3:
+			addr = (addr << 8) | *cp++;
+		}
+		addr |= net;
+		TCHECK2(cp[0], 1);
+		distances = *cp++;
+		printf(" %s %s ",
+		       gateways < (int)egp->egp_intgw ? "int" : "ext",
+		       ipaddr_string(&addr));
+
+		comma = "";
+		putchar('(');
+		while (--distances >= 0) {
+			TCHECK2(cp[0], 2);
+			printf("%sd%d:", comma, (int)*cp++);
+			comma = ", ";
+			networks = *cp++;
+			while (--networks >= 0) {
+				/* Pickup network number */
+				TCHECK2(cp[0], 1);
+				addr = (u_int32_t)*cp++ << 24;
+				if (IN_CLASSB(addr)) {
+					TCHECK2(cp[0], 1);
+					addr |= (u_int32_t)*cp++ << 16;
+				} else if (!IN_CLASSA(addr)) {
+					TCHECK2(cp[0], 2);
+					addr |= (u_int32_t)*cp++ << 16;
+					addr |= (u_int32_t)*cp++ << 8;
+				}
+				printf(" %s", ipaddr_string(&addr));
+			}
+		}
+		putchar(')');
+	}
+	return;
+trunc:
+	fputs("[|]", stdout);
+}
+
+void
+egp_print(register const u_char *bp, register u_int length,
+	  register const u_char *bp2)
+{
+	register const struct egp_packet *egp;
+	register const struct ip *ip;
+	register int status;
+	register int code;
+	register int type;
+
+	egp = (struct egp_packet *)bp;
+	ip = (struct ip *)bp2;
+        (void)printf("%s > %s: egp: ",
+		     ipaddr_string(&ip->ip_src),
+		     ipaddr_string(&ip->ip_dst));
+
+	if (egp->egp_version != EGP_VERSION) {
+		printf("[version %d]", egp->egp_version);
+		return;
+	}
+	printf("as:%d seq:%d", ntohs(egp->egp_as), ntohs(egp->egp_sequence));
+
+	type = egp->egp_type;
+	code = egp->egp_code;
+	status = egp->egp_status;
+
+	switch (type) {
+	case EGPT_ACQUIRE:
+		printf(" acquire");
+		switch (code) {
+		case EGPC_REQUEST:
+		case EGPC_CONFIRM:
+			printf(" %s", egp_acquire_codes[code]);
+			switch (status) {
+			case EGPS_UNSPEC:
+			case EGPS_ACTIVE:
+			case EGPS_PASSIVE:
+				printf(" %s", egp_acquire_status[status]);
+				break;
+
+			default:
+				printf(" [status %d]", status);
+				break;
+			}
+			printf(" hello:%d poll:%d",
+			       ntohs(egp->egp_hello),
+			       ntohs(egp->egp_poll));
+			break;
+
+		case EGPC_REFUSE:
+		case EGPC_CEASE:
+		case EGPC_CEASEACK:
+			printf(" %s", egp_acquire_codes[code]);
+			switch (status ) {
+			case EGPS_UNSPEC:
+			case EGPS_NORES:
+			case EGPS_ADMIN:
+			case EGPS_GODOWN:
+			case EGPS_PARAM:
+			case EGPS_PROTO:
+				printf(" %s", egp_acquire_status[status]);
+				break;
+
+			default:
+				printf("[status %d]", status);
+				break;
+			}
+			break;
+
+		default:
+			printf("[code %d]", code);
+			break;
+		}
+		break;
+
+	case EGPT_REACH:
+		switch (code) {
+
+		case EGPC_HELLO:
+		case EGPC_HEARDU:
+			printf(" %s", egp_reach_codes[code]);
+			if (status <= EGPS_DOWN)
+				printf(" state:%s", egp_status_updown[status]);
+			else
+				printf(" [status %d]", status);
+			break;
+
+		default:
+			printf("[reach code %d]", code);
+			break;
+		}
+		break;
+
+	case EGPT_POLL:
+		printf(" poll");
+		if (egp->egp_status <= EGPS_DOWN)
+			printf(" state:%s", egp_status_updown[status]);
+		else
+			printf(" [status %d]", status);
+		printf(" net:%s", ipaddr_string(&egp->egp_sourcenet));
+		break;
+
+	case EGPT_UPDATE:
+		printf(" update");
+		if (status & EGPS_UNSOL) {
+			status &= ~EGPS_UNSOL;
+			printf(" unsolicited");
+		}
+		if (status <= EGPS_DOWN)
+			printf(" state:%s", egp_status_updown[status]);
+		else
+			printf(" [status %d]", status);
+		printf(" %s int %d ext %d",
+		       ipaddr_string(&egp->egp_sourcenet),
+		       egp->egp_intgw,
+		       egp->egp_extgw);
+		if (vflag)
+			egpnrprint(egp, length);
+		break;
+
+	case EGPT_ERROR:
+		printf(" error");
+		if (status <= EGPS_DOWN)
+			printf(" state:%s", egp_status_updown[status]);
+		else
+			printf(" [status %d]", status);
+
+		if (ntohs(egp->egp_reason) <= EGPR_UVERSION)
+			printf(" %s", egp_reasons[ntohs(egp->egp_reason)]);
+		else
+			printf(" [reason %d]", ntohs(egp->egp_reason));
+		break;
+
+	default:
+		printf("[type %d]", type);
+		break;
+	}
+}
diff --git a/tcpdump.tproj/print-ether.c b/tcpdump.tproj/print-ether.c
new file mode 100644
index 0000000..ae9ddd9
--- /dev/null
+++ b/tcpdump.tproj/print-ether.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-ether.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+const u_char *packetp;
+const u_char *snapend;
+
+static inline void
+ether_print(register const u_char *bp, u_int length)
+{
+	register const struct ether_header *ep;
+
+	ep = (const struct ether_header *)bp;
+	if (qflag)
+		(void)printf("%s %s %d: ",
+			     etheraddr_string(ESRC(ep)),
+			     etheraddr_string(EDST(ep)),
+			     length);
+	else
+		(void)printf("%s %s %s %d: ",
+			     etheraddr_string(ESRC(ep)),
+			     etheraddr_string(EDST(ep)),
+			     etherproto_string(ep->ether_type),
+			     length);
+}
+
+/*
+ * This is the top level routine of the printer.  'p' is the points
+ * to the ether header of the packet, 'tvp' is the timestamp,
+ * 'length' is the length of the packet off the wire, and 'caplen'
+ * is the number of bytes actually captured.
+ */
+void
+ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+	u_int caplen = h->caplen;
+	u_int length = h->len;
+	struct ether_header *ep;
+	u_short ether_type;
+	extern u_short extracted_ethertype;
+
+	ts_print(&h->ts);
+
+	if (caplen < sizeof(struct ether_header)) {
+		printf("[|ether]");
+		goto out;
+	}
+
+	if (eflag)
+		ether_print(p, length);
+
+	/*
+	 * Some printers want to get back at the ethernet addresses,
+	 * and/or check that they're not walking off the end of the packet.
+	 * Rather than pass them all the way down, we set these globals.
+	 */
+	packetp = p;
+	snapend = p + caplen;
+
+	length -= sizeof(struct ether_header);
+	caplen -= sizeof(struct ether_header);
+	ep = (struct ether_header *)p;
+	p += sizeof(struct ether_header);
+
+	ether_type = ntohs(ep->ether_type);
+
+	/*
+	 * Is it (gag) an 802.3 encapsulation?
+	 */
+	extracted_ethertype = 0;
+	if (ether_type < ETHERMTU) {
+		/* Try to print the LLC-layer header & higher layers */
+		if (llc_print(p, length, caplen, ESRC(ep), EDST(ep)) == 0) {
+			/* ether_type not known, print raw packet */
+			if (!eflag)
+				ether_print((u_char *)ep, length);
+			if (extracted_ethertype) {
+				printf("(LLC %s) ",
+			       etherproto_string(htons(extracted_ethertype)));
+			}
+			if (!xflag && !qflag)
+				default_print(p, caplen);
+		}
+	} else if (ether_encap_print(ether_type, p, length, caplen) == 0) {
+		/* ether_type not known, print raw packet */
+		if (!eflag)
+			ether_print((u_char *)ep, length + sizeof(*ep));
+		if (!xflag && !qflag)
+			default_print(p, caplen);
+	}
+	if (xflag)
+		default_print(p, caplen);
+ out:
+	putchar('\n');
+}
+
+/*
+ * Prints the packet encapsulated in an Ethernet data segment
+ * (or an equivalent encapsulation), given the Ethernet type code.
+ *
+ * Returns non-zero if it can do so, zero if the ethertype is unknown.
+ *
+ * Stuffs the ether type into a global for the benefit of lower layers
+ * that might want to know what it is.
+ */
+
+u_short	extracted_ethertype;
+
+int
+ether_encap_print(u_short ethertype, const u_char *p,
+    u_int length, u_int caplen)
+{
+	extracted_ethertype = ethertype;
+
+	switch (ethertype) {
+
+	case ETHERTYPE_IP:
+		ip_print(p, length);
+		return (1);
+
+	case ETHERTYPE_ARP:
+	case ETHERTYPE_REVARP:
+		arp_print(p, length, caplen);
+		return (1);
+
+	case ETHERTYPE_DN:
+		decnet_print(p, length, caplen);
+		return (1);
+
+	case ETHERTYPE_ATALK:
+		if (vflag)
+			fputs("et1 ", stdout);
+		atalk_print(p, length);
+		return (1);
+
+	case ETHERTYPE_AARP:
+		aarp_print(p, length);
+		return (1);
+
+	case ETHERTYPE_LAT:
+	case ETHERTYPE_SCA:
+	case ETHERTYPE_MOPRC:
+	case ETHERTYPE_MOPDL:
+		/* default_print for now */
+	default:
+		return (0);
+	}
+}
diff --git a/tcpdump.tproj/print-fddi.c b/tcpdump.tproj/print-fddi.c
new file mode 100644
index 0000000..15f8297
--- /dev/null
+++ b/tcpdump.tproj/print-fddi.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-fddi.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_FDDI
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#include "fddi.h"
+
+/*
+ * Some FDDI interfaces use bit-swapped addresses.
+ */
+#if defined(ultrix) || defined(__alpha)
+int	fddi_bitswap = 0;
+#else
+int	fddi_bitswap = 1;
+#endif
+
+/*
+ * FDDI support for tcpdump, by Jeffrey Mogul [DECWRL], June 1992
+ *
+ * Based in part on code by Van Jacobson, which bears this note:
+ *
+ * NOTE:  This is a very preliminary hack for FDDI support.
+ * There are all sorts of wired in constants & nothing (yet)
+ * to print SMT packets as anything other than hex dumps.
+ * Most of the necessary changes are waiting on my redoing
+ * the "header" that a kernel fddi driver supplies to bpf:  I
+ * want it to look like one byte of 'direction' (0 or 1
+ * depending on whether the packet was inbound or outbound),
+ * two bytes of system/driver dependent data (anything an
+ * implementor thinks would be useful to filter on and/or
+ * save per-packet, then the real 21-byte FDDI header.
+ * Steve McCanne & I have also talked about adding the
+ * 'direction' byte to all bpf headers (e.g., in the two
+ * bytes of padding on an ethernet header).  It's not clear
+ * we could do this in a backwards compatible way & we hate
+ * the idea of an incompatible bpf change.  Discussions are
+ * proceeding.
+ *
+ * Also, to really support FDDI (and better support 802.2
+ * over ethernet) we really need to re-think the rather simple
+ * minded assumptions about fixed length & fixed format link
+ * level headers made in gencode.c.  One day...
+ *
+ *  - vj
+ */
+
+#define FDDI_HDRLEN (sizeof(struct fddi_header))
+
+static u_char fddi_bit_swap[] = {
+	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
+
+/*
+ * Print FDDI frame-control bits
+ */
+static inline void
+print_fddi_fc(u_char fc)
+{
+	switch (fc) {
+
+	case FDDIFC_VOID:                         /* Void frame */
+		printf("void ");
+		break;
+
+	case FDDIFC_NRT:                          /* Nonrestricted token */
+		printf("nrt ");
+		break;
+
+	case FDDIFC_RT:                           /* Restricted token */
+		printf("rt ");
+		break;
+
+	case FDDIFC_SMT_INFO:                     /* SMT Info */
+		printf("info ");
+		break;
+
+	case FDDIFC_SMT_NSA:                      /* SMT Next station adrs */
+		printf("nsa ");
+		break;
+
+	case FDDIFC_MAC_BEACON:                   /* MAC Beacon frame */
+		printf("beacon ");
+		break;
+
+	case FDDIFC_MAC_CLAIM:                    /* MAC Claim frame */
+		printf("claim ");
+		break;
+
+	default:
+		switch (fc & FDDIFC_CLFF) {
+
+		case FDDIFC_MAC:
+			printf("mac%1x ", fc & FDDIFC_ZZZZ);
+			break;
+
+		case FDDIFC_SMT:
+			printf("smt%1x ", fc & FDDIFC_ZZZZ);
+			break;
+
+		case FDDIFC_LLC_ASYNC:
+			printf("async%1x ", fc & FDDIFC_ZZZZ);
+			break;
+
+		case FDDIFC_LLC_SYNC:
+			printf("sync%1x ", fc & FDDIFC_ZZZZ);
+			break;
+
+		case FDDIFC_IMP_ASYNC:
+			printf("imp_async%1x ", fc & FDDIFC_ZZZZ);
+			break;
+
+		case FDDIFC_IMP_SYNC:
+			printf("imp_sync%1x ", fc & FDDIFC_ZZZZ);
+			break;
+
+		default:
+			printf("%02x ", fc);
+			break;
+		}
+	}
+}
+
+/* Extract src, dst addresses */
+static inline void
+extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst)
+{
+	register int i;
+
+	if (fddi_bitswap) {
+		/*
+		 * bit-swap the fddi addresses (isn't the IEEE standards
+		 * process wonderful!) then convert them to names.
+		 */
+		for (i = 0; i < 6; ++i)
+			fdst[i] = fddi_bit_swap[fddip->fddi_dhost[i]];
+		for (i = 0; i < 6; ++i)
+			fsrc[i] = fddi_bit_swap[fddip->fddi_shost[i]];
+	}
+	else {
+		memcpy(fdst, (char *)fddip->fddi_dhost, 6);
+		memcpy(fsrc, (char *)fddip->fddi_shost, 6);
+	}
+}
+
+/*
+ * Print the FDDI MAC header
+ */
+static inline void
+fddi_print(register const struct fddi_header *fddip, register u_int length,
+	   register const u_char *fsrc, register const u_char *fdst)
+{
+	char *srcname, *dstname;
+
+	srcname = etheraddr_string(fsrc);
+	dstname = etheraddr_string(fdst);
+
+	if (vflag)
+		(void) printf("%02x %s %s %d: ",
+		       fddip->fddi_fc,
+		       srcname, dstname,
+		       length);
+	else if (qflag)
+		printf("%s %s %d: ", srcname, dstname, length);
+	else {
+		(void) print_fddi_fc(fddip->fddi_fc);
+		(void) printf("%s %s %d: ", srcname, dstname, length);
+	}
+}
+
+static inline void
+fddi_smt_print(const u_char *p, u_int length)
+{
+	printf("<SMT printer not yet implemented>");
+}
+
+/*
+ * This is the top level routine of the printer.  'sp' is the points
+ * to the FDDI header of the packet, 'tvp' is the timestamp,
+ * 'length' is the length of the packet off the wire, and 'caplen'
+ * is the number of bytes actually captured.
+ */
+void
+fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
+	      register const u_char *p)
+{
+	u_int caplen = h->caplen;
+	u_int length = h->len;
+	const struct fddi_header *fddip = (struct fddi_header *)p;
+	extern u_short extracted_ethertype;
+	struct ether_header ehdr;
+
+	ts_print(&h->ts);
+
+	if (caplen < FDDI_HDRLEN) {
+		printf("[|fddi]");
+		goto out;
+	}
+	/*
+	 * Get the FDDI addresses into a canonical form
+	 */
+	extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
+	/*
+	 * Some printers want to get back at the link level addresses,
+	 * and/or check that they're not walking off the end of the packet.
+	 * Rather than pass them all the way down, we set these globals.
+	 */
+	snapend = p + caplen;
+	/*
+	 * Actually, the only printer that uses packetp is print-bootp.c,
+	 * and it assumes that packetp points to an Ethernet header.  The
+	 * right thing to do is to fix print-bootp.c to know which link
+	 * type is in use when it excavates. XXX
+	 */
+	packetp = (u_char *)&ehdr;
+
+	if (eflag)
+		fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
+
+	/* Skip over FDDI MAC header */
+	length -= FDDI_HDRLEN;
+	p += FDDI_HDRLEN;
+	caplen -= FDDI_HDRLEN;
+
+	/* Frame Control field determines interpretation of packet */
+	extracted_ethertype = 0;
+	if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) {
+		/* Try to print the LLC-layer header & higher layers */
+		if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr))
+		    == 0) {
+			/*
+			 * Some kinds of LLC packet we cannot
+			 * handle intelligently
+			 */
+			if (!eflag)
+				fddi_print(fddip, length,
+				    ESRC(&ehdr), EDST(&ehdr));
+			if (extracted_ethertype) {
+				printf("(LLC %s) ",
+			etherproto_string(htons(extracted_ethertype)));
+			}
+			if (!xflag && !qflag)
+				default_print(p, caplen);
+		}
+	} else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT)
+		fddi_smt_print(p, caplen);
+	else {
+		/* Some kinds of FDDI packet we cannot handle intelligently */
+		if (!eflag)
+			fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
+		if (!xflag && !qflag)
+			default_print(p, caplen);
+	}
+	if (xflag)
+		default_print(p, caplen);
+out:
+	putchar('\n');
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+void
+fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
+	      register const u_char *p)
+{
+
+	error("not configured for fddi");
+	/* NOTREACHED */
+}
+#endif
diff --git a/tcpdump.tproj/print-gre.c b/tcpdump.tproj/print-gre.c
new file mode 100644
index 0000000..94e42db
--- /dev/null
+++ b/tcpdump.tproj/print-gre.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1996
+ *      The 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, Lawrence Berkeley Laboratory,
+ * Berkeley, CA.  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.
+ *
+ * Initial contribution from John Hawkinson <jhawk@bbnplanet.com>
+ *
+ * This module implements support for decoding GRE (Generic Routing
+ * Encapsulation) tunnels; they're documented in RFC1701 and RFC1702.
+ * This code only supports the IP encapsulation thereof.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-gre.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <netdb.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"		/* must come after interface.h */
+
+#define GRE_SIZE (20)
+
+struct gre {
+	u_short flags;
+	u_short proto;
+	union {
+		struct gre_ckof {
+			u_short cksum;
+			u_short offset;
+		}        gre_ckof;
+		u_int32_t key;
+		u_int32_t seq;
+	}     gre_void1;
+	union {
+		u_int32_t key;
+		u_int32_t seq;
+		u_int32_t routing;
+	}     gre_void2;
+	union {
+		u_int32_t seq;
+		u_int32_t routing;
+	}     gre_void3;
+	union {
+		u_int32_t routing;
+	}     gre_void4;
+};
+
+#define GRE_CP		0x8000	/* Checksum Present */
+#define GRE_RP		0x4000	/* Routing Present */
+#define GRE_KP		0x2000	/* Key Present */
+#define GRE_SP		0x1000	/* Sequence Present */
+
+
+#define GREPROTO_IP	0x0800
+
+
+/*
+ * Deencapsulate and print a GRE-tunneled IP datagram
+ */
+void
+gre_print(const u_char *bp, u_int length)
+{
+	const u_char *cp = bp + 4;
+	const struct gre *gre;
+	u_short flags, proto;
+
+	gre = (const struct gre *)bp;
+
+	if (length < GRE_SIZE) {
+		goto trunc;
+	}
+	flags = EXTRACT_16BITS(&gre->flags);
+	proto = EXTRACT_16BITS(&gre->proto);
+
+	if (vflag) {
+		/* Decode the flags */
+		putchar('[');
+		if (flags & GRE_CP)
+			putchar('C');
+		if (flags & GRE_RP)
+			putchar('R');
+		if (flags & GRE_KP)
+			putchar('K');
+		if (flags & GRE_SP)
+			putchar('S');
+		fputs("] ", stdout);
+	}
+	/* Checksum & Offset are present */
+	if ((flags & GRE_CP) | (flags & GRE_RP))
+		cp += 4;
+
+	/* We don't support routing fields (variable length) now. Punt. */
+	if (flags & GRE_RP)
+		return;
+
+	if (flags & GRE_KP)
+		cp += 4;
+	if (flags & GRE_SP)
+		cp += 4;
+
+	switch (proto) {
+
+	case GREPROTO_IP:
+		ip_print(cp, length - ((cp - bp) / sizeof(u_char)));
+		break;
+
+	default:
+		printf("gre-proto-0x%04X", proto);
+		break;
+	}
+	return;
+
+trunc:
+	fputs("[|gre]", stdout);
+
+}
diff --git a/tcpdump.tproj/print-icmp.c b/tcpdump.tproj/print-icmp.c
new file mode 100644
index 0000000..d4eb3fa
--- /dev/null
+++ b/tcpdump.tproj/print-icmp.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-icmp.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"			/* must come after interface.h */
+
+/* rfc1700 */
+#ifndef ICMP_UNREACH_NET_UNKNOWN
+#define ICMP_UNREACH_NET_UNKNOWN	6	/* destination net unknown */
+#endif
+#ifndef ICMP_UNREACH_HOST_UNKNOWN
+#define ICMP_UNREACH_HOST_UNKNOWN	7	/* destination host unknown */
+#endif
+#ifndef ICMP_UNREACH_ISOLATED
+#define ICMP_UNREACH_ISOLATED		8	/* source host isolated */
+#endif
+#ifndef ICMP_UNREACH_NET_PROHIB
+#define ICMP_UNREACH_NET_PROHIB		9	/* admin prohibited net */
+#endif
+#ifndef ICMP_UNREACH_HOST_PROHIB
+#define ICMP_UNREACH_HOST_PROHIB	10	/* admin prohibited host */
+#endif
+#ifndef ICMP_UNREACH_TOSNET
+#define ICMP_UNREACH_TOSNET		11	/* tos prohibited net */
+#endif
+#ifndef ICMP_UNREACH_TOSHOST
+#define ICMP_UNREACH_TOSHOST		12	/* tos prohibited host */
+#endif
+
+/* rfc1716 */
+#ifndef ICMP_UNREACH_FILTER_PROHIB
+#define ICMP_UNREACH_FILTER_PROHIB	13	/* admin prohibited filter */
+#endif
+#ifndef ICMP_UNREACH_HOST_PRECEDENCE
+#define ICMP_UNREACH_HOST_PRECEDENCE	14	/* host precedence violation */
+#endif
+#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
+#define ICMP_UNREACH_PRECEDENCE_CUTOFF	15	/* precedence cutoff */
+#endif
+
+/* rfc1256 */
+#ifndef ICMP_ROUTERADVERT
+#define ICMP_ROUTERADVERT		9	/* router advertisement */
+#endif
+#ifndef ICMP_ROUTERSOLICIT
+#define ICMP_ROUTERSOLICIT		10	/* router solicitation */
+#endif
+
+/* Most of the icmp types */
+static struct tok icmp2str[] = {
+	{ ICMP_ECHOREPLY,		"echo reply" },
+	{ ICMP_SOURCEQUENCH,		"source quench" },
+	{ ICMP_ECHO,			"echo request" },
+	{ ICMP_ROUTERSOLICIT,		"router solicitation" },
+	{ ICMP_TSTAMP,			"time stamp request" },
+	{ ICMP_TSTAMPREPLY,		"time stamp reply" },
+	{ ICMP_IREQ,			"information request" },
+	{ ICMP_IREQREPLY,		"information reply" },
+	{ ICMP_MASKREQ,			"address mask request" },
+	{ 0,				NULL }
+};
+
+/* Formats for most of the ICMP_UNREACH codes */
+static struct tok unreach2str[] = {
+	{ ICMP_UNREACH_NET,		"net %s unreachable" },
+	{ ICMP_UNREACH_HOST,		"host %s unreachable" },
+	{ ICMP_UNREACH_SRCFAIL,
+	    "%s unreachable - source route failed" },
+	{ ICMP_UNREACH_NET_UNKNOWN,	"net %s unreachable - unknown" },
+	{ ICMP_UNREACH_HOST_UNKNOWN,	"host %s unreachable - unknown" },
+	{ ICMP_UNREACH_ISOLATED,
+	    "%s unreachable - source host isolated" },
+	{ ICMP_UNREACH_NET_PROHIB,
+	    "net %s unreachable - admin prohibited" },
+	{ ICMP_UNREACH_HOST_PROHIB,
+	    "host %s unreachable - admin prohibited" },
+	{ ICMP_UNREACH_TOSNET,
+	    "net %s unreachable - tos prohibited" },
+	{ ICMP_UNREACH_TOSHOST,
+	    "host %s unreachable - tos prohibited" },
+	{ ICMP_UNREACH_FILTER_PROHIB,
+	    "host %s unreachable - admin prohibited filter" },
+	{ ICMP_UNREACH_HOST_PRECEDENCE,
+	    "host %s unreachable - host precedence violation" },
+	{ ICMP_UNREACH_PRECEDENCE_CUTOFF,
+	    "host %s unreachable - precedence cutoff" },
+	{ 0,				NULL }
+};
+
+/* Formats for the ICMP_REDIRECT codes */
+static struct tok type2str[] = {
+	{ ICMP_REDIRECT_NET,		"redirect %s to net %s" },
+	{ ICMP_REDIRECT_HOST,		"redirect %s to host %s" },
+	{ ICMP_REDIRECT_TOSNET,		"redirect-tos %s to net %s" },
+	{ ICMP_REDIRECT_TOSHOST,	"redirect-tos %s to net %s" },
+	{ 0,				NULL }
+};
+
+/* rfc1191 */
+struct mtu_discovery {
+	short unused;
+	short nexthopmtu;
+};
+
+/* rfc1256 */
+struct ih_rdiscovery {
+	u_char ird_addrnum;
+	u_char ird_addrsiz;
+	u_short ird_lifetime;
+};
+
+struct id_rdiscovery {
+	u_int32_t ird_addr;
+	u_int32_t ird_pref;
+};
+
+void
+icmp_print(register const u_char *bp, register const u_char *bp2)
+{
+	register char *cp;
+	register const struct icmp *dp;
+	register const struct ip *ip;
+	register const char *str, *fmt;
+	register const struct ip *oip;
+	register const struct udphdr *ouh;
+	register u_int hlen, dport, mtu;
+	char buf[256];
+
+	dp = (struct icmp *)bp;
+	ip = (struct ip *)bp2;
+	str = buf;
+
+        (void)printf("%s > %s: ",
+		ipaddr_string(&ip->ip_src),
+		ipaddr_string(&ip->ip_dst));
+
+	TCHECK(dp->icmp_code);
+	switch (dp->icmp_type) {
+
+	case ICMP_UNREACH:
+		TCHECK(dp->icmp_ip.ip_dst);
+		switch (dp->icmp_code) {
+
+		case ICMP_UNREACH_PROTOCOL:
+			TCHECK(dp->icmp_ip.ip_p);
+			(void)sprintf(buf, "%s protocol %d unreachable",
+				       ipaddr_string(&dp->icmp_ip.ip_dst),
+				       dp->icmp_ip.ip_p);
+			break;
+
+		case ICMP_UNREACH_PORT:
+			TCHECK(dp->icmp_ip.ip_p);
+			oip = &dp->icmp_ip;
+			hlen = oip->ip_hl * 4;
+			ouh = (struct udphdr *)(((u_char *)oip) + hlen);
+			dport = ntohs(ouh->uh_dport);
+			switch (oip->ip_p) {
+
+			case IPPROTO_TCP:
+				(void)sprintf(buf,
+					"%s tcp port %s unreachable",
+					ipaddr_string(&oip->ip_dst),
+					tcpport_string(dport));
+				break;
+
+			case IPPROTO_UDP:
+				(void)sprintf(buf,
+					"%s udp port %s unreachable",
+					ipaddr_string(&oip->ip_dst),
+					udpport_string(dport));
+				break;
+
+			default:
+				(void)sprintf(buf,
+					"%s protocol %d port %d unreachable",
+					ipaddr_string(&oip->ip_dst),
+					oip->ip_p, dport);
+				break;
+			}
+			break;
+
+		case ICMP_UNREACH_NEEDFRAG:
+			{
+			register const struct mtu_discovery *mp;
+
+			mp = (struct mtu_discovery *)&dp->icmp_void;
+                        mtu = EXTRACT_16BITS(&mp->nexthopmtu);
+                        if (mtu)
+			    (void)sprintf(buf,
+				"%s unreachable - need to frag (mtu %d)",
+				ipaddr_string(&dp->icmp_ip.ip_dst), mtu);
+                        else
+			    (void)sprintf(buf,
+				"%s unreachable - need to frag",
+				ipaddr_string(&dp->icmp_ip.ip_dst));
+			}
+			break;
+
+		default:
+			fmt = tok2str(unreach2str, "#%d %%s unreachable",
+			    dp->icmp_code);
+			(void)sprintf(buf, fmt,
+			    ipaddr_string(&dp->icmp_ip.ip_dst));
+			break;
+		}
+		break;
+
+	case ICMP_REDIRECT:
+		TCHECK(dp->icmp_ip.ip_dst);
+		fmt = tok2str(type2str, "redirect-#%d %%s to net %%s",
+		    dp->icmp_code);
+		(void)sprintf(buf, fmt,
+		    ipaddr_string(&dp->icmp_ip.ip_dst),
+		    ipaddr_string(&dp->icmp_gwaddr));
+		break;
+
+	case ICMP_ROUTERADVERT:
+		{
+		register const struct ih_rdiscovery *ihp;
+		register const struct id_rdiscovery *idp;
+		u_int lifetime, num, size;
+
+		(void)strcpy(buf, "router advertisement");
+		cp = buf + strlen(buf);
+
+		ihp = (struct ih_rdiscovery *)&dp->icmp_void;
+		TCHECK(*ihp);
+		(void)strcpy(cp, " lifetime ");
+		cp = buf + strlen(buf);
+		lifetime = EXTRACT_16BITS(&ihp->ird_lifetime);
+		if (lifetime < 60)
+			(void)sprintf(cp, "%u", lifetime);
+		else if (lifetime < 60 * 60)
+			(void)sprintf(cp, "%u:%02u",
+			    lifetime / 60, lifetime % 60);
+		else
+			(void)sprintf(cp, "%u:%02u:%02u",
+			    lifetime / 3600,
+			    (lifetime % 3600) / 60,
+			    lifetime % 60);
+		cp = buf + strlen(buf);
+
+		num = ihp->ird_addrnum;
+		(void)sprintf(cp, " %d:", num);
+		cp = buf + strlen(buf);
+
+		size = ihp->ird_addrsiz;
+		if (size != 2) {
+			(void)sprintf(cp, " [size %d]", size);
+			break;
+		}
+		idp = (struct id_rdiscovery *)&dp->icmp_data;
+		while (num-- > 0) {
+			TCHECK(*idp);
+			(void)sprintf(cp, " {%s %u}",
+			    ipaddr_string(&idp->ird_addr),
+			    EXTRACT_32BITS(&idp->ird_pref));
+			cp = buf + strlen(buf);
+		}
+		}
+		break;
+
+	case ICMP_TIMXCEED:
+		TCHECK(dp->icmp_ip.ip_dst);
+		switch (dp->icmp_code) {
+
+		case ICMP_TIMXCEED_INTRANS:
+			str = "time exceeded in-transit";
+			break;
+
+		case ICMP_TIMXCEED_REASS:
+			str = "ip reassembly time exceeded";
+			break;
+
+		default:
+			(void)sprintf(buf, "time exceeded-#%d", dp->icmp_code);
+			break;
+		}
+		break;
+
+	case ICMP_PARAMPROB:
+		if (dp->icmp_code)
+			(void)sprintf(buf, "parameter problem - code %d",
+					dp->icmp_code);
+		else {
+			TCHECK(dp->icmp_pptr);
+			(void)sprintf(buf, "parameter problem - octet %d",
+					dp->icmp_pptr);
+		}
+		break;
+
+	case ICMP_MASKREPLY:
+		TCHECK(dp->icmp_mask);
+		(void)sprintf(buf, "address mask is 0x%08x",
+		    (u_int32_t)ntohl(dp->icmp_mask));
+		break;
+
+	default:
+		str = tok2str(icmp2str, "type-#%d", dp->icmp_type);
+		break;
+	}
+        (void)printf("icmp: %s", str);
+	return;
+trunc:
+	fputs("[|icmp]", stdout);
+}
diff --git a/tcpdump.tproj/print-igrp.c b/tcpdump.tproj/print-igrp.c
new file mode 100644
index 0000000..a35e6ac
--- /dev/null
+++ b/tcpdump.tproj/print-igrp.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Initial contribution from Francis Dupont (francis.dupont@inria.fr)
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-igrp.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+#include "igrp.h"
+#include "extract.h"			/* must come after interface.h */
+
+static void
+igrp_entry_print(register struct igrprte *igr, register int is_interior,
+    register int is_exterior)
+{
+	register u_int delay, bandwidth;
+	u_int metric, mtu;
+
+	if (is_interior)
+		printf(" *.%d.%d.%d", igr->igr_net[0],
+		    igr->igr_net[1], igr->igr_net[2]);
+	else if (is_exterior)
+		printf(" X%d.%d.%d.0", igr->igr_net[0],
+		    igr->igr_net[1], igr->igr_net[2]);
+	else
+		printf(" %d.%d.%d.0", igr->igr_net[0],
+		    igr->igr_net[1], igr->igr_net[2]);
+
+	delay = EXTRACT_24BITS(igr->igr_dly);
+	bandwidth = EXTRACT_24BITS(igr->igr_bw);
+	metric = bandwidth + delay;
+	if (metric > 0xffffff)
+		metric = 0xffffff;
+	mtu = EXTRACT_16BITS(igr->igr_mtu);
+
+	printf(" d=%d b=%d r=%d l=%d M=%d mtu=%d in %d hops",
+	    10 * delay, bandwidth == 0 ? 0 : 10000000 / bandwidth,
+	    igr->igr_rel, igr->igr_ld, metric,
+	    mtu, igr->igr_hct);
+}
+
+static struct tok op2str[] = {
+	{ IGRP_UPDATE,		"update" },
+	{ IGRP_REQUEST,		"request" },
+	{ 0,			NULL }
+};
+
+void
+igrp_print(register const u_char *bp, u_int length, register const u_char *bp2)
+{
+	register struct igrphdr *hdr;
+	register struct ip *ip;
+	register u_char *cp;
+	u_int nint, nsys, next;
+
+	hdr = (struct igrphdr *)bp;
+	ip = (struct ip *)bp2;
+	cp = (u_char *)(hdr + 1);
+        (void)printf("%s > %s: igrp: ",
+	    ipaddr_string(&ip->ip_src),
+	    ipaddr_string(&ip->ip_dst));
+
+	/* Header */
+	TCHECK(*hdr);
+	nint = EXTRACT_16BITS(&hdr->ig_ni);
+	nsys = EXTRACT_16BITS(&hdr->ig_ns);
+	next = EXTRACT_16BITS(&hdr->ig_nx);
+
+	(void)printf(" %s V%d edit=%d AS=%d (%d/%d/%d)",
+	    tok2str(op2str, "op-#%d", hdr->ig_op),
+	    hdr->ig_v,
+	    hdr->ig_ed,
+	    EXTRACT_16BITS(&hdr->ig_as),
+	    nint,
+	    nsys,
+	    next);
+
+	length -= sizeof(*hdr);
+	while (length >= IGRP_RTE_SIZE) {
+		if (nint > 0) {
+			TCHECK2(*cp, IGRP_RTE_SIZE);
+			igrp_entry_print((struct igrprte *)cp, 1, 0);
+			--nint;
+		} else if (nsys > 0) {
+			TCHECK2(*cp, IGRP_RTE_SIZE);
+			igrp_entry_print((struct igrprte *)cp, 0, 0);
+			--nsys;
+		} else if (next > 0) {
+			TCHECK2(*cp, IGRP_RTE_SIZE);
+			igrp_entry_print((struct igrprte *)cp, 0, 1);
+			--next;
+		} else {
+			(void)printf("[extra bytes %d]", length);
+			break;
+		}
+		cp += IGRP_RTE_SIZE;
+		length -= IGRP_RTE_SIZE;
+	}
+	if (nint == 0 && nsys == 0 && next == 0)
+		return;
+trunc:
+	fputs("[|igrp]", stdout);
+}
diff --git a/tcpdump.tproj/print-ip.c b/tcpdump.tproj/print-ip.c
new file mode 100644
index 0000000..6c0c31c
--- /dev/null
+++ b/tcpdump.tproj/print-ip.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-ip.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+#include "extract.h"			/* must come after interface.h */
+
+/* Compatibility */
+#ifndef	IPPROTO_ND
+#define	IPPROTO_ND	77
+#endif
+
+#ifndef IN_CLASSD
+#define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000)
+#endif
+
+/* (following from ipmulti/mrouted/prune.h) */
+
+/*
+ * The packet format for a traceroute request.
+ */
+struct tr_query {
+	u_int  tr_src;			/* traceroute source */
+	u_int  tr_dst;			/* traceroute destination */
+	u_int  tr_raddr;		/* traceroute response address */
+#ifdef WORDS_BIGENDIAN
+	struct {
+		u_int   ttl : 8;	/* traceroute response ttl */
+		u_int   qid : 24;	/* traceroute query id */
+	} q;
+#else
+	struct {
+		u_int	qid : 24;	/* traceroute query id */
+		u_int	ttl : 8;	/* traceroute response ttl */
+	} q;
+#endif
+};
+
+#define tr_rttl q.ttl
+#define tr_qid  q.qid
+
+/*
+ * Traceroute response format.  A traceroute response has a tr_query at the
+ * beginning, followed by one tr_resp for each hop taken.
+ */
+struct tr_resp {
+	u_int tr_qarr;			/* query arrival time */
+	u_int tr_inaddr;		/* incoming interface address */
+	u_int tr_outaddr;		/* outgoing interface address */
+	u_int tr_rmtaddr;		/* parent address in source tree */
+	u_int tr_vifin;			/* input packet count on interface */
+	u_int tr_vifout;		/* output packet count on interface */
+	u_int tr_pktcnt;		/* total incoming packets for src-grp */
+	u_char  tr_rproto;		/* routing proto deployed on router */
+	u_char  tr_fttl;		/* ttl required to forward on outvif */
+	u_char  tr_smask;		/* subnet mask for src addr */
+	u_char  tr_rflags;		/* forwarding error codes */
+};
+
+/* defs within mtrace */
+#define TR_QUERY 1
+#define TR_RESP	2
+
+/* fields for tr_rflags (forwarding error codes) */
+#define TR_NO_ERR	0
+#define TR_WRONG_IF	1
+#define TR_PRUNED	2
+#define TR_OPRUNED	3
+#define TR_SCOPED	4
+#define TR_NO_RTE	5
+#define TR_NO_FWD	7
+#define TR_NO_SPACE	0x81
+#define TR_OLD_ROUTER	0x82
+
+/* fields for tr_rproto (routing protocol) */
+#define TR_PROTO_DVMRP	1
+#define TR_PROTO_MOSPF	2
+#define TR_PROTO_PIM	3
+#define TR_PROTO_CBT	4
+
+static void print_mtrace(register const u_char *bp, register u_int len)
+{
+	register struct tr_query *tr = (struct tr_query *)(bp + 8);
+
+	printf("mtrace %d: %s to %s reply-to %s", tr->tr_qid,
+		ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst),
+		ipaddr_string(&tr->tr_raddr));
+	if (IN_CLASSD(ntohl(tr->tr_raddr)))
+		printf(" with-ttl %d", tr->tr_rttl);
+}
+
+static void print_mresp(register const u_char *bp, register u_int len)
+{
+	register struct tr_query *tr = (struct tr_query *)(bp + 8);
+
+	printf("mresp %d: %s to %s reply-to %s", tr->tr_qid,
+		ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst),
+		ipaddr_string(&tr->tr_raddr));
+	if (IN_CLASSD(ntohl(tr->tr_raddr)))
+		printf(" with-ttl %d", tr->tr_rttl);
+}
+
+static void
+igmp_print(register const u_char *bp, register u_int len,
+	   register const u_char *bp2)
+{
+	register const struct ip *ip;
+
+	ip = (const struct ip *)bp2;
+        (void)printf("%s > %s: ",
+		ipaddr_string(&ip->ip_src),
+		ipaddr_string(&ip->ip_dst));
+
+	TCHECK2(bp[0], 8);
+	switch (bp[0]) {
+	case 0x11:
+		(void)printf("igmp query");
+		if (*(int *)&bp[4])
+			(void)printf(" [gaddr %s]", ipaddr_string(&bp[4]));
+		if (len != 8)
+			(void)printf(" [len %d]", len);
+		break;
+	case 0x12:
+		(void)printf("igmp report %s", ipaddr_string(&bp[4]));
+		if (len != 8)
+			(void)printf(" [len %d]", len);
+		break;
+	case 0x16:
+		(void)printf("igmp nreport %s", ipaddr_string(&bp[4]));
+		break;
+	case 0x17:
+		(void)printf("igmp leave %s", ipaddr_string(&bp[4]));
+		break;
+	case 0x13:
+		(void)printf("igmp dvmrp");
+		if (len < 8)
+			(void)printf(" [len %d]", len);
+		else
+			dvmrp_print(bp, len);
+		break;
+	case 0x14:
+		(void)printf("igmp pim");
+		pim_print(bp, len);
+  		break;
+	case 0x1e:
+		print_mresp(bp, len);
+		break;
+	case 0x1f:
+		print_mtrace(bp, len);
+		break;
+	default:
+		(void)printf("igmp-%d", bp[0] & 0xf);
+		break;
+	}
+	if ((bp[0] >> 4) != 1)
+		(void)printf(" [v%d]", bp[0] >> 4);
+
+	TCHECK2(bp[0], len);
+	if (vflag) {
+		/* Check the IGMP checksum */
+		u_int32_t sum = 0;
+		int count;
+		const u_short *sp = (u_short *)bp;
+		
+		for (count = len / 2; --count >= 0; )
+			sum += *sp++;
+		if (len & 1)
+			sum += ntohs(*(u_char *) sp << 8);
+		while (sum >> 16)
+			sum = (sum & 0xffff) + (sum >> 16);
+		sum = 0xffff & ~sum;
+		if (sum != 0)
+			printf(" bad igmp cksum %x!", EXTRACT_16BITS(&bp[2]));
+	}
+	return;
+trunc:
+	fputs("[|igmp]", stdout);
+}
+
+/*
+ * print the recorded route in an IP RR, LSRR or SSRR option.
+ */
+static void
+ip_printroute(const char *type, register const u_char *cp, u_int length)
+{
+	register u_int ptr = cp[2] - 1;
+	register u_int len;
+
+	printf(" %s{", type);
+	if ((length + 1) & 3)
+		printf(" [bad length %d]", length);
+	if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
+		printf(" [bad ptr %d]", cp[2]);
+
+	type = "";
+	for (len = 3; len < length; len += 4) {
+		if (ptr == len)
+			type = "#";
+		printf("%s%s", type, ipaddr_string(&cp[len]));
+		type = " ";
+	}
+	printf("%s}", ptr == len? "#" : "");
+}
+
+/*
+ * print IP options.
+ */
+static void
+ip_optprint(register const u_char *cp, u_int length)
+{
+	register u_int len;
+
+	for (; length > 0; cp += len, length -= len) {
+		int tt = *cp;
+
+		len = (tt == IPOPT_NOP || tt == IPOPT_EOL) ? 1 : cp[1];
+		if (len <= 0) {
+			printf("[|ip op len %d]", len);
+			return;
+		}
+		if (&cp[1] >= snapend || cp + len > snapend) {
+			printf("[|ip]");
+			return;
+		}
+		switch (tt) {
+
+		case IPOPT_EOL:
+			printf(" EOL");
+			if (length > 1)
+				printf("-%d", length - 1);
+			return;
+
+		case IPOPT_NOP:
+			printf(" NOP");
+			break;
+
+		case IPOPT_TS:
+			printf(" TS{%d}", len);
+			break;
+
+		case IPOPT_SECURITY:
+			printf(" SECURITY{%d}", len);
+			break;
+
+		case IPOPT_RR:
+			printf(" RR{%d}=", len);
+			ip_printroute("RR", cp, len);
+			break;
+
+		case IPOPT_SSRR:
+			ip_printroute("SSRR", cp, len);
+			break;
+
+		case IPOPT_LSRR:
+			ip_printroute("LSRR", cp, len);
+			break;
+
+		default:
+			printf(" IPOPT-%d{%d}", cp[0], len);
+			break;
+		}
+	}
+}
+
+/*
+ * compute an IP header checksum.
+ * don't modifiy the packet.
+ */
+static int
+in_cksum(const struct ip *ip)
+{
+	register const u_short *sp = (u_short *)ip;
+	register u_int32_t sum = 0;
+	register int count;
+
+	/*
+	 * No need for endian conversions.
+	 */
+	for (count = ip->ip_hl * 2; --count >= 0; )
+		sum += *sp++;
+	while (sum > 0xffff)
+		sum = (sum & 0xffff) + (sum >> 16);
+	sum = ~sum & 0xffff;
+
+	return (sum);
+}
+
+/*
+ * print an IP datagram.
+ */
+void
+ip_print(register const u_char *bp, register u_int length)
+{
+	register const struct ip *ip;
+	register u_int hlen, len, off;
+	register const u_char *cp;
+
+	ip = (const struct ip *)bp;
+#ifdef LBL_ALIGN
+	/*
+	 * If the IP header is not aligned, copy into abuf.
+	 * This will never happen with BPF.  It does happen raw packet
+	 * dumps from -r.
+	 */
+	if ((long)ip & 3) {
+		static u_char *abuf = NULL;
+		static int didwarn = 0;
+
+		if (abuf == NULL) {
+			abuf = (u_char *)malloc(snaplen);
+			if (abuf == NULL)
+				error("ip_print: malloc");
+		}
+		memcpy((char *)abuf, (char *)ip, min(length, snaplen));
+		snapend += abuf - (u_char *)ip;
+		packetp = abuf;
+		ip = (struct ip *)abuf;
+		/* We really want libpcap to give us aligned packets */
+		if (!didwarn) {
+			warning("compensating for unaligned libpcap packets");
+			++didwarn;
+		}
+	}
+#endif
+	if ((u_char *)(ip + 1) > snapend) {
+		printf("[|ip]");
+		return;
+	}
+	if (length < sizeof (struct ip)) {
+		(void)printf("truncated-ip %d", length);
+		return;
+	}
+	hlen = ip->ip_hl * 4;
+
+	len = ntohs(ip->ip_len);
+	if (length < len)
+		(void)printf("truncated-ip - %d bytes missing!",
+			len - length);
+	len -= hlen;
+
+	/*
+	 * If this is fragment zero, hand it to the next higher
+	 * level protocol.
+	 */
+	off = ntohs(ip->ip_off);
+	if ((off & 0x1fff) == 0) {
+		cp = (const u_char *)ip + hlen;
+		switch (ip->ip_p) {
+
+		case IPPROTO_TCP:
+			tcp_print(cp, len, (const u_char *)ip);
+			break;
+
+		case IPPROTO_UDP:
+			udp_print(cp, len, (const u_char *)ip);
+			break;
+
+		case IPPROTO_ICMP:
+			icmp_print(cp, (const u_char *)ip);
+			break;
+
+#ifndef IPPROTO_IGRP
+#define IPPROTO_IGRP 9
+#endif
+		case IPPROTO_IGRP:
+			igrp_print(cp, len, (const u_char *)ip);
+			break;
+
+		case IPPROTO_ND:
+			(void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
+				ipaddr_string(&ip->ip_dst));
+			(void)printf(" nd %d", len);
+			break;
+
+		case IPPROTO_EGP:
+			egp_print(cp, len, (const u_char *)ip);
+			break;
+
+#ifndef IPPROTO_OSPF
+#define IPPROTO_OSPF 89
+#endif
+		case IPPROTO_OSPF:
+			ospf_print(cp, len, (const u_char *)ip);
+			break;
+
+#ifndef IPPROTO_IGMP
+#define IPPROTO_IGMP 2
+#endif
+		case IPPROTO_IGMP:
+			igmp_print(cp, len, (const u_char *)ip);
+			break;
+
+#ifndef IPPROTO_ENCAP
+#define IPPROTO_ENCAP 4
+#endif
+		case IPPROTO_ENCAP:
+			/* ip-in-ip encapsulation */
+			if (vflag)
+				(void)printf("%s > %s: ",
+					     ipaddr_string(&ip->ip_src),
+					     ipaddr_string(&ip->ip_dst));
+			ip_print(cp, len);
+			if (! vflag) {
+				printf(" (encap)");
+				return;
+			}
+			break;
+
+#ifndef IPPROTO_GRE
+#define IPPROTO_GRE 47
+#endif
+		case IPPROTO_GRE:
+			if (vflag)
+				(void)printf("gre %s > %s: ",
+					     ipaddr_string(&ip->ip_src),
+					     ipaddr_string(&ip->ip_dst));
+			/* do it */
+			gre_print(cp, len);
+			if (! vflag) {
+				printf(" (gre encap)");
+				return;
+  			}
+  			break;
+
+		default:
+			(void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
+				ipaddr_string(&ip->ip_dst));
+			(void)printf(" ip-proto-%d %d", ip->ip_p, len);
+			break;
+		}
+	}
+	/*
+	 * for fragmented datagrams, print id:size@offset.  On all
+	 * but the last stick a "+".  For unfragmented datagrams, note
+	 * the don't fragment flag.
+	 */
+	if (off & 0x3fff) {
+		/*
+		 * if this isn't the first frag, we're missing the
+		 * next level protocol header.  print the ip addr.
+		 */
+		if (off & 0x1fff)
+			(void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
+				      ipaddr_string(&ip->ip_dst));
+		(void)printf(" (frag %d:%d@%d%s)", ntohs(ip->ip_id), len,
+			(off & 0x1fff) * 8,
+			(off & IP_MF)? "+" : "");
+	} else if (off & IP_DF)
+		(void)printf(" (DF)");
+
+	if (ip->ip_tos)
+		(void)printf(" [tos 0x%x]", (int)ip->ip_tos);
+	if (ip->ip_ttl <= 1)
+		(void)printf(" [ttl %d]", (int)ip->ip_ttl);
+
+	if (vflag) {
+		int sum;
+		char *sep = "";
+
+		printf(" (");
+		if (ip->ip_ttl > 1) {
+			(void)printf("%sttl %d", sep, (int)ip->ip_ttl);
+			sep = ", ";
+		}
+		if ((off & 0x3fff) == 0) {
+			(void)printf("%sid %d", sep, (int)ntohs(ip->ip_id));
+			sep = ", ";
+		}
+		if ((u_char *)ip + hlen <= snapend) {
+			sum = in_cksum(ip);
+			if (sum != 0) {
+				(void)printf("%sbad cksum %x!", sep,
+					     ntohs(ip->ip_sum));
+				sep = ", ";
+			}
+		}
+		if ((hlen -= sizeof(struct ip)) > 0) {
+			(void)printf("%soptlen=%d", sep, hlen);
+			ip_optprint((u_char *)(ip + 1), hlen);
+		}
+		printf(")");
+	}
+}
diff --git a/tcpdump.tproj/print-ipx.c b/tcpdump.tproj/print-ipx.c
new file mode 100644
index 0000000..f526160
--- /dev/null
+++ b/tcpdump.tproj/print-ipx.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print Novell IPX packets.
+ * Contributed by Brad Parker (brad@fcr.com).
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-ipx.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ipx.h"
+#include "extract.h"
+
+
+static const char *ipxaddr_string(u_int32_t, const u_char *);
+void ipx_decode(const struct ipxHdr *, const u_char *, u_int);
+void ipx_sap_print(const u_short *, u_int);
+void ipx_rip_print(const u_short *, u_int);
+
+/*
+ * Print IPX datagram packets.
+ */
+void
+ipx_print(const u_char *p, u_int length)
+{
+	const struct ipxHdr *ipx = (const struct ipxHdr *)p;
+
+	TCHECK(ipx->srcSkt);
+	(void)printf("%s.%x > ",
+		     ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode),
+		     EXTRACT_16BITS(&ipx->srcSkt));
+
+	(void)printf("%s.%x:",
+		     ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode),
+		     EXTRACT_16BITS(&ipx->dstSkt));
+
+	/* take length from ipx header */
+	TCHECK(ipx->length);
+	length = EXTRACT_16BITS(&ipx->length);
+
+	ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize);
+	return;
+trunc:
+	printf("[|ipx %d]", length);
+}
+
+static const char *
+ipxaddr_string(u_int32_t net, const u_char *node)
+{
+    static char line[256];
+
+    sprintf(line, "%x.%02x:%02x:%02x:%02x:%02x:%02x",
+	    net, node[0], node[1], node[2], node[3], node[4], node[5]);
+
+    return line;
+}
+
+void
+ipx_decode(const struct ipxHdr *ipx, const u_char *datap, u_int length)
+{
+    register u_short dstSkt;
+
+    dstSkt = EXTRACT_16BITS(&ipx->dstSkt);
+    switch (dstSkt) {
+      case IPX_SKT_NCP:
+	(void)printf(" ipx-ncp %d", length);
+	break;
+      case IPX_SKT_SAP:
+	ipx_sap_print((u_short *)datap, length);
+	break;
+      case IPX_SKT_RIP:
+	ipx_rip_print((u_short *)datap, length);
+	break;
+      case IPX_SKT_NETBIOS:
+	(void)printf(" ipx-netbios %d", length);
+	break;
+      case IPX_SKT_DIAGNOSTICS:
+	(void)printf(" ipx-diags %d", length);
+	break;
+      default:
+	(void)printf(" ipx-#%x %d", dstSkt, length);
+	break;
+    }
+}
+
+void
+ipx_sap_print(const u_short *ipx, u_int length)
+{
+    int command, i;
+
+    TCHECK(ipx[0]);
+    command = EXTRACT_16BITS(ipx);
+    ipx++;
+    length -= 2;
+
+    switch (command) {
+      case 1:
+      case 3:
+	if (command == 1)
+	    (void)printf("ipx-sap-req");
+	else
+	    (void)printf("ipx-sap-nearest-req");
+
+	if (length > 0) {
+	    TCHECK(ipx[1]);
+	    (void)printf(" %x '", EXTRACT_16BITS(&ipx[0]));
+	    fn_print((u_char *)&ipx[1], (u_char *)&ipx[1] + 48);
+	    putchar('\'');
+	}
+	break;
+
+      case 2:
+      case 4:
+	if (command == 2)
+	    (void)printf("ipx-sap-resp");
+	else
+	    (void)printf("ipx-sap-nearest-resp");
+
+	for (i = 0; i < 8 && length > 0; i++) {
+	    TCHECK2(ipx[27], 1);
+	    (void)printf(" %x '", EXTRACT_16BITS(&ipx[0]));
+	    fn_print((u_char *)&ipx[1], (u_char *)&ipx[1] + 48);
+	    printf("' addr %s",
+		ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (u_char *)&ipx[27]));
+	    ipx += 32;
+	    length -= 64;
+	}
+	break;
+      default:
+	    (void)printf("ipx-sap-?%x", command);
+	break;
+    }
+	return;
+trunc:
+	printf("[|ipx %d]", length);
+}
+
+void
+ipx_rip_print(const u_short *ipx, u_int length)
+{
+    int command, i;
+
+    TCHECK(ipx[0]);
+    command = EXTRACT_16BITS(ipx);
+    ipx++;
+    length -= 2;
+
+    switch (command) {
+      case 1:
+	(void)printf("ipx-rip-req");
+	if (length > 0) {
+	    TCHECK(ipx[3]);
+	    (void)printf(" %u/%d.%d", EXTRACT_32BITS(&ipx[0]),
+			 EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3]));
+	}
+	break;
+      case 2:
+	(void)printf("ipx-rip-resp");
+	for (i = 0; i < 50 && length > 0; i++) {
+	    TCHECK(ipx[3]);
+	    (void)printf(" %u/%d.%d", EXTRACT_32BITS(&ipx[0]),
+			 EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3]));
+
+	    ipx += 4;
+	    length -= 8;
+	}
+	break;
+      default:
+	    (void)printf("ipx-rip-?%x", command);
+    }
+	return;
+trunc:
+	printf("[|ipx %d]", length);
+}
+
diff --git a/tcpdump.tproj/print-isoclns.c b/tcpdump.tproj/print-isoclns.c
new file mode 100644
index 0000000..cea4a7e
--- /dev/null
+++ b/tcpdump.tproj/print-isoclns.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Matt Thomas, Digital Equipment Corporation
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-isoclns.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#define	CLNS	129
+#define	ESIS	130
+#define	ISIS	131
+#define	NULLNS	0
+
+static int osi_cksum(const u_char *, u_int, const u_char *, u_char *, u_char *);
+static void esis_print(const u_char *, u_int);
+
+void
+isoclns_print(const u_char *p, u_int length, u_int caplen,
+	      const u_char *esrc, const u_char *edst)
+{
+	if (caplen < 1) {
+		printf("[|iso-clns] ");
+		if (!eflag)
+			printf("%s > %s",
+			       etheraddr_string(esrc),
+			       etheraddr_string(edst));
+		return;
+	}
+
+	switch (*p) {
+
+	case CLNS:
+		/* esis_print(&p, &length); */
+		printf("iso-clns");
+		if (!eflag)
+			(void)printf(" %s > %s",
+				     etheraddr_string(esrc),
+				     etheraddr_string(edst));
+		break;
+
+	case ESIS:
+		printf("iso-esis");
+		if (!eflag)
+			(void)printf(" %s > %s",
+				     etheraddr_string(esrc),
+				     etheraddr_string(edst));
+		esis_print(p, length);
+		return;
+
+	case ISIS:
+		printf("iso-isis");
+		if (!eflag)
+			(void)printf(" %s > %s",
+				     etheraddr_string(esrc),
+				     etheraddr_string(edst));
+		/* isis_print(&p, &length); */
+		(void)printf(" len=%d ", length);
+		if (caplen > 1)
+			default_print_unaligned(p, caplen);
+		break;
+
+	case NULLNS:
+		printf("iso-nullns");
+		if (!eflag)
+			(void)printf(" %s > %s",
+				     etheraddr_string(esrc),
+				     etheraddr_string(edst));
+		break;
+
+	default:
+		printf("iso-clns %02x", p[0]);
+		if (!eflag)
+			(void)printf(" %s > %s",
+				     etheraddr_string(esrc),
+				     etheraddr_string(edst));
+		(void)printf(" len=%d ", length);
+		if (caplen > 1)
+			default_print_unaligned(p, caplen);
+		break;
+	}
+}
+
+#define	ESIS_REDIRECT	6
+#define	ESIS_ESH	2
+#define	ESIS_ISH	4
+
+struct esis_hdr {
+	u_char version;
+	u_char reserved;
+	u_char type;
+	u_char tmo[2];
+	u_char cksum[2];
+};
+
+static void
+esis_print(const u_char *p, u_int length)
+{
+	const u_char *ep;
+	int li = p[1];
+	const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
+	u_char cksum[2];
+	u_char off[2];
+
+	if (length == 2) {
+		if (qflag)
+			printf(" bad pkt!");
+		else
+			printf(" no header at all!");
+		return;
+	}
+	ep = p + li;
+	if (li > length) {
+		if (qflag)
+			printf(" bad pkt!");
+		else
+			printf(" LI(%d) > PDU size (%d)!", li, length);
+		return;
+	}
+	if (li < sizeof(struct esis_hdr) + 2) {
+		if (qflag)
+			printf(" bad pkt!");
+		else {
+			printf(" too short for esis header %d:", li);
+			while (--length >= 0)
+				printf("%02X", *p++);
+		}
+		return;
+	}
+	switch (eh->type & 0x1f) {
+
+	case ESIS_REDIRECT:
+		printf(" redirect");
+		break;
+
+	case ESIS_ESH:
+		printf(" esh");
+		break;
+
+	case ESIS_ISH:
+		printf(" ish");
+		break;
+
+	default:
+		printf(" type %d", eh->type & 0x1f);
+		break;
+	}
+	off[0] = eh->cksum[0];
+	off[1] = eh->cksum[1];
+	if (vflag && osi_cksum(p, li, eh->cksum, cksum, off)) {
+		printf(" bad cksum (got %02x%02x want %02x%02x)",
+		       eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]);
+		return;
+	}
+	if (eh->version != 1) {
+		printf(" unsupported version %d", eh->version);
+		return;
+	}
+	p += sizeof(*eh) + 2;
+	li -= sizeof(*eh) + 2;	/* protoid * li */
+
+	switch (eh->type & 0x1f) {
+	case ESIS_REDIRECT: {
+		const u_char *dst, *snpa, *is;
+
+		dst = p; p += *p + 1;
+		if (p > snapend)
+			return;
+		printf(" %s", isonsap_string(dst));
+		snpa = p; p += *p + 1;
+		is = p;   p += *p + 1;
+		if (p > snapend)
+			return;
+		if (p > ep) {
+			printf(" [bad li]");
+			return;
+		}
+		if (is[0] == 0)
+			printf(" > %s", etheraddr_string(&snpa[1]));
+		else
+			printf(" > %s", isonsap_string(is));
+		li = ep - p;
+		break;
+	}
+#if 0
+	case ESIS_ESH:
+		printf(" esh");
+		break;
+#endif
+	case ESIS_ISH: {
+		const u_char *is;
+
+		is = p; p += *p + 1;
+		if (p > ep) {
+			printf(" [bad li]");
+			return;
+		}
+		if (p > snapend)
+			return;
+		printf(" %s", isonsap_string(is));
+		li = ep - p;
+		break;
+	}
+
+	default:
+		(void)printf(" len=%d", length);
+		if (length && p < snapend) {
+			length = snapend - p;
+			default_print(p, length);
+		}
+		return;
+	}
+	if (vflag)
+		while (p < ep && li) {
+			int op, opli;
+			const u_char *q;
+
+			if (snapend - p < 2)
+				return;
+			if (li < 2) {
+				printf(" bad opts/li");
+				return;
+			}
+			op = *p++;
+			opli = *p++;
+			li -= 2;
+			if (opli > li) {
+				printf(" opt (%d) too long", op);
+				return;
+			}
+			li -= opli;
+			q = p;
+			p += opli;
+			if (snapend < p)
+				return;
+			if (op == 198 && opli == 2) {
+				printf(" tmo=%d", q[0] * 256 + q[1]);
+				continue;
+			}
+			printf (" %d:<", op);
+			while (--opli >= 0)
+				printf("%02x", *q++);
+			printf (">");
+		}
+}
+
+static int
+osi_cksum(register const u_char *p, register u_int len,
+	  const u_char *toff, u_char *cksum, u_char *off)
+{
+	int x, y, f = (len - ((toff - p) + 1));
+	int32_t c0 = 0, c1 = 0;
+
+	if ((cksum[0] = off[0]) == 0 && (cksum[1] = off[1]) == 0)
+		return 0;
+
+	off[0] = off[1] = 0;
+	while (--len >= 0) {
+		c0 += *p++;
+		c1 += c0;
+		c0 %= 255;
+		c1 %= 255;
+	}
+	x = (c0 * f - c1);
+	if (x < 0)
+		x = 255 - (-x % 255);
+	else
+		x %= 255;
+	y = -1 * (x + c0);
+	if (y < 0)
+		y = 255 - (-y % 255);
+	else
+		y %= 255;
+
+	off[0] = x;
+	off[1] = y;
+
+	return (off[0] != cksum[0] || off[1] != cksum[1]);
+}
diff --git a/tcpdump.tproj/print-krb.c b/tcpdump.tproj/print-krb.c
new file mode 100644
index 0000000..16116a0
--- /dev/null
+++ b/tcpdump.tproj/print-krb.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Initial contribution from John Hawkinson (jhawk@mit.edu).
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-krb.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+const u_char *c_print(register const u_char *, register const u_char *);
+const u_char *krb4_print_hdr(const u_char *);
+void krb4_print(const u_char *);
+void krb_print(const u_char *, u_int);
+
+
+#define AUTH_MSG_KDC_REQUEST			1<<1
+#define AUTH_MSG_KDC_REPLY			2<<1
+#define AUTH_MSG_APPL_REQUEST			3<<1
+#define AUTH_MSG_APPL_REQUEST_MUTUAL		4<<1
+#define AUTH_MSG_ERR_REPLY			5<<1
+#define AUTH_MSG_PRIVATE			6<<1
+#define AUTH_MSG_SAFE				7<<1
+#define AUTH_MSG_APPL_ERR			8<<1
+#define AUTH_MSG_DIE				63<<1
+
+#define KERB_ERR_OK				0
+#define KERB_ERR_NAME_EXP			1
+#define KERB_ERR_SERVICE_EXP			2
+#define KERB_ERR_AUTH_EXP			3
+#define KERB_ERR_PKT_VER			4
+#define KERB_ERR_NAME_MAST_KEY_VER		5
+#define KERB_ERR_SERV_MAST_KEY_VER		6
+#define KERB_ERR_BYTE_ORDER			7
+#define KERB_ERR_PRINCIPAL_UNKNOWN		8
+#define KERB_ERR_PRINCIPAL_NOT_UNIQUE		9
+#define KERB_ERR_NULL_KEY			10
+
+struct krb {
+    u_char pvno;		/* Protocol Version */
+    u_char type;		/* Type+B */
+};
+
+static char tstr[] = " [|kerberos]";
+
+static struct tok type2str[] = {
+    { AUTH_MSG_KDC_REQUEST,		"KDC_REQUEST" },
+    { AUTH_MSG_KDC_REPLY,		"KDC_REPLY" },
+    { AUTH_MSG_APPL_REQUEST,		"APPL_REQUEST" },
+    { AUTH_MSG_APPL_REQUEST_MUTUAL,	"APPL_REQUEST_MUTUAL" },
+    { AUTH_MSG_ERR_REPLY,		"ERR_REPLY" },
+    { AUTH_MSG_PRIVATE,			"PRIVATE" },
+    { AUTH_MSG_SAFE,			"SAFE" },
+    { AUTH_MSG_APPL_ERR,		"APPL_ERR" },
+    { AUTH_MSG_DIE,			"DIE" },
+    { 0,				NULL }
+};
+
+static struct tok kerr2str[] = {
+    { KERB_ERR_OK,			"OK" },
+    { KERB_ERR_NAME_EXP,		"NAME_EXP" },
+    { KERB_ERR_SERVICE_EXP,		"SERVICE_EXP" },
+    { KERB_ERR_AUTH_EXP,		"AUTH_EXP" },
+    { KERB_ERR_PKT_VER,			"PKT_VER" },
+    { KERB_ERR_NAME_MAST_KEY_VER,	"NAME_MAST_KEY_VER" },
+    { KERB_ERR_SERV_MAST_KEY_VER,	"SERV_MAST_KEY_VER" },
+    { KERB_ERR_BYTE_ORDER,		"BYTE_ORDER" },
+    { KERB_ERR_PRINCIPAL_UNKNOWN,	"PRINCIPAL_UNKNOWN" },
+    { KERB_ERR_PRINCIPAL_NOT_UNIQUE,	"PRINCIPAL_NOT_UNIQUE" },
+    { KERB_ERR_NULL_KEY,		"NULL_KEY"},
+    { 0,				NULL}
+};
+
+
+/* little endian (unaligned) to host byte order */
+/* XXX need to look at this... */
+#define vtohlp(x)	    ((( ((char *)(x))[0] )      )  | \
+			     (( ((char *)(x))[1] ) <<  8)  | \
+			     (( ((char *)(x))[2] ) << 16)  | \
+			     (( ((char *)(x))[3] ) << 24))
+#define vtohsp(x)          ((( ((char *)(x))[0] )      )  | \
+			     (( ((char *)(x))[1] ) <<  8))
+/* network (big endian) (unaligned) to host byte order */
+#define ntohlp(x)	    ((( ((char *)(x))[3] )      )  | \
+			     (( ((char *)(x))[2] ) <<  8)  | \
+			     (( ((char *)(x))[1] ) << 16)  | \
+			     (( ((char *)(x))[0] ) << 24))
+#define ntohsp(x)          ((( ((char *)(x))[1] )      )  | \
+			     (( ((char *)(x))[0] ) <<  8))
+
+
+
+const u_char *
+c_print(register const u_char *s, register const u_char *ep)
+{
+	register u_char c;
+	register int flag;
+
+	flag = 1;
+	while (ep == NULL || s < ep) {
+		c = *s++;
+		if (c == '\0') {
+			flag = 0;
+			break;
+		}
+		if (!isascii(c)) {
+			c = toascii(c);
+			putchar('M');
+			putchar('-');
+		}
+		if (!isprint(c)) {
+			c ^= 0x40;	/* DEL to ?, others to alpha */
+			putchar('^');
+		}
+		putchar(c);
+	}
+	if (flag)
+		return NULL;
+	return(s);
+}
+
+const u_char *
+krb4_print_hdr(const u_char *cp)
+{
+	cp+=2;
+
+#define PRINT		if ((cp=c_print(cp, snapend))==NULL) goto trunc
+
+	TCHECK2(cp, 0);
+	PRINT;
+	TCHECK2(cp, 0);
+	putchar('.'); PRINT;
+	TCHECK2(cp, 0);
+	putchar('@'); PRINT;
+	return(cp);
+
+trunc:
+	fputs(tstr, stdout);
+	return(NULL);
+
+#undef PRINT
+}
+
+void
+krb4_print(const u_char *cp)
+{
+	register const struct krb *kp;
+	u_char type;
+	u_short len;
+
+#define PRINT		if ((cp=c_print(cp, snapend))==NULL) goto trunc
+/*  True if struct krb is little endian */
+#define IS_LENDIAN(kp)	(((kp)->type & 0x01) != 0)
+#define KTOHSP(kp, cp)	(IS_LENDIAN(kp) ? vtohsp(cp) : ntohsp(cp))
+
+	kp = (struct krb *)cp;
+
+	if ((&kp->type) >= snapend) {
+		fputs(tstr, stdout);
+		return;
+	}
+
+	type = kp->type & (0xFF << 1);
+
+	printf(" %s %s: ",
+	    IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type));
+
+	switch (type) {
+
+	case AUTH_MSG_KDC_REQUEST:
+		if ((cp = krb4_print_hdr(cp)) == NULL)
+			return;
+		 cp += 4; 	  /* ctime */
+		 TCHECK2(cp, 0);
+		 printf(" %dmin ", *cp++ * 5);
+		 TCHECK2(cp, 0);
+		 PRINT;
+		 TCHECK2(cp, 0);
+		 putchar('.');  PRINT;
+		 break;
+
+	case AUTH_MSG_APPL_REQUEST:
+		cp += 2;
+		TCHECK2(cp, 0);
+		printf("v%d ", *cp++);
+		TCHECK2(cp, 0);
+		PRINT;
+		TCHECK2(cp, 0);
+		printf(" (%d)", *cp++);
+		TCHECK2(cp, 0);
+		printf(" (%d)", *cp);
+		TCHECK2(cp, 0);
+		break;
+
+	case AUTH_MSG_KDC_REPLY:
+		if ((cp = krb4_print_hdr(cp)) == NULL)
+			return;
+		cp += 10;	/* timestamp + n + exp + kvno */
+		TCHECK2(cp, 0);
+		len = KTOHSP(kp, cp);
+		printf(" (%d)", len);
+		TCHECK2(cp, 0);
+		break;
+
+	case AUTH_MSG_ERR_REPLY:
+		if ((cp = krb4_print_hdr(cp)) == NULL)
+			return;
+		cp += 4; 	  /* timestamp */
+		TCHECK2(cp, 0);
+		printf(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp)));
+		cp += 4;
+		TCHECK2(cp, 0);
+		PRINT;
+		break;
+
+	default:
+		fputs("(unknown)", stdout);
+		break;
+	}
+
+	return;
+trunc:
+	fputs(tstr, stdout);
+}
+
+void
+krb_print(const u_char *dat, u_int length)
+{
+	register const struct krb *kp;
+
+	kp = (struct krb *)dat;
+
+	if (dat >= snapend) {
+		fputs(tstr, stdout);
+		return;
+	}
+
+	switch (kp->pvno) {
+
+	case 1:
+	case 2:
+	case 3:
+		printf(" v%d", kp->pvno);
+		break;
+
+	case 4:
+		printf(" v%d", kp->pvno);
+		krb4_print((const u_char *)kp);
+		break;
+
+	case 106:
+	case 107:
+		fputs(" v5", stdout);
+		/* Decode ASN.1 here "someday" */
+		break;
+	}
+	return;
+}
diff --git a/tcpdump.tproj/print-llc.c b/tcpdump.tproj/print-llc.c
new file mode 100644
index 0000000..4deb6ed
--- /dev/null
+++ b/tcpdump.tproj/print-llc.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Code by Matt Thomas, Digital Equipment Corporation
+ *	with an awful lot of hacking by Jeffrey Mogul, DECWRL
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-llc.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"			/* must come after interface.h */
+
+#include "llc.h"
+
+static struct tok cmd2str[] = {
+	{ LLC_UI,	"ui" },
+	{ LLC_TEST,	"test" },
+	{ LLC_XID,	"xid" },
+	{ LLC_UA,	"ua" },
+	{ LLC_DISC,	"disc" },
+	{ LLC_DM,	"dm" },
+	{ LLC_SABME,	"sabme" },
+	{ LLC_FRMR,	"frmr" },
+	{ 0,		NULL }
+};
+
+/*
+ * Returns non-zero IFF it succeeds in printing the header
+ */
+int
+llc_print(const u_char *p, u_int length, u_int caplen,
+	  const u_char *esrc, const u_char *edst)
+{
+	struct llc llc;
+	register u_short et;
+	register int ret;
+
+	if (caplen < 3) {
+		(void)printf("[|llc]");
+		default_print((u_char *)p, caplen);
+		return(0);
+	}
+
+	/* Watch out for possible alignment problems */
+	memcpy((char *)&llc, (char *)p, min(caplen, sizeof(llc)));
+
+	if (llc.ssap == LLCSAP_GLOBAL && llc.dsap == LLCSAP_GLOBAL) {
+		ipx_print(p, length);
+		return (1);
+	}
+#ifdef notyet
+	else if (p[0] == 0xf0 && p[1] == 0xf0)
+		netbios_print(p, length);
+#endif
+	if (llc.ssap == LLCSAP_ISONS && llc.dsap == LLCSAP_ISONS
+	    && llc.llcui == LLC_UI) {
+		isoclns_print(p + 3, length - 3, caplen - 3, esrc, edst);
+		return (1);
+	}
+
+	if (llc.ssap == LLCSAP_SNAP && llc.dsap == LLCSAP_SNAP
+	    && llc.llcui == LLC_UI) {
+		if (caplen < sizeof(llc)) {
+		    (void)printf("[|llc-snap]");
+		    default_print((u_char *)p, caplen);
+		    return (0);
+		}
+		if (vflag)
+			(void)printf("snap %s ", protoid_string(llc.llcpi));
+
+		caplen -= sizeof(llc);
+		length -= sizeof(llc);
+		p += sizeof(llc);
+
+		/* This is an encapsulated Ethernet packet */
+		et = EXTRACT_16BITS(&llc.ethertype[0]);
+		ret = ether_encap_print(et, p, length, caplen);
+		if (ret)
+			return (ret);
+	}
+
+	if ((llc.ssap & ~LLC_GSAP) == llc.dsap) {
+		if (eflag)
+			(void)printf("%s ", llcsap_string(llc.dsap));
+		else
+			(void)printf("%s > %s %s ",
+					etheraddr_string(esrc),
+					etheraddr_string(edst),
+					llcsap_string(llc.dsap));
+	} else {
+		if (eflag)
+			(void)printf("%s > %s ",
+				llcsap_string(llc.ssap & ~LLC_GSAP),
+				llcsap_string(llc.dsap));
+		else
+			(void)printf("%s %s > %s %s ",
+				etheraddr_string(esrc),
+				llcsap_string(llc.ssap & ~LLC_GSAP),
+				etheraddr_string(edst),
+				llcsap_string(llc.dsap));
+	}
+
+	if ((llc.llcu & LLC_U_FMT) == LLC_U_FMT) {
+		const char *m;
+		char f;
+		m = tok2str(cmd2str, "%02x", LLC_U_CMD(llc.llcu));
+		switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
+		    case 0:			f = 'C'; break;
+		    case LLC_GSAP:		f = 'R'; break;
+		    case LLC_U_POLL:		f = 'P'; break;
+		    case LLC_GSAP|LLC_U_POLL:	f = 'F'; break;
+		    default:			f = '?'; break;
+		}
+
+		printf("%s/%c", m, f);
+
+		p += 3;
+		length -= 3;
+		caplen -= 3;
+
+		if ((llc.llcu & ~LLC_U_POLL) == LLC_XID) {
+		    if (*p == LLC_XID_FI) {
+			printf(": %02x %02x", p[1], p[2]);
+			p += 3;
+			length -= 3;
+			caplen -= 3;
+		    }
+		}
+	} else {
+		char f;
+		llc.llcis = ntohs(llc.llcis);
+		switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
+		    case 0:			f = 'C'; break;
+		    case LLC_GSAP:		f = 'R'; break;
+		    case LLC_U_POLL:		f = 'P'; break;
+		    case LLC_GSAP|LLC_U_POLL:	f = 'F'; break;
+		    default:			f = '?'; break;
+		}
+
+		if ((llc.llcu & LLC_S_FMT) == LLC_S_FMT) {
+			static char *llc_s[] = { "rr", "rej", "rnr", "03" };
+			(void)printf("%s (r=%d,%c)",
+				llc_s[LLC_S_CMD(llc.llcis)],
+				LLC_IS_NR(llc.llcis),
+				f);
+		} else {
+			(void)printf("I (s=%d,r=%d,%c)",
+				LLC_I_NS(llc.llcis),
+				LLC_IS_NR(llc.llcis),
+				f);
+		}
+		p += 4;
+		length -= 4;
+		caplen -= 4;
+	}
+	(void)printf(" len=%d", length);
+	if (caplen > 0) {
+		default_print_unaligned(p, caplen);
+	}
+	return(1);
+}
diff --git a/tcpdump.tproj/print-netbios.c b/tcpdump.tproj/print-netbios.c
new file mode 100644
index 0000000..fdf16a3
--- /dev/null
+++ b/tcpdump.tproj/print-netbios.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print NETBIOS packets.
+ * Contributed by Brad Parker (brad@fcr.com).
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-netbios.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "netbios.h"
+#include "extract.h"
+
+/*
+ * Print NETBIOS packets.
+ */
+void
+netbios_print(struct p8022Hdr *nb, u_int length)
+{
+	if (length < p8022Size) {
+		(void)printf(" truncated-netbios %d", length);
+		return;
+	}
+
+	if (nb->flags == UI) {
+	    (void)printf("802.1 UI ");
+	} else {
+	    (void)printf("802.1 CONN ");
+	}
+
+	if ((u_char *)(nb + 1) > snapend) {
+		printf(" [|netbios]");
+		return;
+	}
+
+/*
+	netbios_decode(nb, (u_char *)nb + p8022Size, length - p8022Size);
+*/
+}
+
+#ifdef never
+	(void)printf("%s.%d > ",
+		     ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode),
+		     EXTRACT_16BITS(ipx->srcSkt));
+
+	(void)printf("%s.%d:",
+		     ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode),
+		     EXTRACT_16BITS(ipx->dstSkt));
+
+	if ((u_char *)(ipx + 1) > snapend) {
+		printf(" [|ipx]");
+		return;
+	}
+
+	/* take length from ipx header */
+	length = EXTRACT_16BITS(&ipx->length);
+
+	ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize);
+#endif
+
diff --git a/tcpdump.tproj/print-nfs.c b/tcpdump.tproj/print-nfs.c
new file mode 100644
index 0000000..9f7b5b2
--- /dev/null
+++ b/tcpdump.tproj/print-nfs.c
@@ -0,0 +1,891 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-nfs.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <rpc/rpc.h>
+
+#include <ctype.h>
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#include "nfsv2.h"
+#include "nfsfh.h"
+
+static void nfs_printfh(const u_int32_t *);
+static void xid_map_enter(const struct rpc_msg *, const struct ip *);
+static int32_t xid_map_find(const struct rpc_msg *, const struct ip *);
+static void interp_reply(const struct rpc_msg *, u_int32_t, u_int);
+
+static int nfserr;		/* true if we error rather than trunc */
+
+void
+nfsreply_print(register const u_char *bp, u_int length,
+	       register const u_char *bp2)
+{
+	register const struct rpc_msg *rp;
+	register const struct ip *ip;
+	int32_t proc;
+
+	nfserr = 0;		/* assume no error */
+	rp = (const struct rpc_msg *)bp;
+	ip = (const struct ip *)bp2;
+
+	if (!nflag)
+		(void)printf("%s.nfs > %s.%x: reply %s %d",
+			     ipaddr_string(&ip->ip_src),
+			     ipaddr_string(&ip->ip_dst),
+			     (u_int32_t)ntohl(rp->rm_xid),
+			     ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?
+				     "ok":"ERR",
+			     length);
+	else
+		(void)printf("%s.%x > %s.%x: reply %s %d",
+			     ipaddr_string(&ip->ip_src),
+			     NFS_PORT,
+			     ipaddr_string(&ip->ip_dst),
+			     (u_int32_t)ntohl(rp->rm_xid),
+			     ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?
+			     	"ok":"ERR",
+			     length);
+
+	proc = xid_map_find(rp, ip);
+	if (proc >= 0)
+		interp_reply(rp, (u_int32_t)proc, length);
+}
+
+/*
+ * Return a pointer to the first file handle in the packet.
+ * If the packet was truncated, return 0.
+ */
+static const u_int32_t *
+parsereq(register const struct rpc_msg *rp, register u_int length)
+{
+	register const u_int32_t *dp;
+	register u_int len;
+
+	/*
+	 * find the start of the req data (if we captured it)
+	 */
+	dp = (u_int32_t *)&rp->rm_call.cb_cred;
+	TCHECK(dp[1]);
+	len = ntohl(dp[1]);
+	if (len < length) {
+		dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp);
+		TCHECK(dp[1]);
+		len = ntohl(dp[1]);
+		if (len < length) {
+			dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp);
+			TCHECK2(dp[0], 0);
+			return (dp);
+		}
+	}
+trunc:
+	return (NULL);
+}
+
+/*
+ * Print out an NFS file handle and return a pointer to following word.
+ * If packet was truncated, return 0.
+ */
+static const u_int32_t *
+parsefh(register const u_int32_t *dp)
+{
+	if (dp + 8 <= (u_int32_t *)snapend) {
+		nfs_printfh(dp);
+		return (dp + 8);
+	}
+	return (NULL);
+}
+
+/*
+ * Print out a file name and return pointer to 32-bit word past it.
+ * If packet was truncated, return 0.
+ */
+static const u_int32_t *
+parsefn(register const u_int32_t *dp)
+{
+	register u_int32_t len;
+	register const u_char *cp;
+
+	/* Bail if we don't have the string length */
+	if ((u_char *)dp > snapend - sizeof(*dp))
+		return (NULL);
+
+	/* Fetch string length; convert to host order */
+	len = *dp++;
+	NTOHL(len);
+
+	cp = (u_char *)dp;
+	/* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */
+	dp += ((len + 3) & ~3) / sizeof(*dp);
+	if ((u_char *)dp > snapend)
+		return (NULL);
+	/* XXX seems like we should be checking the length */
+	putchar('"');
+	(void) fn_printn(cp, len, NULL);
+	putchar('"');
+
+	return (dp);
+}
+
+/*
+ * Print out file handle and file name.
+ * Return pointer to 32-bit word past file name.
+ * If packet was truncated (or there was some other error), return 0.
+ */
+static const u_int32_t *
+parsefhn(register const u_int32_t *dp)
+{
+	dp = parsefh(dp);
+	if (dp == NULL)
+		return (NULL);
+	putchar(' ');
+	return (parsefn(dp));
+}
+
+void
+nfsreq_print(register const u_char *bp, u_int length,
+    register const u_char *bp2)
+{
+	register const struct rpc_msg *rp;
+	register const struct ip *ip;
+	register const u_int32_t *dp;
+
+	nfserr = 0;		/* assume no error */
+	rp = (const struct rpc_msg *)bp;
+	ip = (const struct ip *)bp2;
+	if (!nflag)
+		(void)printf("%s.%x > %s.nfs: %d",
+			     ipaddr_string(&ip->ip_src),
+			     (u_int32_t)ntohl(rp->rm_xid),
+			     ipaddr_string(&ip->ip_dst),
+			     length);
+	else
+		(void)printf("%s.%x > %s.%x: %d",
+			     ipaddr_string(&ip->ip_src),
+			     (u_int32_t)ntohl(rp->rm_xid),
+			     ipaddr_string(&ip->ip_dst),
+			     NFS_PORT,
+			     length);
+
+	xid_map_enter(rp, ip);	/* record proc number for later on */
+
+	switch (ntohl(rp->rm_call.cb_proc)) {
+#ifdef NFSPROC_NOOP
+	case NFSPROC_NOOP:
+		printf(" nop");
+		return;
+#else
+#define NFSPROC_NOOP -1
+#endif
+	case NFSPROC_NULL:
+		printf(" null");
+		return;
+
+	case NFSPROC_GETATTR:
+		printf(" getattr");
+		if ((dp = parsereq(rp, length)) != NULL && parsefh(dp) != NULL)
+			return;
+		break;
+
+	case NFSPROC_SETATTR:
+		printf(" setattr");
+		if ((dp = parsereq(rp, length)) != NULL && parsefh(dp) != NULL)
+			return;
+		break;
+
+#if NFSPROC_ROOT != NFSPROC_NOOP
+	case NFSPROC_ROOT:
+		printf(" root");
+		break;
+#endif
+	case NFSPROC_LOOKUP:
+		printf(" lookup");
+		if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL)
+			return;
+		break;
+
+	case NFSPROC_READLINK:
+		printf(" readlink");
+		if ((dp = parsereq(rp, length)) != NULL && parsefh(dp) != NULL)
+			return;
+		break;
+
+	case NFSPROC_READ:
+		printf(" read");
+		if ((dp = parsereq(rp, length)) != NULL &&
+		    (dp = parsefh(dp)) != NULL) {
+			TCHECK2(dp[0], 3 * sizeof(*dp));
+			printf(" %u bytes @ %u",
+			    (u_int32_t)ntohl(dp[1]),
+			    (u_int32_t)ntohl(dp[0]));
+			return;
+		}
+		break;
+
+#if NFSPROC_WRITECACHE != NFSPROC_NOOP
+	case NFSPROC_WRITECACHE:
+		printf(" writecache");
+		if ((dp = parsereq(rp, length)) != NULL &&
+		    (dp = parsefh(dp)) != NULL) {
+			TCHECK2(dp[0], 4 * sizeof(*dp));
+			printf(" %u (%u) bytes @ %u (%u)",
+			    (u_int32_t)ntohl(dp[3]),
+			    (u_int32_t)ntohl(dp[2]),
+			    (u_int32_t)ntohl(dp[1]),
+			    (u_int32_t)ntohl(dp[0]));
+			return;
+		}
+		break;
+#endif
+	case NFSPROC_WRITE:
+		printf(" write");
+		if ((dp = parsereq(rp, length)) != NULL &&
+		    (dp = parsefh(dp)) != NULL) {
+			TCHECK2(dp[0], 4 * sizeof(*dp));
+			printf(" %u (%u) bytes @ %u (%u)",
+			    (u_int32_t)ntohl(dp[3]),
+			    (u_int32_t)ntohl(dp[2]),
+			    (u_int32_t)ntohl(dp[1]),
+			    (u_int32_t)ntohl(dp[0]));
+			return;
+		}
+		break;
+
+	case NFSPROC_CREATE:
+		printf(" create");
+		if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL)
+			return;
+		break;
+
+	case NFSPROC_REMOVE:
+		printf(" remove");
+		if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL)
+			return;
+		break;
+
+	case NFSPROC_RENAME:
+		printf(" rename");
+		if ((dp = parsereq(rp, length)) != NULL &&
+		    (dp = parsefhn(dp)) != NULL) {
+			fputs(" ->", stdout);
+			if (parsefhn(dp) != NULL)
+				return;
+		}
+		break;
+
+	case NFSPROC_LINK:
+		printf(" link");
+		if ((dp = parsereq(rp, length)) != NULL &&
+		    (dp = parsefh(dp)) != NULL) {
+			fputs(" ->", stdout);
+			if (parsefhn(dp) != NULL)
+				return;
+		}
+		break;
+
+	case NFSPROC_SYMLINK:
+		printf(" symlink");
+		if ((dp = parsereq(rp, length)) != NULL &&
+		    (dp = parsefhn(dp)) != NULL) {
+			fputs(" -> ", stdout);
+			if (parsefn(dp) != NULL)
+				return;
+		}
+		break;
+
+	case NFSPROC_MKDIR:
+		printf(" mkdir");
+		if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL)
+			return;
+		break;
+
+	case NFSPROC_RMDIR:
+		printf(" rmdir");
+		if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL)
+			return;
+		break;
+
+	case NFSPROC_READDIR:
+		printf(" readdir");
+		if ((dp = parsereq(rp, length)) != NULL &&
+		    (dp = parsefh(dp)) != NULL) {
+			TCHECK2(dp[0], 2 * sizeof(*dp));
+			/*
+			 * Print the offset as signed, since -1 is common,
+			 * but offsets > 2^31 aren't.
+			 */
+			printf(" %u bytes @ %d",
+			    (u_int32_t)ntohl(dp[1]),
+			    (u_int32_t)ntohl(dp[0]));
+			return;
+		}
+		break;
+
+	case NFSPROC_STATFS:
+		printf(" statfs");
+		if ((dp = parsereq(rp, length)) != NULL && parsefh(dp) != NULL)
+			return;
+		break;
+
+	default:
+		printf(" proc-%u", (u_int32_t)ntohl(rp->rm_call.cb_proc));
+		return;
+	}
+trunc:
+	if (!nfserr)
+		fputs(" [|nfs]", stdout);
+}
+
+/*
+ * Print out an NFS file handle.
+ * We assume packet was not truncated before the end of the
+ * file handle pointed to by dp.
+ *
+ * Note: new version (using portable file-handle parser) doesn't produce
+ * generation number.  It probably could be made to do that, with some
+ * additional hacking on the parser code.
+ */
+static void
+nfs_printfh(register const u_int32_t *dp)
+{
+	my_fsid fsid;
+	ino_t ino;
+	char *sfsname = NULL;
+
+	Parse_fh((caddr_t *)dp, &fsid, &ino, NULL, &sfsname, 0);
+
+	if (sfsname) {
+		/* file system ID is ASCII, not numeric, for this server OS */
+		static char temp[NFS_FHSIZE+1];
+
+		/* Make sure string is null-terminated */
+		strncpy(temp, sfsname, NFS_FHSIZE);
+		/* Remove trailing spaces */
+		sfsname = strchr(temp, ' ');
+		if (sfsname)
+			*sfsname = 0;
+
+		(void)printf(" fh %s/%u", temp, (u_int32_t)ino);
+	} else {
+		(void)printf(" fh %u,%u/%u",
+		    fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor, (u_int32_t)ino);
+	}
+}
+
+/*
+ * Maintain a small cache of recent client.XID.server/proc pairs, to allow
+ * us to match up replies with requests and thus to know how to parse
+ * the reply.
+ */
+
+struct xid_map_entry {
+	u_int32_t		xid;		/* transaction ID (net order) */
+	struct in_addr	client;		/* client IP address (net order) */
+	struct in_addr	server;		/* server IP address (net order) */
+	u_int32_t		proc;		/* call proc number (host order) */
+};
+
+/*
+ * Map entries are kept in an array that we manage as a ring;
+ * new entries are always added at the tail of the ring.  Initially,
+ * all the entries are zero and hence don't match anything.
+ */
+
+#define	XIDMAPSIZE	64
+
+struct xid_map_entry xid_map[XIDMAPSIZE];
+
+int	xid_map_next = 0;
+int	xid_map_hint = 0;
+
+static void
+xid_map_enter(const struct rpc_msg *rp, const struct ip *ip)
+{
+	struct xid_map_entry *xmep;
+
+	xmep = &xid_map[xid_map_next];
+
+	if (++xid_map_next >= XIDMAPSIZE)
+		xid_map_next = 0;
+
+	xmep->xid = rp->rm_xid;
+	xmep->client = ip->ip_src;
+	xmep->server = ip->ip_dst;
+	xmep->proc = ntohl(rp->rm_call.cb_proc);
+}
+
+/* Returns NFSPROC_xxx or -1 on failure */
+static int32_t
+xid_map_find(const struct rpc_msg *rp, const struct ip *ip)
+{
+	int i;
+	struct xid_map_entry *xmep;
+	u_int32_t xid = rp->rm_xid;
+	u_int32_t clip = ip->ip_dst.s_addr;
+	u_int32_t sip = ip->ip_src.s_addr;
+
+	/* Start searching from where we last left off */
+	i = xid_map_hint;
+	do {
+		xmep = &xid_map[i];
+		if (xmep->xid == xid && xmep->client.s_addr == clip &&
+		    xmep->server.s_addr == sip) {
+			/* match */
+			xid_map_hint = i;
+			return ((int32_t)xmep->proc);
+		}
+		if (++i >= XIDMAPSIZE)
+			i = 0;
+	} while (i != xid_map_hint);
+
+	/* search failed */
+	return (-1);
+}
+
+/*
+ * Routines for parsing reply packets
+ */
+
+/*
+ * Return a pointer to the beginning of the actual results.
+ * If the packet was truncated, return 0.
+ */
+static const u_int32_t *
+parserep(register const struct rpc_msg *rp, register u_int length)
+{
+	register const u_int32_t *dp;
+	u_int len;
+	enum accept_stat astat;
+
+	/*
+	 * Portability note:
+	 * Here we find the address of the ar_verf credentials.
+	 * Originally, this calculation was
+	 *	dp = (u_int32_t *)&rp->rm_reply.rp_acpt.ar_verf
+	 * On the wire, the rp_acpt field starts immediately after
+	 * the (32 bit) rp_stat field.  However, rp_acpt (which is a
+	 * "struct accepted_reply") contains a "struct opaque_auth",
+	 * whose internal representation contains a pointer, so on a
+	 * 64-bit machine the compiler inserts 32 bits of padding
+	 * before rp->rm_reply.rp_acpt.ar_verf.  So, we cannot use
+	 * the internal representation to parse the on-the-wire
+	 * representation.  Instead, we skip past the rp_stat field,
+	 * which is an "enum" and so occupies one 32-bit word.
+	 */
+	dp = ((const u_int32_t *)&rp->rm_reply) + 1;
+	TCHECK2(dp[0], 1);
+	len = ntohl(dp[1]);
+	if (len >= length)
+		return (NULL);
+	/*
+	 * skip past the ar_verf credentials.
+	 */
+	dp += (len + (2*sizeof(u_int32_t) + 3)) / sizeof(u_int32_t);
+	TCHECK2(dp[0], 0);
+
+	/*
+	 * now we can check the ar_stat field
+	 */
+	astat = ntohl(*(enum accept_stat *)dp);
+	switch (astat) {
+
+	case SUCCESS:
+		break;
+
+	case PROG_UNAVAIL:
+		printf(" PROG_UNAVAIL");
+		nfserr = 1;		/* suppress trunc string */
+		return (NULL);
+
+	case PROG_MISMATCH:
+		printf(" PROG_MISMATCH");
+		nfserr = 1;		/* suppress trunc string */
+		return (NULL);
+
+	case PROC_UNAVAIL:
+		printf(" PROC_UNAVAIL");
+		nfserr = 1;		/* suppress trunc string */
+		return (NULL);
+
+	case GARBAGE_ARGS:
+		printf(" GARBAGE_ARGS");
+		nfserr = 1;		/* suppress trunc string */
+		return (NULL);
+
+	case SYSTEM_ERR:
+		printf(" SYSTEM_ERR");
+		nfserr = 1;		/* suppress trunc string */
+		return (NULL);
+
+	default:
+		printf(" ar_stat %d", astat);
+		nfserr = 1;		/* suppress trunc string */
+		return (NULL);
+	}
+	/* successful return */
+	if ((sizeof(astat) + ((u_char *)dp)) < snapend)
+		return ((u_int32_t *) (sizeof(astat) + ((char *)dp)));
+
+trunc:
+	return (NULL);
+}
+
+static const u_int32_t *
+parsestatus(const u_int32_t *dp)
+{
+	register int errnum;
+
+	TCHECK(dp[0]);
+	errnum = ntohl(dp[0]);
+	if (errnum != 0) {
+		if (!qflag)
+			printf(" ERROR: %s", pcap_strerror(errnum));
+		nfserr = 1;		/* suppress trunc string */
+		return (NULL);
+	}
+	return (dp + 1);
+trunc:
+	return (NULL);
+}
+
+static struct tok type2str[] = {
+	{ NFNON,	"NON" },
+	{ NFREG,	"REG" },
+	{ NFDIR,	"DIR" },
+	{ NFBLK,	"BLK" },
+	{ NFCHR,	"CHR" },
+	{ NFLNK,	"LNK" },
+	{ 0,		NULL }
+};
+
+static const u_int32_t *
+parsefattr(const u_int32_t *dp, int verbose)
+{
+	const struct nfsv2_fattr *fap;
+
+	fap = (const struct nfsv2_fattr *)dp;
+	if (verbose) {
+		TCHECK(fap->fa_nfssize);
+		printf(" %s %o ids %u/%u sz %u ",
+		    tok2str(type2str, "unk-ft %d ",
+		    (u_int32_t)ntohl(fap->fa_type)),
+		    (u_int32_t)ntohl(fap->fa_mode),
+		    (u_int32_t)ntohl(fap->fa_uid),
+		    (u_int32_t)ntohl(fap->fa_gid),
+		    (u_int32_t)ntohl(fap->fa_nfssize));
+	}
+	/* print lots more stuff */
+	if (verbose > 1) {
+		TCHECK(fap->fa_nfsfileid);
+		printf("nlink %u rdev %x fsid %x nodeid %x a/m/ctime ",
+		    (u_int32_t)ntohl(fap->fa_nlink),
+		    (u_int32_t)ntohl(fap->fa_nfsrdev),
+		    (u_int32_t)ntohl(fap->fa_nfsfsid),
+		    (u_int32_t)ntohl(fap->fa_nfsfileid));
+		TCHECK(fap->fa_nfsatime);
+		printf("%u.%06u ",
+		    (u_int32_t)ntohl(fap->fa_nfsatime.nfs_sec),
+		    (u_int32_t)ntohl(fap->fa_nfsatime.nfs_usec));
+		TCHECK(fap->fa_nfsmtime);
+		printf("%u.%06u ",
+		    (u_int32_t)ntohl(fap->fa_nfsmtime.nfs_sec),
+		    (u_int32_t)ntohl(fap->fa_nfsmtime.nfs_usec));
+		TCHECK(fap->fa_nfsctime);
+		printf("%u.%06u ",
+		    (u_int32_t)ntohl(fap->fa_nfsctime.nfs_sec),
+		    (u_int32_t)ntohl(fap->fa_nfsctime.nfs_usec));
+	}
+	return ((const u_int32_t *)&fap[1]);
+trunc:
+	return (NULL);
+}
+
+static int
+parseattrstat(const u_int32_t *dp, int verbose)
+{
+
+	dp = parsestatus(dp);
+	if (dp == NULL)
+		return (0);
+
+	return (parsefattr(dp, verbose) != NULL);
+}
+
+static int
+parsediropres(const u_int32_t *dp)
+{
+
+	dp = parsestatus(dp);
+	if (dp == NULL)
+		return (0);
+
+	dp = parsefh(dp);
+	if (dp == NULL)
+		return (0);
+
+	return (parsefattr(dp, vflag) != NULL);
+}
+
+static int
+parselinkres(const u_int32_t *dp)
+{
+	dp = parsestatus(dp);
+	if (dp == NULL)
+		return (0);
+
+	putchar(' ');
+	return (parsefn(dp) != NULL);
+}
+
+static int
+parsestatfs(const u_int32_t *dp)
+{
+	const struct nfsv2_statfs *sfsp;
+
+	dp = parsestatus(dp);
+	if (dp == NULL)
+		return (0);
+
+	if (!qflag) {
+		sfsp = (const struct nfsv2_statfs *)dp;
+		TCHECK(sfsp->sf_bavail);
+		printf(" tsize %u bsize %u blocks %u bfree %u bavail %u",
+		    (u_int32_t)ntohl(sfsp->sf_tsize),
+		    (u_int32_t)ntohl(sfsp->sf_bsize),
+		    (u_int32_t)ntohl(sfsp->sf_blocks),
+		    (u_int32_t)ntohl(sfsp->sf_bfree),
+		    (u_int32_t)ntohl(sfsp->sf_bavail));
+	}
+
+	return (1);
+trunc:
+	return (0);
+}
+
+static int
+parserddires(const u_int32_t *dp)
+{
+	dp = parsestatus(dp);
+	if (dp == NULL)
+		return (0);
+	if (!qflag) {
+		TCHECK(dp[0]);
+		printf(" offset %x", (u_int32_t)ntohl(dp[0]));
+		TCHECK(dp[1]);
+		printf(" size %u", (u_int32_t)ntohl(dp[1]));
+		TCHECK(dp[2]);
+		if (dp[2] != 0)
+			printf(" eof");
+	}
+
+	return (1);
+trunc:
+	return (0);
+}
+
+static void
+interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int length)
+{
+	register const u_int32_t *dp;
+
+	switch (proc) {
+
+#ifdef NFSPROC_NOOP
+	case NFSPROC_NOOP:
+		printf(" nop");
+		return;
+#else
+#define NFSPROC_NOOP -1
+#endif
+	case NFSPROC_NULL:
+		printf(" null");
+		return;
+
+	case NFSPROC_GETATTR:
+		printf(" getattr");
+		dp = parserep(rp, length);
+		if (dp != NULL && parseattrstat(dp, !qflag) != 0)
+			return;
+		break;
+
+	case NFSPROC_SETATTR:
+		printf(" setattr");
+		dp = parserep(rp, length);
+		if (dp != NULL && parseattrstat(dp, !qflag) != 0)
+			return;
+		break;
+
+#if NFSPROC_ROOT != NFSPROC_NOOP
+	case NFSPROC_ROOT:
+		printf(" root");
+		break;
+#endif
+	case NFSPROC_LOOKUP:
+		printf(" lookup");
+		dp = parserep(rp, length);
+		if (dp != NULL && parsediropres(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_READLINK:
+		printf(" readlink");
+		dp = parserep(rp, length);
+		if (dp != NULL && parselinkres(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_READ:
+		printf(" read");
+		dp = parserep(rp, length);
+		if (dp != NULL && parseattrstat(dp, vflag) != 0)
+			return;
+		break;
+
+#if NFSPROC_WRITECACHE != NFSPROC_NOOP
+	case NFSPROC_WRITECACHE:
+		printf(" writecache");
+		break;
+#endif
+	case NFSPROC_WRITE:
+		printf(" write");
+		dp = parserep(rp, length);
+		if (dp != NULL && parseattrstat(dp, vflag) != 0)
+			return;
+		break;
+
+	case NFSPROC_CREATE:
+		printf(" create");
+		dp = parserep(rp, length);
+		if (dp != NULL && parsediropres(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_REMOVE:
+		printf(" remove");
+		dp = parserep(rp, length);
+		if (dp != NULL && parsestatus(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_RENAME:
+		printf(" rename");
+		dp = parserep(rp, length);
+		if (dp != NULL && parsestatus(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_LINK:
+		printf(" link");
+		dp = parserep(rp, length);
+		if (dp != NULL && parsestatus(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_SYMLINK:
+		printf(" symlink");
+		dp = parserep(rp, length);
+		if (dp != NULL && parsestatus(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_MKDIR:
+		printf(" mkdir");
+		dp = parserep(rp, length);
+		if (dp != NULL && parsediropres(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_RMDIR:
+		printf(" rmdir");
+		dp = parserep(rp, length);
+		if (dp != NULL && parsestatus(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_READDIR:
+		printf(" readdir");
+		dp = parserep(rp, length);
+		if (dp != NULL && parserddires(dp) != 0)
+			return;
+		break;
+
+	case NFSPROC_STATFS:
+		printf(" statfs");
+		dp = parserep(rp, length);
+		if (dp != NULL && parsestatfs(dp) != 0)
+			return;
+		break;
+
+	default:
+		printf(" proc-%u", proc);
+		return;
+	}
+	if (!nfserr)
+		fputs(" [|nfs]", stdout);
+}
diff --git a/tcpdump.tproj/print-ntp.c b/tcpdump.tproj/print-ntp.c
new file mode 100644
index 0000000..52931a7
--- /dev/null
+++ b/tcpdump.tproj/print-ntp.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print ntp packets.
+ *	By Jeffrey Mogul/DECWRL
+ *	loosely based on print-bootp.c
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-ntp.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#undef MODEMASK					/* Solaris sucks */
+#include "ntp.h"
+
+static void p_sfix(const struct s_fixedpt *);
+static void p_ntp_time(const struct l_fixedpt *);
+static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *);
+
+/*
+ * Print ntp requests
+ */
+void
+ntp_print(register const u_char *cp, u_int length)
+{
+	register const struct ntpdata *bp;
+	int mode, version, leapind;
+	static char rclock[5];
+
+	bp = (struct ntpdata *)cp;
+	/* Note funny sized packets */
+	if (length != sizeof(struct ntpdata))
+		(void)printf(" [len=%d]", length);
+
+	TCHECK(bp->status);
+
+	version = (int)(bp->status & VERSIONMASK) >> 3;
+	printf(" v%d", version);
+
+	leapind = bp->status & LEAPMASK;
+	switch (leapind) {
+
+	case NO_WARNING:
+		break;
+
+	case PLUS_SEC:
+		fputs(" +1s", stdout);
+		break;
+
+	case MINUS_SEC:
+		fputs(" -1s", stdout);
+		break;
+	}
+
+	mode = bp->status & MODEMASK;
+	switch (mode) {
+
+	case MODE_UNSPEC:	/* unspecified */
+		fputs(" unspec", stdout);
+		break;
+
+	case MODE_SYM_ACT:	/* symmetric active */
+		fputs(" sym_act", stdout);
+		break;
+
+	case MODE_SYM_PAS:	/* symmetric passive */
+		fputs(" sym_pas", stdout);
+		break;
+
+	case MODE_CLIENT:	/* client */
+		fputs(" client", stdout);
+		break;
+
+	case MODE_SERVER:	/* server */
+		fputs(" server", stdout);
+		break;
+
+	case MODE_BROADCAST:	/* broadcast */
+		fputs(" bcast", stdout);
+		break;
+
+	case MODE_RES1:		/* reserved */
+		fputs(" res1", stdout);
+		break;
+
+	case MODE_RES2:		/* reserved */
+		fputs(" res2", stdout);
+		break;
+
+	}
+
+	TCHECK(bp->stratum);
+	printf(" strat %d", bp->stratum);
+
+	TCHECK(bp->ppoll);
+	printf(" poll %d", bp->ppoll);
+
+	/* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */
+	TCHECK2(bp->distance, 0);
+	printf(" prec %d", bp->precision);
+
+	if (!vflag)
+		return;
+
+	TCHECK(bp->distance);
+	fputs(" dist ", stdout);
+	p_sfix(&bp->distance);
+
+	TCHECK(bp->dispersion);
+	fputs(" disp ", stdout);
+	p_sfix(&bp->dispersion);
+
+	TCHECK(bp->refid);
+	fputs(" ref ", stdout);
+	/* Interpretation depends on stratum */
+	switch (bp->stratum) {
+
+	case UNSPECIFIED:
+		printf("(unspec)");
+		break;
+
+	case PRIM_REF:
+		strncpy(rclock, (char *)&(bp->refid), 4);
+		rclock[4] = '\0';
+		fputs(rclock, stdout);
+		break;
+
+	case INFO_QUERY:
+		printf("%s INFO_QUERY", ipaddr_string(&(bp->refid)));
+		/* this doesn't have more content */
+		return;
+
+	case INFO_REPLY:
+		printf("%s INFO_REPLY", ipaddr_string(&(bp->refid)));
+		/* this is too complex to be worth printing */
+		return;
+
+	default:
+		printf("%s", ipaddr_string(&(bp->refid)));
+		break;
+	}
+
+	TCHECK(bp->reftime);
+	putchar('@');
+	p_ntp_time(&(bp->reftime));
+
+	TCHECK(bp->org);
+	fputs(" orig ", stdout);
+	p_ntp_time(&(bp->org));
+
+	TCHECK(bp->rec);
+	fputs(" rec ", stdout);
+	p_ntp_delta(&(bp->org), &(bp->rec));
+
+	TCHECK(bp->xmt);
+	fputs(" xmt ", stdout);
+	p_ntp_delta(&(bp->org), &(bp->xmt));
+
+	return;
+
+trunc:
+	fputs(" [|ntp]", stdout);
+}
+
+static void
+p_sfix(register const struct s_fixedpt *sfp)
+{
+	register int i;
+	register int f;
+	register float ff;
+
+	i = ntohs(sfp->int_part);
+	f = ntohs(sfp->fraction);
+	ff = f / 65536.0;	/* shift radix point by 16 bits */
+	f = ff * 1000000.0;	/* Treat fraction as parts per million */
+	printf("%d.%06d", i, f);
+}
+
+#define	FMAXINT	(4294967296.0)	/* floating point rep. of MAXINT */
+
+static void
+p_ntp_time(register const struct l_fixedpt *lfp)
+{
+	register int32_t i;
+	register u_int32_t uf;
+	register u_int32_t f;
+	register float ff;
+
+	i = ntohl(lfp->int_part);
+	uf = ntohl(lfp->fraction);
+	ff = uf;
+	if (ff < 0.0)		/* some compilers are buggy */
+		ff += FMAXINT;
+	ff = ff / FMAXINT;	/* shift radix point by 32 bits */
+	f = ff * 1000000000.0;	/* treat fraction as parts per billion */
+	printf("%u.%09d", i, f);
+}
+
+/* Prints time difference between *lfp and *olfp */
+static void
+p_ntp_delta(register const struct l_fixedpt *olfp,
+	    register const struct l_fixedpt *lfp)
+{
+	register int32_t i;
+	register u_int32_t uf;
+	register u_int32_t ouf;
+	register u_int32_t f;
+	register float ff;
+	int signbit;
+
+	i = ntohl(lfp->int_part) - ntohl(olfp->int_part);
+
+	uf = ntohl(lfp->fraction);
+	ouf = ntohl(olfp->fraction);
+
+	if (i > 0) {		/* new is definitely greater than old */
+		signbit = 0;
+		f = uf - ouf;
+		if (ouf > uf)	/* must borrow from high-order bits */
+			i -= 1;
+	} else if (i < 0) {	/* new is definitely less than old */
+		signbit = 1;
+		f = ouf - uf;
+		if (uf > ouf)	/* must carry into the high-order bits */
+			i += 1;
+		i = -i;
+	} else {		/* int_part is zero */
+		if (uf > ouf) {
+			signbit = 0;
+			f = uf - ouf;
+		} else {
+			signbit = 1;
+			f = ouf - uf;
+		}
+	}
+
+	ff = f;
+	if (ff < 0.0)		/* some compilers are buggy */
+		ff += FMAXINT;
+	ff = ff / FMAXINT;	/* shift radix point by 32 bits */
+	f = ff * 1000000000.0;	/* treat fraction as parts per billion */
+	if (signbit)
+		putchar('-');
+	else
+		putchar('+');
+	printf("%d.%09d", i, f);
+}
diff --git a/tcpdump.tproj/print-null.c b/tcpdump.tproj/print-null.c
new file mode 100644
index 0000000..7dcf69b
--- /dev/null
+++ b/tcpdump.tproj/print-null.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1991, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-null.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+
+#define	NULL_HDRLEN 4
+
+#ifndef AF_NS
+#define AF_NS		6		/* XEROX NS protocols */
+#endif
+
+static void
+null_print(const u_char *p, const struct ip *ip, u_int length)
+{
+	u_int family;
+
+	memcpy((char *)&family, (char *)p, sizeof(family));
+
+	if (nflag) {
+		/* XXX just dump the header */
+		return;
+	}
+	switch (family) {
+
+	case AF_INET:
+		printf("ip: ");
+		break;
+
+	case AF_NS:
+		printf("ns: ");
+		break;
+
+	default:
+		printf("AF %d: ", family);
+		break;
+	}
+}
+
+void
+null_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+	u_int length = h->len;
+	u_int caplen = h->caplen;
+	const struct ip *ip;
+
+	ts_print(&h->ts);
+
+	/*
+	 * Some printers want to get back at the link level addresses,
+	 * and/or check that they're not walking off the end of the packet.
+	 * Rather than pass them all the way down, we set these globals.
+	 */
+	packetp = p;
+	snapend = p + caplen;
+
+	length -= NULL_HDRLEN;
+
+	ip = (struct ip *)(p + NULL_HDRLEN);
+
+	if (eflag)
+		null_print(p, ip, length);
+
+	ip_print((const u_char *)ip, length);
+
+	if (xflag)
+		default_print((const u_char *)ip, caplen - NULL_HDRLEN);
+	putchar('\n');
+}
+
diff --git a/tcpdump.tproj/print-ospf.c b/tcpdump.tproj/print-ospf.c
new file mode 100644
index 0000000..5012fb8
--- /dev/null
+++ b/tcpdump.tproj/print-ospf.c
@@ -0,0 +1,603 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-ospf.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <ctype.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#include "ospf.h"
+
+struct bits {
+	u_int32_t bit;
+	const char *str;
+};
+
+static const struct bits ospf_option_bits[] = {
+	{ OSPF_OPTION_T,	"T" },
+	{ OSPF_OPTION_E,	"E" },
+	{ OSPF_OPTION_MC,	"MC" },
+	{ 0,			NULL }
+};
+
+static const struct bits ospf_rla_flag_bits[] = {
+	{ RLA_FLAG_B,		"B" },
+	{ RLA_FLAG_E,		"E" },
+	{ RLA_FLAG_W1,		"W1" },
+	{ RLA_FLAG_W2,		"W2" },
+	{ 0,			NULL }
+};
+
+static struct tok type2str[] = {
+	{ OSPF_TYPE_UMD,	"umd" },
+	{ OSPF_TYPE_HELLO,	"hello" },
+	{ OSPF_TYPE_DB,		"dd" },
+	{ OSPF_TYPE_LSR,	"ls_req" },
+	{ OSPF_TYPE_LSU,	"ls_upd" },
+	{ OSPF_TYPE_LSA,	"ls_ack" },
+	{ 0,			NULL }
+};
+
+static char tstr[] = " [|ospf]";
+
+/* Forwards */
+static inline void ospf_print_seqage(u_int32_t, time_t);
+static inline void ospf_print_bits(const struct bits *, u_char);
+static void ospf_print_ls_type(u_int, const struct in_addr *,
+    const struct in_addr *, const char *);
+static int ospf_print_lshdr(const struct lsa_hdr *);
+static int ospf_print_lsa(const struct lsa *);
+static int ospf_decode_v2(const struct ospfhdr *, const u_char *);
+
+static inline void
+ospf_print_seqage(register u_int32_t seq, register time_t us)
+{
+	register time_t sec = us % 60;
+	register time_t mins = (us / 60) % 60;
+	register time_t hour = us / 3600;
+
+	printf(" S %X age ", seq);
+	if (hour)
+		printf("%u:%02u:%02u",
+		    (u_int32_t) hour, (u_int32_t) mins, (u_int32_t) sec);
+	else if (mins)
+		printf("%u:%02u", (u_int32_t) mins, (u_int32_t) sec);
+	else
+		printf("%u", (u_int32_t) sec);
+}
+
+
+static inline void
+ospf_print_bits(register const struct bits *bp, register u_char options)
+{
+	register char sep = ' ';
+
+	do {
+		if (options & bp->bit) {
+			printf("%c%s", sep, bp->str);
+			sep = '/';
+		}
+	} while ((++bp)->bit);
+}
+
+static void
+ospf_print_ls_type(register u_int ls_type,
+    register const struct in_addr *ls_stateid,
+    register const struct in_addr *ls_router, register const char *fmt)
+{
+
+	switch (ls_type) {
+
+	case LS_TYPE_ROUTER:
+		printf(" rtr %s ", ipaddr_string(ls_router));
+		break;
+
+	case LS_TYPE_NETWORK:
+		printf(" net dr %s if %s",
+		    ipaddr_string(ls_router),
+		    ipaddr_string(ls_stateid));
+		break;
+
+	case LS_TYPE_SUM_IP:
+		printf(" sum %s abr %s",
+		    ipaddr_string(ls_stateid),
+		    ipaddr_string(ls_router));
+		break;
+
+	case LS_TYPE_SUM_ABR:
+		printf(" abr %s rtr %s",
+		    ipaddr_string(ls_router),
+		    ipaddr_string(ls_stateid));
+		break;
+
+	case LS_TYPE_ASE:
+		printf(" ase %s asbr %s",
+		    ipaddr_string(ls_stateid),
+		    ipaddr_string(ls_router));
+		break;
+
+	case LS_TYPE_GROUP:
+		printf(" group %s rtr %s",
+		    ipaddr_string(ls_stateid),
+		    ipaddr_string(ls_router));
+		break;
+
+	default:
+		putchar(' ');
+		printf(fmt, ls_type);
+		break;
+	}
+}
+
+static int
+ospf_print_lshdr(register const struct lsa_hdr *lshp)
+{
+
+	TCHECK(lshp->ls_type);
+	printf(" {");						/* } (ctags) */
+
+	TCHECK(lshp->ls_options);
+	ospf_print_bits(ospf_option_bits, lshp->ls_options);
+	TCHECK(lshp->ls_seq);
+	ospf_print_seqage(ntohl(lshp->ls_seq), ntohs(lshp->ls_age));
+	ospf_print_ls_type(lshp->ls_type, &lshp->ls_stateid, &lshp->ls_router,
+	    "ls_type %d");
+
+	return (0);
+trunc:
+	return (1);
+}
+
+
+/*
+ * Print a single link state advertisement.  If truncated return 1, else 0.
+ */
+static int
+ospf_print_lsa(register const struct lsa *lsap)
+{
+	register const u_char *ls_end;
+	register const struct rlalink *rlp;
+	register const struct tos_metric *tosp;
+	register const struct in_addr *ap;
+	register const struct aslametric *almp;
+	register const struct mcla *mcp;
+	register const u_int32_t *lp;
+	register int j, k;
+
+	if (ospf_print_lshdr(&lsap->ls_hdr))
+		return (1);
+	TCHECK(lsap->ls_hdr.ls_length);
+	ls_end = (u_char *)lsap + ntohs(lsap->ls_hdr.ls_length);
+	switch (lsap->ls_hdr.ls_type) {
+
+	case LS_TYPE_ROUTER:
+		TCHECK(lsap->lsa_un.un_rla.rla_flags);
+		ospf_print_bits(ospf_rla_flag_bits,
+		    lsap->lsa_un.un_rla.rla_flags);
+
+		TCHECK(lsap->lsa_un.un_rla.rla_count);
+		j = ntohs(lsap->lsa_un.un_rla.rla_count);
+		TCHECK(lsap->lsa_un.un_rla.rla_link);
+		rlp = lsap->lsa_un.un_rla.rla_link;
+		while (j--) {
+			register struct rlalink *rln =
+			    (struct rlalink *)((u_char *)(rlp + 1) +
+			    ((rlp->link_toscount) * sizeof(*tosp)));
+
+			TCHECK(*rln);
+			printf(" {");				/* } (ctags) */
+			switch (rlp->link_type) {
+
+			case RLA_TYPE_VIRTUAL:
+				printf(" virt");
+				/* Fall through */
+
+			case RLA_TYPE_ROUTER:
+				printf(" nbrid %s if %s",
+				    ipaddr_string(&rlp->link_id),
+				    ipaddr_string(&rlp->link_data));
+				break;
+
+			case RLA_TYPE_TRANSIT:
+				printf(" dr %s if %s",
+				    ipaddr_string(&rlp->link_id),
+				    ipaddr_string(&rlp->link_data));
+				break;
+
+			case RLA_TYPE_STUB:
+				printf(" net %s mask %s",
+				    ipaddr_string(&rlp->link_id),
+				    ipaddr_string(&rlp->link_data));
+				break;
+
+			default:
+								/* { (ctags) */
+				printf(" ??RouterLinksType %d?? }",
+				    rlp->link_type);
+				return (0);
+			}
+			printf(" tos 0 metric %d", ntohs(rlp->link_tos0metric));
+			tosp = (struct tos_metric *)
+			    ((sizeof rlp->link_tos0metric) + (u_char *) rlp);
+			for (k = 0; k < (int) rlp->link_toscount; ++k, ++tosp) {
+				TCHECK(*tosp);
+				printf(" tos %d metric %d",
+				    tosp->tos_type,
+				    ntohs(tosp->tos_metric));
+			}
+								/* { (ctags) */
+			printf(" }");
+			rlp = rln;
+		}
+		break;
+
+	case LS_TYPE_NETWORK:
+		TCHECK(lsap->lsa_un.un_nla.nla_mask);
+		printf(" mask %s rtrs",
+		    ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
+		ap = lsap->lsa_un.un_nla.nla_router;
+		while ((u_char *)ap < ls_end) {
+			TCHECK(*ap);
+			printf(" %s", ipaddr_string(ap));
+			++ap;
+		}
+		break;
+
+	case LS_TYPE_SUM_IP:
+		TCHECK(lsap->lsa_un.un_nla.nla_mask);
+		printf(" mask %s",
+		    ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
+		/* Fall through */
+
+	case LS_TYPE_SUM_ABR:
+		TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
+		lp = lsap->lsa_un.un_sla.sla_tosmetric;
+		while ((u_char *)lp < ls_end) {
+			register u_int32_t ul;
+
+			TCHECK(*lp);
+			ul = ntohl(*lp);
+			printf(" tos %d metric %d",
+			    (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
+			    ul & SLA_MASK_METRIC);
+			++lp;
+		}
+		break;
+
+	case LS_TYPE_ASE:
+		TCHECK(lsap->lsa_un.un_nla.nla_mask);
+		printf(" mask %s",
+		    ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
+
+		TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
+		almp = lsap->lsa_un.un_asla.asla_metric;
+		while ((u_char *)almp < ls_end) {
+			register u_int32_t ul;
+
+			TCHECK(almp->asla_tosmetric);
+			ul = ntohl(almp->asla_tosmetric);
+			printf(" type %d tos %d metric %d",
+			    (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1,
+			    (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS,
+			    (ul & ASLA_MASK_METRIC));
+			TCHECK(almp->asla_forward);
+			if (almp->asla_forward.s_addr) {
+				printf(" forward %s",
+				    ipaddr_string(&almp->asla_forward));
+			}
+			TCHECK(almp->asla_tag);
+			if (almp->asla_tag.s_addr) {
+				printf(" tag %s",
+				    ipaddr_string(&almp->asla_tag));
+			}
+			++almp;
+		}
+		break;
+
+	case LS_TYPE_GROUP:
+		/* Multicast extensions as of 23 July 1991 */
+		mcp = lsap->lsa_un.un_mcla;
+		while ((u_char *)mcp < ls_end) {
+			TCHECK(mcp->mcla_vid);
+			switch (ntohl(mcp->mcla_vtype)) {
+
+			case MCLA_VERTEX_ROUTER:
+				printf(" rtr rtrid %s",
+				    ipaddr_string(&mcp->mcla_vid));
+				break;
+
+			case MCLA_VERTEX_NETWORK:
+				printf(" net dr %s",
+				    ipaddr_string(&mcp->mcla_vid));
+				break;
+
+			default:
+				printf(" ??VertexType %u??",
+				    (u_int32_t)ntohl(mcp->mcla_vtype));
+				break;
+			}
+		++mcp;
+		}
+	}
+
+								/* { (ctags) */
+	fputs(" }", stdout);
+	return (0);
+trunc:
+	fputs(" }", stdout);
+	return (1);
+}
+
+static int
+ospf_decode_v2(register const struct ospfhdr *op,
+    register const u_char *dataend)
+{
+	register const struct in_addr *ap;
+	register const struct lsr *lsrp;
+	register const struct lsa_hdr *lshp;
+	register const struct lsa *lsap;
+	register char sep;
+	register int i;
+
+	switch (op->ospf_type) {
+
+	case OSPF_TYPE_UMD:
+		/*
+		 * Rob Coltun's special monitoring packets;
+		 * do nothing
+		 */
+		break;
+
+	case OSPF_TYPE_HELLO:
+		if (vflag) {
+			TCHECK(op->ospf_hello.hello_deadint);
+			ospf_print_bits(ospf_option_bits,
+			    op->ospf_hello.hello_options);
+			printf(" mask %s int %d pri %d dead %u",
+			    ipaddr_string(&op->ospf_hello.hello_mask),
+			    ntohs(op->ospf_hello.hello_helloint),
+			    op->ospf_hello.hello_priority,
+			    (u_int32_t)ntohl(op->ospf_hello.hello_deadint));
+		}
+		TCHECK(op->ospf_hello.hello_dr);
+		if (op->ospf_hello.hello_dr.s_addr != 0)
+			printf(" dr %s",
+			    ipaddr_string(&op->ospf_hello.hello_dr));
+		TCHECK(op->ospf_hello.hello_bdr);
+		if (op->ospf_hello.hello_bdr.s_addr != 0)
+			printf(" bdr %s",
+			    ipaddr_string(&op->ospf_hello.hello_bdr));
+		if (vflag) {
+			printf(" nbrs");
+			ap = op->ospf_hello.hello_neighbor;
+			while ((u_char *)ap < dataend) {
+				TCHECK(*ap);
+				printf(" %s", ipaddr_string(ap));
+				++ap;
+			}
+		}
+		break;	/* HELLO */
+
+	case OSPF_TYPE_DB:
+		TCHECK(op->ospf_db.db_options);
+		ospf_print_bits(ospf_option_bits, op->ospf_db.db_options);
+		sep = ' ';
+		TCHECK(op->ospf_db.db_flags);
+		if (op->ospf_db.db_flags & OSPF_DB_INIT) {
+			printf("%cI", sep);
+			sep = '/';
+		}
+		if (op->ospf_db.db_flags & OSPF_DB_MORE) {
+			printf("%cM", sep);
+			sep = '/';
+		}
+		if (op->ospf_db.db_flags & OSPF_DB_MASTER) {
+			printf("%cMS", sep);
+			sep = '/';
+		}
+		TCHECK(op->ospf_db.db_seq);
+		printf(" S %X", (u_int32_t)ntohl(op->ospf_db.db_seq));
+
+		if (vflag) {
+			/* Print all the LS adv's */
+			lshp = op->ospf_db.db_lshdr;
+
+			while (!ospf_print_lshdr(lshp)) {
+							/* { (ctags) */
+				printf(" }");
+				++lshp;
+			}
+		}
+		break;
+
+	case OSPF_TYPE_LSR:
+		if (vflag) {
+			lsrp = op->ospf_lsr;
+			while ((u_char *)lsrp < dataend) {
+				TCHECK(*lsrp);
+				printf(" {");		/* } (ctags) */
+				ospf_print_ls_type(ntohl(lsrp->ls_type),
+				    &lsrp->ls_stateid,
+				    &lsrp->ls_router,
+				    "LinkStateType %d");
+							/* { (ctags) */
+				printf(" }");
+				++lsrp;
+			}
+		}
+		break;
+
+	case OSPF_TYPE_LSU:
+		if (vflag) {
+			lsap = op->ospf_lsu.lsu_lsa;
+			TCHECK(op->ospf_lsu.lsu_count);
+			i = ntohl(op->ospf_lsu.lsu_count);
+			while (i--) {
+				if (ospf_print_lsa(lsap))
+					goto trunc;
+				lsap = (struct lsa *)((u_char *)lsap +
+				    ntohs(lsap->ls_hdr.ls_length));
+			}
+		}
+		break;
+
+
+	case OSPF_TYPE_LSA:
+		if (vflag) {
+			lshp = op->ospf_lsa.lsa_lshdr;
+
+			while (!ospf_print_lshdr(lshp)) {
+							/* { (ctags) */
+				printf(" }");
+				++lshp;
+			}
+		}
+		break;
+
+	default:
+		printf("v2 type %d", op->ospf_type);
+		break;
+	}
+	return (0);
+trunc:
+	return (1);
+}
+
+void
+ospf_print(register const u_char *bp, register u_int length,
+    register const u_char *bp2)
+{
+	register const struct ospfhdr *op;
+	register const struct ip *ip;
+	register const u_char *dataend;
+	register const char *cp;
+
+	op = (struct ospfhdr *)bp;
+	ip = (struct ip *)bp2;
+	/* Print the source and destination address  */
+	(void) printf("%s > %s:",
+	    ipaddr_string(&ip->ip_src),
+	    ipaddr_string(&ip->ip_dst));
+
+	/* If the type is valid translate it, or just print the type */
+	/* value.  If it's not valid, say so and return */
+	TCHECK(op->ospf_type);
+	cp = tok2str(type2str, "type%d", op->ospf_type);
+	printf(" OSPFv%d-%s %d:", op->ospf_version, cp, length);
+	if (*cp == 't')
+		return;
+
+	TCHECK(op->ospf_len);
+	if (length != ntohs(op->ospf_len)) {
+		printf(" [len %d]", ntohs(op->ospf_len));
+		return;
+	}
+	dataend = bp + length;
+
+	/* Print the routerid if it is not the same as the source */
+	TCHECK(op->ospf_routerid);
+	if (ip->ip_src.s_addr != op->ospf_routerid.s_addr)
+		printf(" rtrid %s", ipaddr_string(&op->ospf_routerid));
+
+	TCHECK(op->ospf_areaid);
+	if (op->ospf_areaid.s_addr != 0)
+		printf(" area %s", ipaddr_string(&op->ospf_areaid));
+	else
+		printf(" backbone");
+
+	if (vflag) {
+		/* Print authentication data (should we really do this?) */
+		TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata));
+		switch (ntohs(op->ospf_authtype)) {
+
+		case OSPF_AUTH_NONE:
+			break;
+
+		case OSPF_AUTH_SIMPLE:
+			printf(" auth \"");
+			(void)fn_printn(op->ospf_authdata,
+			    sizeof(op->ospf_authdata), NULL);
+			printf("\"");
+			break;
+
+		default:
+			printf(" ??authtype-%d??", ntohs(op->ospf_authtype));
+			return;
+		}
+	}
+	/* Do rest according to version.	 */
+	switch (op->ospf_version) {
+
+	case 2:
+		/* ospf version 2 */
+		if (ospf_decode_v2(op, dataend))
+			goto trunc;
+		break;
+
+	default:
+		printf(" ospf [version %d]", op->ospf_version);
+		break;
+	}			/* end switch on version */
+
+	return;
+trunc:
+	fputs(tstr, stdout);
+}
diff --git a/tcpdump.tproj/print-pim.c b/tcpdump.tproj/print-pim.c
new file mode 100644
index 0000000..3fb9909
--- /dev/null
+++ b/tcpdump.tproj/print-pim.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-pim.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+void
+pim_print(register const u_char *bp, register u_int len)
+{
+    register const u_char *ep;
+    register u_char type;
+
+    ep = (const u_char *)snapend;
+    if (bp >= ep)
+	return;
+
+    type = bp[1];
+
+    switch (type) {
+    case 0:
+	(void)printf(" Query");
+	break;
+
+    case 1:
+	(void)printf(" Register");
+	break;
+
+    case 2:
+	(void)printf(" Register-Stop");
+	break;
+
+    case 3:
+	(void)printf(" Join/Prune");
+	break;
+
+    case 4:
+	(void)printf(" RP-reachable");
+	break;
+
+    case 5:
+	(void)printf(" Assert");
+	break;
+
+    case 6:
+	(void)printf(" Graft");
+	break;
+
+    case 7:
+	(void)printf(" Graft-ACK");
+	break;
+
+    case 8:
+	(void)printf(" Mode");
+	break;
+
+    default:
+	(void)printf(" [type %d]", type);
+	break;
+    }
+}
diff --git a/tcpdump.tproj/print-ppp.c b/tcpdump.tproj/print-ppp.c
new file mode 100644
index 0000000..9fd2a49
--- /dev/null
+++ b/tcpdump.tproj/print-ppp.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-ppp.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#ifdef PPP
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/* XXX This goes somewhere else. */
+#define PPP_HDRLEN 4
+
+void
+ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
+	     register const u_char *p)
+{
+	register u_int length = h->len;
+	register u_int caplen = h->caplen;
+	const struct ip *ip;
+
+	ts_print(&h->ts);
+
+	if (caplen < PPP_HDRLEN) {
+		printf("[|ppp]");
+		goto out;
+	}
+
+	/*
+	 * Some printers want to get back at the link level addresses,
+	 * and/or check that they're not walking off the end of the packet.
+	 * Rather than pass them all the way down, we set these globals.
+	 */
+	packetp = p;
+	snapend = p + caplen;
+
+	if (eflag)
+		printf("%c %4d %02x %04x: ", p[0] ? 'O' : 'I', length,
+		       p[1], ntohs(*(u_short *)&p[2]));
+
+	length -= PPP_HDRLEN;
+	ip = (struct ip *)(p + PPP_HDRLEN);
+	ip_print((const u_char *)ip, length);
+
+	if (xflag)
+		default_print((const u_char *)ip, caplen - PPP_HDRLEN);
+out:
+	putchar('\n');
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+void
+ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+	error("not configured for ppp");
+	/* NOTREACHED */
+}
+#endif
diff --git a/tcpdump.tproj/print-rip.c b/tcpdump.tproj/print-rip.c
new file mode 100644
index 0000000..7c87af7
--- /dev/null
+++ b/tcpdump.tproj/print-rip.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-rip.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"			/* must come after interface.h */
+
+struct rip {
+	u_char rip_cmd;			/* request/response */
+	u_char rip_vers;		/* protocol version # */
+	u_short rip_zero2;		/* unused */
+};
+#define	RIPCMD_REQUEST		1	/* want info */
+#define	RIPCMD_RESPONSE		2	/* responding to request */
+#define	RIPCMD_TRACEON		3	/* turn tracing on */
+#define	RIPCMD_TRACEOFF		4	/* turn it off */
+#define	RIPCMD_POLL		5	/* want info from everybody */
+#define	RIPCMD_POLLENTRY	6	/* poll for entry */
+
+struct rip_netinfo {
+	u_short rip_family;
+	u_short rip_tag;
+	u_int32_t rip_dest;
+	u_int32_t rip_dest_mask;
+	u_int32_t rip_router;
+	u_int32_t rip_metric;		/* cost of route */
+};
+
+static void
+rip_entry_print(register int vers, register const struct rip_netinfo *ni)
+{
+	register u_char *cp, *ep;
+
+	if (EXTRACT_16BITS(&ni->rip_family) != AF_INET) {
+
+		printf(" [family %d:", EXTRACT_16BITS(&ni->rip_family));
+		cp = (u_char *)&ni->rip_tag;
+		ep = (u_char *)&ni->rip_metric + sizeof(ni->rip_metric);
+		for (; cp < ep; cp += 2)
+			printf(" %04x", EXTRACT_16BITS(cp));
+		printf("]");
+	} else if (vers < 2) {
+		/* RFC 1058 */
+		printf(" %s", ipaddr_string(&ni->rip_dest));
+	} else {
+		/* RFC 1723 */
+		printf(" {%s", ipaddr_string(&ni->rip_dest));
+		if (ni->rip_dest_mask)
+			printf("/%s", ipaddr_string(&ni->rip_dest_mask));
+		if (ni->rip_router)
+			printf("->%s", ipaddr_string(&ni->rip_router));
+		if (ni->rip_tag)
+			printf(" tag %04x", EXTRACT_16BITS(&ni->rip_tag));
+		printf("}");
+	}
+	printf("(%d)", EXTRACT_32BITS(&ni->rip_metric));
+}
+
+void
+rip_print(const u_char *dat, u_int length)
+{
+	register const struct rip *rp;
+	register const struct rip_netinfo *ni;
+	register int i, j, trunc;
+
+	i = min(length, snapend - dat) - sizeof(*rp);
+	if (i < 0)
+		return;
+
+	rp = (struct rip *)dat;
+	switch (rp->rip_cmd) {
+
+	case RIPCMD_REQUEST:
+		printf(" rip-req %d", length);
+		break;
+
+	case RIPCMD_RESPONSE:
+		j = length / sizeof(*ni);
+		if (j * sizeof(*ni) != length - 4)
+			printf(" rip-resp %d[%d]:", j, length);
+		else
+			printf(" rip-resp %d:", j);
+		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
+		ni = (struct rip_netinfo *)(rp + 1);
+		for (; (i -= sizeof(*ni)) >= 0; ++ni)
+			rip_entry_print(rp->rip_vers, ni);
+		if (trunc)
+			printf("[|rip]");
+		break;
+
+	case RIPCMD_TRACEON:
+		printf(" rip-traceon %d: \"", length);
+		(void)fn_print((const u_char *)(rp + 1), snapend);
+		fputs("\"\n", stdout);
+		break;
+
+	case RIPCMD_TRACEOFF:
+		printf(" rip-traceoff %d", length);
+		break;
+
+	case RIPCMD_POLL:
+		printf(" rip-poll %d", length);
+		break;
+
+	case RIPCMD_POLLENTRY:
+		printf(" rip-pollentry %d", length);
+		break;
+
+	default:
+		printf(" rip-#%d %d", rp->rip_cmd, length);
+		break;
+	}
+	switch (rp->rip_vers) {
+
+	case 1:
+	case 2:
+		break;
+
+	default:
+		printf(" [vers %d]", rp->rip_vers);
+		break;
+        }
+}
diff --git a/tcpdump.tproj/print-skip.c b/tcpdump.tproj/print-skip.c
new file mode 100644
index 0000000..d9f5059
--- /dev/null
+++ b/tcpdump.tproj/print-skip.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: print-skip.c,v 1.2 1996/07/13 11:01:29 mickey Exp $	*/
+
+/*
+ * Copyright (c) 1995 Sun Microsystems, Inc.
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+
+ * IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ * SUN MICROSYSTEMS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+
+ * SUN MICROSYSTEMS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND SUN
+ * MICROSYSTEMS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
+ * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+#include <sys/param.h> 
+#include <sys/time.h> 
+#include <sys/types.h>
+ 
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#define MAX_ALGS		(256)
+
+int skipflag = 0;
+
+const int       skip_max_algs = MAX_ALGS;
+
+char            *old_skip_crypt_algs[MAX_ALGS] = {
+                                        "none",         /* 0 */
+                                        "des_cbc",      /* 1 */
+                                        "rc2_cbc",      /* 2 */
+                                        "rc4(40bit)",   /* 3 */
+                                        "rc4(128bit)",  /* 4 */
+                                        "des_ede-2",    /* 5 */
+                                        "des_ede-3",    /* 6 */
+                                        "idea",         /* 7 */
+                                        "",             /* 8 */
+                                        "",             /* 9 */
+                                        "simplecrypt"   /* 10 */
+                };
+
+
+char *
+skip_alg_to_name(char *table[], int alg)
+{
+        if (alg > skip_max_algs) {
+                return ("<invalid>");
+        }
+        if (alg < 0) {
+                return ("<invalid>");
+        }
+        if (table[alg] == NULL) {
+                return ("<unknown>");
+        }
+        if (strlen(table[alg]) == 0) {
+                return ("<unknown>");
+        }
+        return (table[alg]);
+}
+
+/*
+ * This is what an OLD skip encrypted-authenticated packet looks like:
+ *
+ *
+ *                 0       1      2      3
+ *            ---------------------------------
+ *            |                               |
+ *            /      Clear IP Header          /  
+ *            |                               |     IP protocol = IPSP
+ *            ---------------------------------
+ *            |                               |
+ *            |         IPSP header           |  
+ *            |                               |
+ *            ---------------------------------
+ *            |                               |
+ *            /    Protected  IPSP Payload    /
+ *            /                               /
+ *            |                               |
+ *            ---------------------------------
+ *
+ *
+ * The format of the IPSP header for encrypted-encapsulated mode is shown below. * The fields are transmitted from left to right.
+ *
+ *   0                   1                   2                   3
+ *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  | Ver.  |E|A|C|S|B|R|               zero                        |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |    Kij alg.   |   Kp alg.     |        reserved               |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |    Optional boxid field                                       |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |    Kp encrypted in Kij...          (typically 8-16 bytes)
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |    Message Indicator (e.g IV)...   (typically 8-16 bytes)
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |    Protected IPSP Payload...
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *
+ *   Field values:
+ *   Ver.: protocol version
+ *   E:    1 if packet is encrypted, 0 otherwise
+ *   A:    1 if packet is authenticated, 0 otherwise
+ *   C:    1 if packet is compressed before encryption, 0 otherwise
+ *   S:    1 if packet is sequenced, 0 otherwise
+ *   B:    1 if packet is tunneled (header contains boxid), 0 otherwise
+ *   R:    reserved (should be 0 until specified)
+ *
+ */
+/*
+ * per-algorithm encrytped key sizes...
+ */
+unsigned char   old_skip_ekp_sizes[MAX_ALGS] = {
+                          8,    /* plaintext */
+                          8,    /* DES */
+                          8,    /* RC2 */
+                          8,    /* RC4 (40 bit)  */
+                         16,    /* RC4 (128 bit) */
+                         16,    /* 3DES 2 */
+                         24,    /* 3DES 3 */
+                         16,    /* IDEA */
+                          0,    /* */
+                          0,    /* */
+                          8,    /* simplecrypt */
+                };
+/*
+ * per-algorithm message indicator sizes...
+ */
+unsigned char   old_skip_mid_sizes[MAX_ALGS] = {
+                          8,    /* plaintext */
+                          8,    /* DES */
+                          8,    /* RC2 */
+                          8,    /* RC4 40 bit */
+                          8,    /* RC4 128 bit */
+                          8,    /* 3DES 2 */
+                          8,    /* 3DES 3 */
+                          8,    /* IDEA */
+                          0,    /* */
+                          0,    /* */
+                          8,    /* simplecrypt */
+                };
+
+void skip_print_old(register const u_char *bp, register int length, 
+							const u_char *bp2)
+{
+	struct ip *ip;
+	const u_char *end;
+	u_char *p;
+	unsigned char	kij_alg, kp_alg, *c;
+	unsigned short i;
+	unsigned short len;
+	int boxid;
+	int node;
+
+	ip=(struct ip *)bp2;
+	p=(u_char *)bp;
+	end=bp+length;
+	printf("SKIP: *** OLD SKIP ***\n");
+	printf("OSKIP: %s>%s:%d",ipaddr_string(&ip->ip_src),
+			       ipaddr_string(&ip->ip_dst),length);
+	if (!skipflag)
+		return;
+	printf("\nOSKIP: SAID byte 1= 0x%02x\n",*p);
+	printf("OSKIP:    xxxx .... = version %d\n", (int) (*p & 0xf0) >> 4);
+        if (*p & 0x08) {
+                printf("OSKIP:    .... 1... = encrypted\n");
+        } else {
+                printf("OSKIP:    .... 0... = not encrypted\n");
+        }
+ 
+        if (*p & 0x04) {
+                printf("OSKIP:    .... .1.. = authenticated\n");
+        } else {
+                printf("OSKIP:    .... .0.. = not authenticated\n");
+        }
+ 
+        if (*p & 0x02) {
+                printf("OSKIP:    .... ..1. = compressed\n");
+        } else {
+                printf("OSKIP:    .... ..0. = not compressed\n");
+        }
+ 
+        if (*p & 0x01) {
+                printf("OSKIP:    .... ...1 = sequenced\n");
+        } else {
+                printf("OSKIP:    .... ...0 = not sequenced\n");
+        }
+                           
+        p++;
+
+  	printf("OSKIP: SAID byte 2 = 0x%02x\n", *p);
+ 
+        if (*p & 0x80) {
+		node=1;
+                printf("OSKIP:    1... .... = Node ID present\n");
+        } else {
+		node=0;
+                printf("OSKIP:    0... .... = no Node ID present\n");
+        }
+ 
+        if (*p & 0x40) {
+                printf("OSKIP:    .1.. .... = <reserved should be zero>\n");
+        } else {
+                printf("OSKIP:    .0.. .... = <reserved should be zero>\n");
+        }
+ 
+        if (*p & 0x20) {
+                printf("OSKIP:    ..1. .... = <reserved should be zero>\n");
+        } else {
+                printf("OSKIP:    ..0. .... = <reserved should be zero>\n");
+        }
+ 
+        if (*p & 0x10) {
+                printf("OSKIP:    ...1 .... = <reserved should be zero>\n");
+        } else {
+                printf("OSKIP:    ...0 .... = <reserved should be zero>\n");
+        }
+	  p++;
+        printf("OSKIP: SAID byte 3 = 0x%02x\n", *p);
+ 
+        p++;     
+        printf("OSKIP: SAID byte 4 = 0x%02x\n", *p);
+ 
+        p++;
+ 
+        kij_alg = *p;
+        printf("OSKIP: Kij alg (key encryption algorithm) = 0x%02x (%s)\n",
+		    kij_alg, skip_alg_to_name(old_skip_crypt_algs,kij_alg));
+ 
+        p++;
+ 
+        kp_alg = *p;
+        printf("OSKIP: Kp alg (traffic encryption algorithm) = 0x%02x (%s)\n",
+		    kp_alg, skip_alg_to_name(old_skip_crypt_algs,kp_alg));
+ 
+        p++;
+ 
+        /*
+         * the skip reserved field
+         */
+        printf("OSKIP: reserved byte 1 = 0x%02x\n", *p++);
+        printf("OSKIP: reserved byte 2 = 0x%02x\n", *p++);
+
+        if (node) {
+        /*
+         * boxid field
+         */
+	    if ((end - p) < sizeof(boxid)) {
+		    return;
+	    }
+	    c = (unsigned char *) &boxid;
+	    *c++ = *p++;
+	    *c++ = *p++;
+	    *c++ = *p++;
+	    *c++ = *p++;
+
+	    printf("OSKIP: Node ID = 0x%08x\n", ntohl(boxid));
+        }
+
+        /*
+         * encrypted kp (ekp) field
+         */
+
+        /*
+         * do this with a for-loop to avoid alignment problems and the
+         * overhead of calling bcopy()
+         */
+        len     = old_skip_ekp_sizes[kp_alg];
+        if ((unsigned short) (end - p) < len) {
+                return;
+        }
+
+        printf("OSKIP: encrypted Kp:  ");
+        for (i = 0; i < len; i++) {
+                printf("%02x ", (unsigned char) *p++);
+        }
+        printf("\n");
+
+        /*
+         * message indicator (mid) field
+         */
+        len     = old_skip_mid_sizes[kp_alg];
+        if ((unsigned short) (end - p) < len) {
+                return;
+        }
+        printf("OSKIP: message indicator field:  ");
+        for (i = 0; i < len; i++) {
+                printf("%02x ", (unsigned char) *p++);
+        }
+        printf("\n");
+}
+
+
+
+/* 
+ * The following part is (c) by G. Caronni  -- 29.11.95 
+ *
+ * This code is in the public domain; do with it what you wish.
+ *
+ * NO WARRANTY, NO SUPPORT, NO NOTHING!
+ */
+
+
+/*
+ * This is what a NEW skip encrypted-authenticated packet looks like:
+ *
+ *
+ *                 0       1      2      3
+ *            ---------------------------------
+ *            |                               |
+ *            /      Clear IP Header          /  
+ *            |                               |     IP protocol = SKIP
+ *            ---------------------------------
+ *            |                               |
+ *            |         SKIP header           |  
+ *            |                               |
+ *            ---------------------------------
+ *            |                               |
+ *            |    Auth Header & payload      |  
+ *            |                               |
+ *            ---------------------------------
+ *            |                               |
+ *            |    ESP header and SPI         |  
+ *            |                               |
+ *            ---------------------------------
+ *            |                               |
+ *            /    Protected  ESP Payload     /
+ *            |                               |
+ *            ---------------------------------
+ *
+ *
+ * The format of the SKIP header for encrypted-encapsulated mode is shown below. * The fields are transmitted from left to right.
+ *
+ *    0                   1                   2                   3
+ *    0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |  Ver  | Rsvd  | Source NSID   | Dest NSID     | NEXT HEADER   |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |                    Counter n                                  |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |    Kij Alg    |   Crypt Alg   |  MAC Alg      |  Comp Alg     |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |    Kp encrypted in Kijn...          (typically 8-16 bytes)
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |    Source Master Key-ID  (If Source NSID is non-zero)
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |    Destination Master Key-ID (If Dest NSID is non-zero)
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+
+
+
+
+/*
+ * per name space key ID sizes...
+ */
+unsigned char   skip_nsid_sizes[MAX_ALGS] = {
+                          0,    /* 0  none */
+                          4,    /* 1  IP v4 Address Space */
+                          4,    /* 2  POSIX/XOPEN User Ids */
+                         16,    /* 3  IPv6 Address Space */
+                         16,    /* 4  MD5 of DNS Names */
+                         16,    /* 5  MD5 of ISO ASN.1 DN encoding */
+                         16,    /* 6  MD5 of US Social Security number */
+                          6,    /* 7  802.x MAC Address */
+                         16,    /* 8  MD5 of public Value */
+                         16,    /* 9  MD5 of RFC822 Mailbox Address */
+                         16,    /* 10 MD5 of Bank Account # */
+                         16,    /* 11 MD5 of NIS Name */
+                };
+
+
+/*
+ * per Kp algorithm encrypted Kp sizes... (Kij alg does not matter for now)
+ */
+unsigned char   skip_ekp_sizes[MAX_ALGS] = {
+                          0,    /* 0 plaintext */
+                          8,    /* 1 DES_CBC */
+                          24,   /* 2 3 key triple DES-EDE-CBC */
+                          0,    /* 3  */
+                          0,    /* 4  */
+                          0,    /* 5  */
+                          0,    /* 6  */
+                          0,    /* 7  */
+                          0,    /* 8  */
+                          0,    /* 9  */                        /* 10 .. 249 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+			  8,    /* 250 RC4-40 */                          
+			  16,   /* 251 RC4-128 */                          
+			  8,    /* 252 simple crypt */                          
+			  16,   /* 253 IDEA */                          
+			  0,    /* 254 */                          
+			  0     /* 255 */                          
+                };
+
+
+/*
+ * per-algorithm NSID names ...
+ */
+char            *skip_nsid_names[MAX_ALGS] = {
+                                        "none",             /* 0 */
+                                        "IPv4",             /* 1 */
+                                        "Posix/Xopen UID",  /* 2 */
+                                        "IPv6",             /* 3 */
+                                        "MD5 DNS",          /* 4 */
+                                        "MD5 ASN.1 DN",     /* 5 */
+                                        "MD5 U.S. Soc. #",  /* 6 */
+                                        "802.x MAC",        /* 7 */
+                                        "MD5 DH Public Key",/* 8 */
+                                        "MD5 RFC822 Mail",  /* 9 */
+                                        "MD5 Bank Account", /* 10 */
+                                        "MD5 NIS Name",     /* 11 */
+                };
+
+
+/*
+ * per-algorithm Kij alg names ...
+ */
+char            *skip_kij_names[MAX_ALGS] = {
+                                        "none",             /* 0 */
+                                        "DES-CBC",          /* 1 */
+                                        "3DES3-EDE-CBC",    /* 2 */
+                                        "IDEA-CBC",         /* 3 */
+		};
+
+
+/* for padding of ekp */
+
+char            skip_kij_sizes[MAX_ALGS] = {
+                                        0, /* 0 none */
+                                        8, /* 1  des-cbc */
+                                        8, /* 2 3des3-ede-cbc */
+                                        8, /* 3 idea-cbc */
+		};
+
+
+/*
+ * per-algorithm Crypt alg names ...
+ */
+char            *skip_crypt_names[MAX_ALGS] = {
+                                        "none",                      /* 0 */
+                                        "DES-CBC",                   /* 1 */
+                                        "3 key DES-EDE-CBC",         /* 2 */
+                                        "",                          /* 3 */
+                                        "",                          /* 4 */
+                                        "",                          /* 5 */
+                                        "",                          /* 6 */
+                                        "",                          /* 7 */
+                                        "",                          /* 8 */
+					"",   /* 9 */        /* 10 .. 249 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+					"RC4-40",                    /* 250 */ 
+					"RC4-128",                   /* 251 */
+					"simple crypt",              /* 252 */ 
+					"IDEA CBC",                  /* 253 */
+					"",                          /* 254 */ 
+					""                           /* 255 */
+                };
+
+
+/*
+ * per-algorithm Auth alg names ...
+ */
+char            *skip_auth_names[MAX_ALGS] = {
+                                        "none",        /* 0 */
+                                        "keyed MD5",   /* 1 */
+                                        "DES-CBC MAC", /* 2 */
+                                        "Keyed SHA",   /* 3 */
+                };
+
+
+char            skip_auth_sizes[MAX_ALGS] = {
+                                        0, 		/* 0 none */
+                                       16,	 	/* 1 keyed MD5 */
+                                        8, 		/* 2 DES-CBC MAC */
+                                       20, 		/* 3 Keyed SHA */
+                };
+
+
+/*
+ * per-algorithm Crypt alg IV sizes ...
+ */
+char            skip_crypt_sizes[MAX_ALGS] = {
+                                        0, /* 0 none */
+                                        8, /* 1 DES-CBC */
+                                        8, /* 2 3key DES-EDE-CBC */
+                                        0, /* 3 */
+                                        0, /* 4 */
+                                        0, /* 5 */
+                                        0, /* 6 */
+                                        0, /* 7 */
+                                        0, /* 8 */
+					0, /* 9 */        /* 10 .. 249 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+					8, /* 250 RC4-40 */ 
+				        8, /* 251 RC4-128 */
+					8, /* 252 simple crypt */ 
+					8, /* 253 IDEA CBC */
+					0, /* 254 */ 
+					0  /* 255 */
+                };
+
+
+#ifndef IPPROTO_ESP
+#define IPPROTO_ESP 50
+#endif
+#ifndef IPPROTO_AH
+#define IPPROTO_AH 51
+#endif
+#ifndef IPPROTO_SKIP
+#define IPPROTO_SKIP 57
+#endif
+#ifndef IPPROTO_OSKIP
+#define IPPROTO_OSKIP 79
+#endif
+
+static int expected_auth_size=0;
+static int expected_iv_size=0;
+
+char *skip_protocol_name(int p)
+{
+    switch(p) {
+	case IPPROTO_IP:    return "IP";
+	case IPPROTO_ICMP:  return "ICMP";
+	case IPPROTO_IGMP:  return "IGMP";
+	case IPPROTO_ENCAP: return "ENCAP";
+	case IPPROTO_TCP:   return "TCP";
+	case IPPROTO_EGP:   return "EGP";
+	case IPPROTO_UDP:   return "UDP";
+	case IPPROTO_ESP:   return "ESP";
+	case IPPROTO_AH:    return "AH";
+	case IPPROTO_SKIP:  return "SKIP";
+	case IPPROTO_ND:    return "ND";
+	case IPPROTO_OSKIP: return "OLD-SKIP";
+	case IPPROTO_RAW:   return "RAW IP";
+	default:            return "<unknown>";
+    }
+}
+
+void skip_print_next(u_char nxt, const u_char *p, int len, const u_char *bp2)
+{
+    switch(nxt) {
+	case IPPROTO_IP:   ip_print(p,len); break;
+	case IPPROTO_ICMP: icmp_print(p,bp2); break;
+	case IPPROTO_TCP:  tcp_print(p,len,bp2); break;
+	case IPPROTO_UDP:  udp_print(p,len,bp2); break;
+	case IPPROTO_ESP:  esp_print(p,len,bp2); break;
+	case IPPROTO_AH:   ah_print(p,len,bp2); break;
+	case IPPROTO_SKIP: skip_print(p,len,bp2); break;
+	default: break;
+    }
+}
+
+void skip_print(register const u_char *bp, register int length, 
+							const u_char *bp2)
+{
+	struct ip *ip;
+	const u_char *end;
+	const u_char *p;
+	unsigned char	kij_alg, crypt_alg, auth_alg, snsid, dnsid, nxt;
+	unsigned short i;
+	unsigned short len;
+	u_int n;
+	time_t full_n;
+
+	ip=(struct ip *)bp2;
+	p=bp;
+	end=bp+length<snapend?bp+length:snapend;
+
+	printf("%s>%s:%d SKIP",ipaddr_string(&ip->ip_src),
+			       ipaddr_string(&ip->ip_dst),length);
+	if (!skipflag)
+		return;
+
+
+        if ((unsigned short) (end - p) < 4) {
+	    printf("[SKIP|] (truncated)\n");
+	    return;
+        }
+
+	printf("\nSKIP: version\t\t\t%d\n", (int) (*p & 0xf0) >> 4);
+	if (*p & 0xf) 
+		printf("SKIP: version byte \t\treserved,\tis now 0x%x\n", 
+							(int) (*p & 0xf));
+        p++;
+
+        snsid = *p;
+        printf("SKIP: Source NSID\t\t0x%02x\t\t%s\n",
+		    snsid, skip_alg_to_name(skip_nsid_names,snsid));
+        p++;
+
+        dnsid = *p;
+        printf("SKIP: Destination NSID\t\t0x%02x\t\t%s\n",
+		    dnsid, skip_alg_to_name(skip_nsid_names,dnsid));
+        p++;
+
+        nxt = *p;
+        printf("SKIP: Next Protocol Field\t0x%02x\t\t%s\n", nxt, 
+						    skip_protocol_name(nxt));
+ 
+        p++;
+
+        if ((unsigned short) (end - p) < 4) {
+	    printf("[SKIP|] (truncated)\n");
+	    return;
+        }
+
+	n=*p++<<24; 
+	n+=*p++<<16;
+	n+=*p++<<8;
+	n+=*p;
+	full_n=(((365*25+6)*24)+n)*3600;
+        printf("SKIP: Counter n Field\t\t0x%08x\t%s", n, 
+						asctime(gmtime(&full_n)));
+        p++;
+
+        if ((unsigned short) (end - p) < 4) {
+	    printf("[SKIP|] (truncated)\n");
+	    return;
+        }
+
+        kij_alg = *p;
+        printf("SKIP: Kij alg (key encryption)\t0x%02x\t\t%s\n",
+		    kij_alg, skip_alg_to_name(skip_kij_names,kij_alg));
+        p++;
+ 
+        crypt_alg = *p;
+	expected_iv_size=skip_crypt_sizes[crypt_alg];
+        printf("SKIP: Crypt Alg\t\t\t0x%02x\t\t%s\n",
+		    crypt_alg, skip_alg_to_name(skip_crypt_names,crypt_alg));
+        p++;
+ 
+        auth_alg = *p;
+	expected_auth_size=skip_auth_sizes[auth_alg];
+        printf("SKIP: Auth Alg\t\t\t0x%02x\t\t%s\n",
+		    auth_alg, skip_alg_to_name(skip_auth_names,auth_alg));
+        p++;
+ 
+        if (*p) printf("SKIP: compression\t\treserved,\tis now0x%02x\n",
+								(int) *p++);
+        else p++;
+
+        /*
+         * encrypted kp (ekp) field
+         */
+
+	if (kij_alg==0 && (crypt_alg || auth_alg)) {
+	    printf("Warning: Kij Alg. undefined, but Auth. or Crypt. used!");
+	    printf("Warning: Assuming empty Kp\n");
+	    crypt_alg=auth_alg=0;
+	}
+        /*
+         * do this with a for-loop to avoid alignment problems and the
+         * overhead of calling bcopy()
+         */
+        len = skip_ekp_sizes[crypt_alg];
+        len = len>(int)skip_auth_sizes[auth_alg]?len:skip_auth_sizes[auth_alg];
+        if (len && skip_kij_sizes[kij_alg] && len % skip_kij_sizes[kij_alg]) {
+	    len += skip_kij_sizes[kij_alg] - (len%skip_kij_sizes[kij_alg]);
+	}
+        if ((unsigned short) (end - p) < len) {
+	    printf("[SKIP|] (truncated)\n");
+	    return;
+        }
+
+        printf("SKIP: Encrypted Kp\t\t");
+        for (i = 0; i < len; i++) {
+                printf("%02x ", (unsigned char) *p++);
+        }
+        printf("\n");
+
+
+        if (snsid) {
+        /*
+         * Source Master Key-ID field
+         */
+	    if ((end - p) < skip_nsid_sizes[snsid]) {
+		printf("[SKIP|] (truncated)\n");
+		return;
+	    }
+	    printf("SKIP: Source Master Key-ID\t");
+            if (snsid==1) {
+		printf("%s",ipaddr_string(p));
+		p+=skip_nsid_sizes[snsid];
+	    } else {
+		for (i = 0; i < skip_nsid_sizes[snsid]; i++) {
+		    printf("%02x ", (unsigned char) *p++);
+		}
+	    }
+	    printf("\n");
+        }
+
+        if (dnsid) {
+        /*
+         * Destination Master Key-ID field
+         */
+	    if ((end - p) < skip_nsid_sizes[dnsid]) {
+		printf("[SKIP|] (truncated)\n");
+		return;
+	    }
+	    printf("SKIP: Dest. Master Key-ID\t");
+            if (dnsid==1) {
+		printf("%s",ipaddr_string(p));
+		p+=skip_nsid_sizes[dnsid];
+	    } else {
+		for (i = 0; i < skip_nsid_sizes[dnsid]; i++) {
+		    printf("%02x ", (unsigned char) *p++);
+		}
+	    }
+	    printf("\n");
+        }
+        if (p<end) skip_print_next(nxt,p,end-p,bp2);
+        else printf("(truncated)\n");
+}
+
+
+
+void ah_print(register const u_char *bp, register int length, 
+							const u_char *bp2)
+{
+	struct ip *ip;
+	const u_char *end;
+	const u_char *p;
+	u_char	nxt;
+	int len, i;
+	u_int spi;
+
+	ip=(struct ip *)bp2;
+	p=bp;
+	end=bp+length<snapend?bp+length:snapend;
+
+
+	printf("SKIP-AH: %s>%s:%d",ipaddr_string(&ip->ip_src),
+			       ipaddr_string(&ip->ip_dst),length);
+	if (!skipflag)
+		return;
+
+	if (end-p <4) {
+            printf("[SKIP-AH|]\n");
+	    return;
+	}
+
+        nxt = *p;
+        printf("\nSKIP-AH: Next Protocol Field\t0x%02x\t\t%s\n", nxt, 
+						    skip_protocol_name(nxt));
+        p++;
+
+	len= 4 * (int) *p;
+	printf("SKIP-AH: length\t\t\t%d\n", len);
+
+        p++;
+
+        if (*p) printf("SKIP-AH: byte 3\t\t\treserved,\tis now0x%02x\n",
+								(int) *p++);
+        else p++;
+        if (*p) printf("SKIP-AH: byte 4\t\t\treserved,\tis now0x%02x\n",
+								(int) *p++);
+        else p++;
+
+	if (end-p <4) {
+            printf("[SKIP-AH|]\n");
+	    return;
+	}
+
+	spi=*p++<<24; 
+	spi+=*p++<<16;
+	spi+=*p++<<8;
+	spi+=*p;
+        printf("SKIP-AH: SPI\t\t\t0x%08x\t", spi );
+	if (spi==0) {
+	    printf("NO association\n");
+	} else if (spi==1) {
+	    printf("SKIP association\n");
+	    if (expected_auth_size) {
+		if (expected_auth_size != len) {
+		    printf("Warning: Length does not match SKIP Auth Alg!\n");
+		}
+		expected_auth_size=0;
+	    }
+	} else if (spi<256) {
+	    printf("UNKNOWN association\n");
+	} else {
+	    printf("DYNAMIC association\n");
+        }
+
+        p++;
+ 
+
+        /*
+         * authentication data
+         */
+
+        if ((unsigned short) (end - p) < len) {
+	    printf("[SKIP-AH|] (truncated)\n");
+	    return;
+        }
+
+        printf("SKIP-AH: Authentication Data\t");
+        for (i = 0; i < len; i++) {
+                printf("%02x ", (unsigned char) *p++);
+		if (i<len-1 && (i+1)%16==0) printf("\n\t\t\t\t");
+        }
+        printf("\n");
+
+        if (p<end) skip_print_next(nxt,p,end-p,bp2);
+        else printf("(truncated)\n");
+}
+
+
+void esp_print(register const u_char *bp, register int length, 
+							const u_char *bp2)
+{
+	struct ip *ip;
+	const u_char *end;
+	const u_char *p;
+	int len, i;
+	u_int spi;
+
+	ip=(struct ip *)bp2;
+	p=bp;
+	end=bp+length<snapend?bp+length:snapend;
+
+
+	printf("SKIP-ESP: %s>%s:%d",ipaddr_string(&ip->ip_src),
+			       ipaddr_string(&ip->ip_dst),length);
+	if (!skipflag)
+		return;
+
+	if (end-p <4) {
+            printf("[SKIP-ESP|]\n");
+	}
+
+	spi=*p++<<24; 
+	spi+=*p++<<16;
+	spi+=*p++<<8;
+	spi+=*p;
+        printf("\nSKIP-ESP: SPI\t\t\t0x%08x\t", spi );
+	if (spi==0) {
+	    printf("NO association\n");
+	    len=0;
+	} else if (spi==1) {
+	    printf("SKIP association\n");
+	    len=expected_iv_size;
+	    if (!expected_iv_size) {
+		printf("Warning: IV size not defined by SKIP Crypt Alg!\n");
+	    } else expected_iv_size=0;
+	} else if (spi<256) {
+	    printf("UNKNOWN association\n");
+	    len=0;
+	} else {
+	    printf("DYNAMIC association\n");
+	    len=0;
+        }
+
+        p++;
+ 
+        /*
+         * IV data
+         */
+
+        if ((unsigned short) (end - p) < len) {
+	    printf("[SKIP-ESP|] (truncated)\n");
+	    return;
+        }
+
+        printf("SKIP-ESP: Initalization Vector\t");
+	if (len) {
+	    for (i = 0; i < len; i++) {
+		    printf("%02x ", (unsigned char) *p++);
+		    if (i<len-1 && (i+1)%16==0) printf("\n\t\t\t\t");
+	    }
+        } else {
+	    printf("UNDEFINED (unknown algorithm)");
+	}
+	printf("\n");
+
+	/* no further analysis is possible without decrypting */
+}
+
diff --git a/tcpdump.tproj/print-sl.c b/tcpdump.tproj/print-sl.c
new file mode 100644
index 0000000..4e4e25e
--- /dev/null
+++ b/tcpdump.tproj/print-sl.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-sl.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_NET_SLIP_H
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <net/slcompress.h>
+#include <net/slip.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"			/* must come after interface.h */
+
+static u_int lastlen[2][256];
+static u_int lastconn = 255;
+
+static void sliplink_print(const u_char *, const struct ip *, u_int);
+static void compressed_sl_print(const u_char *, const struct ip *, u_int, int);
+
+/* XXX BSD/OS 2.1 compatibility */
+#if !defined(SLIP_HDRLEN) && defined(SLC_BPFHDR)
+#define SLIP_HDRLEN SLC_BPFHDR
+#define SLX_DIR 0
+#define SLX_CHDR (SLC_BPFHDRLEN - 1)
+#define CHDR_LEN (SLC_BPFHDR - SLC_BPFHDRLEN)
+#endif
+
+void
+sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+	register u_int caplen = h->caplen;
+	register u_int length = h->len;
+	register const struct ip *ip;
+
+	ts_print(&h->ts);
+
+	if (caplen < SLIP_HDRLEN) {
+		printf("[|slip]");
+		goto out;
+	}
+	/*
+	 * Some printers want to get back at the link level addresses,
+	 * and/or check that they're not walking off the end of the packet.
+	 * Rather than pass them all the way down, we set these globals.
+	 */
+	packetp = p;
+	snapend = p + caplen;
+
+	length -= SLIP_HDRLEN;
+
+	ip = (struct ip *)(p + SLIP_HDRLEN);
+
+	if (eflag)
+		sliplink_print(p, ip, length);
+
+	ip_print((u_char *)ip, length);
+
+	if (xflag)
+		default_print((u_char *)ip, caplen - SLIP_HDRLEN);
+ out:
+	putchar('\n');
+}
+
+static void
+sliplink_print(register const u_char *p, register const struct ip *ip,
+	       register u_int length)
+{
+	int dir;
+	u_int hlen;
+
+	dir = p[SLX_DIR];
+	putchar(dir == SLIPDIR_IN ? 'I' : 'O');
+	putchar(' ');
+
+	if (nflag) {
+		/* XXX just dump the header */
+		register int i;
+
+		for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i)
+			printf("%02x.", p[i]);
+		printf("%02x: ", p[SLX_CHDR + CHDR_LEN - 1]);
+		return;
+	}
+	switch (p[SLX_CHDR] & 0xf0) {
+
+	case TYPE_IP:
+		printf("ip %d: ", length + SLIP_HDRLEN);
+		break;
+
+	case TYPE_UNCOMPRESSED_TCP:
+		/*
+		 * The connection id is stored in the IP protocol field.
+		 * Get it from the link layer since sl_uncompress_tcp()
+		 * has restored the IP header copy to IPPROTO_TCP.
+		 */
+		lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p;
+		hlen = ip->ip_hl;
+		hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off;
+		lastlen[dir][lastconn] = length - (hlen << 2);
+		printf("utcp %d: ", lastconn);
+		break;
+
+	default:
+		if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
+			compressed_sl_print(&p[SLX_CHDR], ip,
+			    length, dir);
+			printf(": ");
+		} else
+			printf("slip-%d!: ", p[SLX_CHDR]);
+	}
+}
+
+static const u_char *
+print_sl_change(const char *str, register const u_char *cp)
+{
+	register u_int i;
+
+	if ((i = *cp++) == 0) {
+		i = EXTRACT_16BITS(cp);
+		cp += 2;
+	}
+	printf(" %s%d", str, i);
+	return (cp);
+}
+
+static const u_char *
+print_sl_winchange(register const u_char *cp)
+{
+	register short i;
+
+	if ((i = *cp++) == 0) {
+		i = EXTRACT_16BITS(cp);
+		cp += 2;
+	}
+	if (i >= 0)
+		printf(" W+%d", i);
+	else
+		printf(" W%d", i);
+	return (cp);
+}
+
+static void
+compressed_sl_print(const u_char *chdr, const struct ip *ip,
+		    u_int length, int dir)
+{
+	register const u_char *cp = chdr;
+	register u_int flags, hlen;
+
+	flags = *cp++;
+	if (flags & NEW_C) {
+		lastconn = *cp++;
+		printf("ctcp %d", lastconn);
+	} else
+		printf("ctcp *");
+
+	/* skip tcp checksum */
+	cp += 2;
+
+	switch (flags & SPECIALS_MASK) {
+	case SPECIAL_I:
+		printf(" *SA+%d", lastlen[dir][lastconn]);
+		break;
+
+	case SPECIAL_D:
+		printf(" *S+%d", lastlen[dir][lastconn]);
+		break;
+
+	default:
+		if (flags & NEW_U)
+			cp = print_sl_change("U=", cp);
+		if (flags & NEW_W)
+			cp = print_sl_winchange(cp);
+		if (flags & NEW_A)
+			cp = print_sl_change("A+", cp);
+		if (flags & NEW_S)
+			cp = print_sl_change("S+", cp);
+		break;
+	}
+	if (flags & NEW_I)
+		cp = print_sl_change("I+", cp);
+
+	/*
+	 * 'hlen' is the length of the uncompressed TCP/IP header (in words).
+	 * 'cp - chdr' is the length of the compressed header.
+	 * 'length - hlen' is the amount of data in the packet.
+	 */
+	hlen = ip->ip_hl;
+	hlen += ((struct tcphdr *)&((int32_t *)ip)[hlen])->th_off;
+	lastlen[dir][lastconn] = length - (hlen << 2);
+	printf(" %d (%d)", lastlen[dir][lastconn], cp - chdr);
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <pcap.h>
+#include <stdio.h>
+
+#include "interface.h"
+void
+sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+
+	error("not configured for slip");
+	/* NOTREACHED */
+}
+#endif
diff --git a/tcpdump.tproj/print-snmp.c b/tcpdump.tproj/print-snmp.c
new file mode 100644
index 0000000..860be8a
--- /dev/null
+++ b/tcpdump.tproj/print-snmp.c
@@ -0,0 +1,1063 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
+ *	The 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 John Robert LoVerso.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * This implementation has been influenced by the CMU SNMP release,
+ * by Steve Waldbusser.  However, this shares no code with that system.
+ * Additional ASN.1 insight gained from Marshall T. Rose's _The_Open_Book_.
+ * Earlier forms of this implementation were derived and/or inspired by an
+ * awk script originally written by C. Philip Wood of LANL (but later
+ * heavily modified by John Robert LoVerso).  The copyright notice for
+ * that work is preserved below, even though it may not rightly apply
+ * to this file.
+ *
+ * This started out as a very simple program, but the incremental decoding
+ * (into the BE structure) complicated things.
+ *
+ #			Los Alamos National Laboratory
+ #
+ #	Copyright, 1990.  The Regents of the University of California.
+ #	This software was produced under a U.S. Government contract
+ #	(W-7405-ENG-36) by Los Alamos National Laboratory, which is
+ #	operated by the	University of California for the U.S. Department
+ #	of Energy.  The U.S. Government is licensed to use, reproduce,
+ #	and distribute this software.  Permission is granted to the
+ #	public to copy and use this software without charge, provided
+ #	that this Notice and any statement of authorship are reproduced
+ #	on all copies.  Neither the Government nor the University makes
+ #	any warranty, express or implied, or assumes any liability or
+ #	responsibility for the use of this software.
+ #	@(#)snmp.awk.x	1.1 (LANL) 1/15/90
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-snmp.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/*
+ * Universal ASN.1 types
+ * (we only care about the tag values for those allowed in the Internet SMI)
+ */
+char *Universal[] = {
+	"U-0",
+	"Boolean",
+	"Integer",
+#define INTEGER 2
+	"Bitstring",
+	"String",
+#define STRING 4
+	"Null",
+#define ASN_NULL 5
+	"ObjID",
+#define OBJECTID 6
+	"ObjectDes",
+	"U-8","U-9","U-10","U-11",	/* 8-11 */
+	"U-12","U-13","U-14","U-15",	/* 12-15 */
+	"Sequence",
+#define SEQUENCE 16
+	"Set"
+};
+
+/*
+ * Application-wide ASN.1 types from the Internet SMI and their tags
+ */
+char *Application[] = {
+	"IpAddress",
+#define IPADDR 0
+	"Counter",
+#define COUNTER 1
+	"Gauge",
+#define GAUGE 2
+	"TimeTicks",
+#define TIMETICKS 3
+	"Opaque"
+};
+
+/*
+ * Context-specific ASN.1 types for the SNMP PDUs and their tags
+ */
+char *Context[] = {
+	"GetRequest",
+#define GETREQ 0
+	"GetNextRequest",
+#define GETNEXTREQ 1
+	"GetResponse",
+#define GETRESP 2
+	"SetRequest",
+#define SETREQ 3
+	"Trap"
+#define TRAP 4
+};
+
+/*
+ * Private ASN.1 types
+ * The Internet SMI does not specify any
+ */
+char *Private[] = {
+	"P-0"
+};
+
+/*
+ * error-status values for any SNMP PDU
+ */
+char *ErrorStatus[] = {
+	"noError",
+	"tooBig",
+	"noSuchName",
+	"badValue",
+	"readOnly",
+	"genErr"
+};
+#define DECODE_ErrorStatus(e) \
+	( e >= 0 && e <= sizeof(ErrorStatus)/sizeof(ErrorStatus[0]) \
+	? ErrorStatus[e] : (sprintf(errbuf, "err=%u", e), errbuf))
+
+/*
+ * generic-trap values in the SNMP Trap-PDU
+ */
+char *GenericTrap[] = {
+	"coldStart",
+	"warmStart",
+	"linkDown",
+	"linkUp",
+	"authenticationFailure",
+	"egpNeighborLoss",
+	"enterpriseSpecific"
+#define GT_ENTERPRISE 7
+};
+#define DECODE_GenericTrap(t) \
+	( t >= 0 && t <= sizeof(GenericTrap)/sizeof(GenericTrap[0]) \
+	? GenericTrap[t] : (sprintf(buf, "gt=%d", t), buf))
+
+/*
+ * ASN.1 type class table
+ * Ties together the preceding Universal, Application, Context, and Private
+ * type definitions.
+ */
+#define defineCLASS(x) { "x", x, sizeof(x)/sizeof(x[0]) } /* not ANSI-C */
+struct {
+	char	*name;
+	char	**Id;
+	    int	numIDs;
+    } Class[] = {
+	defineCLASS(Universal),
+#define	UNIVERSAL	0
+	defineCLASS(Application),
+#define	APPLICATION	1
+	defineCLASS(Context),
+#define	CONTEXT		2
+	defineCLASS(Private),
+#define	PRIVATE		3
+};
+
+/*
+ * defined forms for ASN.1 types
+ */
+char *Form[] = {
+	"Primitive",
+#define PRIMITIVE	0
+	"Constructed",
+#define CONSTRUCTED	1
+};
+
+/*
+ * A structure for the OID tree for the compiled-in MIB.
+ * This is stored as a general-order tree.
+ */
+struct obj {
+	char	*desc;			/* name of object */
+	u_char	oid;			/* sub-id following parent */
+	u_char	type;			/* object type (unused) */
+	struct obj *child, *next;	/* child and next sibling pointers */
+} *objp = NULL;
+
+/*
+ * Include the compiled in SNMP MIB.  "mib.h" is produced by feeding
+ * RFC-1156 format files into "makemib".  "mib.h" MUST define at least
+ * a value for `mibroot'.
+ *
+ * In particular, this is gross, as this is including initialized structures,
+ * and by right shouldn't be an "include" file.
+ */
+#include "mib.h"
+
+/*
+ * This defines a list of OIDs which will be abbreviated on output.
+ * Currently, this includes the prefixes for the Internet MIB, the
+ * private enterprises tree, and the experimental tree.
+ */
+struct obj_abrev {
+	char *prefix;			/* prefix for this abrev */
+	struct obj *node;		/* pointer into object table */
+	char *oid;			/* ASN.1 encoded OID */
+} obj_abrev_list[] = {
+#ifndef NO_ABREV_MIB
+	/* .iso.org.dod.internet.mgmt.mib */
+	{ "",	&_mib_obj,		"\53\6\1\2\1" },
+#endif
+#ifndef NO_ABREV_ENTER
+	/* .iso.org.dod.internet.private.enterprises */
+	{ "E:",	&_enterprises_obj,	"\53\6\1\4\1" },
+#endif
+#ifndef NO_ABREV_EXPERI
+	/* .iso.org.dod.internet.experimental */
+	{ "X:",	&_experimental_obj,	"\53\6\1\3" },
+#endif
+	{ 0,0,0 }
+};
+
+/*
+ * This is used in the OID print routine to walk down the object tree
+ * rooted at `mibroot'.
+ */
+#define OBJ_PRINT(o, suppressdot) \
+{ \
+	if (objp) { \
+		do { \
+			if ((o) == objp->oid) \
+				break; \
+		} while ((objp = objp->next) != NULL); \
+	} \
+	if (objp) { \
+		printf(suppressdot?"%s":".%s", objp->desc); \
+		objp = objp->child; \
+	} else \
+		printf(suppressdot?"%u":".%u", (o)); \
+}
+
+/*
+ * This is the definition for the Any-Data-Type storage used purely for
+ * temporary internal representation while decoding an ASN.1 data stream.
+ */
+struct be {
+	u_int32_t asnlen;
+	union {
+		caddr_t raw;
+		int32_t integer;
+		u_int32_t uns;
+		const u_char *str;
+	} data;
+	u_short id;
+	u_char form, class;		/* tag info */
+	u_char type;
+#define BE_ANY		255
+#define BE_NONE		0
+#define BE_NULL		1
+#define BE_OCTET	2
+#define BE_OID		3
+#define BE_INT		4
+#define BE_UNS		5
+#define BE_STR		6
+#define BE_SEQ		7
+#define BE_INETADDR	8
+#define BE_PDU		9
+};
+
+/*
+ * Defaults for SNMP PDU components
+ */
+#define DEF_COMMUNITY "public"
+#define DEF_VERSION 0
+
+/*
+ * constants for ASN.1 decoding
+ */
+#define OIDMUX 40
+#define ASNLEN_INETADDR 4
+#define ASN_SHIFT7 7
+#define ASN_SHIFT8 8
+#define ASN_BIT8 0x80
+#define ASN_LONGLEN 0x80
+
+#define ASN_ID_BITS 0x1f
+#define ASN_FORM_BITS 0x20
+#define ASN_FORM_SHIFT 5
+#define ASN_CLASS_BITS 0xc0
+#define ASN_CLASS_SHIFT 6
+
+#define ASN_ID_EXT 0x1f		/* extension ID in tag field */
+
+/*
+ * truncated==1 means the packet was complete, but we don't have all of
+ * it to decode.
+ */
+static int truncated;
+#define ifNotTruncated if (truncated) fputs("[|snmp]", stdout); else
+
+/*
+ * This decodes the next ASN.1 object in the stream pointed to by "p"
+ * (and of real-length "len") and stores the intermediate data in the
+ * provided BE object.
+ *
+ * This returns -l if it fails (i.e., the ASN.1 stream is not valid).
+ * O/w, this returns the number of bytes parsed from "p".
+ */
+static int
+asn1_parse(register const u_char *p, u_int len, struct be *elem)
+{
+	u_char form, class, id;
+	int i, hdr;
+
+	elem->asnlen = 0;
+	elem->type = BE_ANY;
+	if (len < 1) {
+		ifNotTruncated puts("[nothing to parse], stdout");
+		return -1;
+	}
+
+	/*
+	 * it would be nice to use a bit field, but you can't depend on them.
+	 *  +---+---+---+---+---+---+---+---+
+	 *  + class |frm|        id         |
+	 *  +---+---+---+---+---+---+---+---+
+	 *    7   6   5   4   3   2   1   0
+	 */
+	id = *p & ASN_ID_BITS;		/* lower 5 bits, range 00-1f */
+#ifdef notdef
+	form = (*p & 0xe0) >> 5;	/* move upper 3 bits to lower 3 */
+	class = form >> 1;		/* bits 7&6 -> bits 1&0, range 0-3 */
+	form &= 0x1;			/* bit 5 -> bit 0, range 0-1 */
+#else
+	form = (u_char)(*p & ASN_FORM_BITS) >> ASN_FORM_SHIFT;
+	class = (u_char)(*p & ASN_CLASS_BITS) >> ASN_CLASS_SHIFT;
+#endif
+	elem->form = form;
+	elem->class = class;
+	elem->id = id;
+	if (vflag)
+		printf("|%.2x", *p);
+	p++; len--; hdr = 1;
+	/* extended tag field */
+	if (id == ASN_ID_EXT) {
+		for (id = 0; *p & ASN_BIT8 && len > 0; len--, hdr++, p++) {
+			if (vflag)
+				printf("|%.2x", *p);
+			id = (id << 7) | (*p & ~ASN_BIT8);
+		}
+		if (len == 0 && *p & ASN_BIT8) {
+			ifNotTruncated fputs("[Xtagfield?]", stdout);
+			return -1;
+		}
+		elem->id = id = (id << 7) | *p;
+		--len;
+		++hdr;
+		++p;
+	}
+	if (len < 1) {
+		ifNotTruncated fputs("[no asnlen]", stdout);
+		return -1;
+	}
+	elem->asnlen = *p;
+	if (vflag)
+		printf("|%.2x", *p);
+	p++; len--; hdr++;
+	if (elem->asnlen & ASN_BIT8) {
+		int noct = elem->asnlen % ASN_BIT8;
+		elem->asnlen = 0;
+		if (len < noct) {
+			ifNotTruncated printf("[asnlen? %d<%d]", len, noct);
+			return -1;
+		}
+		for (; noct-- > 0; len--, hdr++) {
+			if (vflag)
+				printf("|%.2x", *p);
+			elem->asnlen = (elem->asnlen << ASN_SHIFT8) | *p++;
+		}
+	}
+	if (len < elem->asnlen) {
+		if (!truncated) {
+			printf("[len%d<asnlen%u]", len, elem->asnlen);
+			return -1;
+		}
+		/* maybe should check at least 4? */
+		elem->asnlen = len;
+	}
+	if (form >= sizeof(Form)/sizeof(Form[0])) {
+		ifNotTruncated printf("[form?%d]", form);
+		return -1;
+	}
+	if (class >= sizeof(Class)/sizeof(Class[0])) {
+		ifNotTruncated printf("[class?%c/%d]", *Form[form], class);
+		return -1;
+	}
+	if ((int)id >= Class[class].numIDs) {
+		ifNotTruncated printf("[id?%c/%s/%d]", *Form[form],
+			Class[class].name, id);
+		return -1;
+	}
+
+	switch (form) {
+	case PRIMITIVE:
+		switch (class) {
+		case UNIVERSAL:
+			switch (id) {
+			case STRING:
+				elem->type = BE_STR;
+				elem->data.str = p;
+				break;
+
+			case INTEGER: {
+				register int32_t data;
+				elem->type = BE_INT;
+				data = 0;
+
+				if (*p & ASN_BIT8)	/* negative */
+					data = -1;
+				for (i = elem->asnlen; i-- > 0; p++)
+					data = (data << ASN_SHIFT8) | *p;
+				elem->data.integer = data;
+				break;
+			}
+
+			case OBJECTID:
+				elem->type = BE_OID;
+				elem->data.raw = (caddr_t)p;
+				break;
+
+			case ASN_NULL:
+				elem->type = BE_NULL;
+				elem->data.raw = NULL;
+				break;
+
+			default:
+				elem->type = BE_OCTET;
+				elem->data.raw = (caddr_t)p;
+				printf("[P/U/%s]",
+					Class[class].Id[id]);
+				break;
+			}
+			break;
+
+		case APPLICATION:
+			switch (id) {
+			case IPADDR:
+				elem->type = BE_INETADDR;
+				elem->data.raw = (caddr_t)p;
+				break;
+
+			case COUNTER:
+			case GAUGE:
+			case TIMETICKS: {
+				register u_int32_t data;
+				elem->type = BE_UNS;
+				data = 0;
+				for (i = elem->asnlen; i-- > 0; p++)
+					data = (data << 8) + *p;
+				elem->data.uns = data;
+				break;
+			}
+
+			default:
+				elem->type = BE_OCTET;
+				elem->data.raw = (caddr_t)p;
+				printf("[P/A/%s]",
+					Class[class].Id[id]);
+				break;
+			}
+			break;
+
+		default:
+			elem->type = BE_OCTET;
+			elem->data.raw = (caddr_t)p;
+			printf("[P/%s/%s]",
+				Class[class].name, Class[class].Id[id]);
+			break;
+		}
+		break;
+
+	case CONSTRUCTED:
+		switch (class) {
+		case UNIVERSAL:
+			switch (id) {
+			case SEQUENCE:
+				elem->type = BE_SEQ;
+				elem->data.raw = (caddr_t)p;
+				break;
+
+			default:
+				elem->type = BE_OCTET;
+				elem->data.raw = (caddr_t)p;
+				printf("C/U/%s", Class[class].Id[id]);
+				break;
+			}
+			break;
+
+		case CONTEXT:
+			elem->type = BE_PDU;
+			elem->data.raw = (caddr_t)p;
+			break;
+
+		default:
+			elem->type = BE_OCTET;
+			elem->data.raw = (caddr_t)p;
+			printf("C/%s/%s",
+				Class[class].name, Class[class].Id[id]);
+			break;
+		}
+		break;
+	}
+	p += elem->asnlen;
+	len -= elem->asnlen;
+	return elem->asnlen + hdr;
+}
+
+/*
+ * Display the ASN.1 object represented by the BE object.
+ * This used to be an integral part of asn1_parse() before the intermediate
+ * BE form was added.
+ */
+static void
+asn1_print(struct be *elem)
+{
+	u_char *p = (u_char *)elem->data.raw;
+	u_int32_t asnlen = elem->asnlen;
+	int i;
+
+	switch (elem->type) {
+
+	case BE_OCTET:
+		for (i = asnlen; i-- > 0; p++);
+			printf("_%.2x", *p);
+		break;
+
+	case BE_NULL:
+		break;
+
+	case BE_OID: {
+	int o = 0, first = -1, i = asnlen;
+
+		if (!nflag && asnlen > 2) {
+			struct obj_abrev *a = &obj_abrev_list[0];
+			for (; a->node; a++) {
+				if (!memcmp(a->oid, (char *)p,
+				    strlen(a->oid))) {
+					objp = a->node->child;
+					i -= strlen(a->oid);
+					p += strlen(a->oid);
+					fputs(a->prefix, stdout);
+					first = 1;
+					break;
+				}
+			}
+		}
+		for (; i-- > 0; p++) {
+			o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8);
+			if (*p & ASN_LONGLEN)
+				continue;
+
+			/*
+			 * first subitem encodes two items with 1st*OIDMUX+2nd
+			 */
+			if (first < 0) {
+				if (!nflag)
+					objp = mibroot;
+				first = 0;
+				OBJ_PRINT(o/OIDMUX, first);
+				o %= OIDMUX;
+			}
+			OBJ_PRINT(o, first);
+			if (--first < 0)
+				first = 0;
+			o = 0;
+		}
+		break;
+	}
+
+	case BE_INT:
+		printf("%d", elem->data.integer);
+		break;
+
+	case BE_UNS:
+		printf("%d", elem->data.uns);
+		break;
+
+	case BE_STR: {
+		register int printable = 1, first = 1;
+		const u_char *p = elem->data.str;
+		for (i = asnlen; printable && i-- > 0; p++)
+			printable = isprint(*p) || isspace(*p);
+		p = elem->data.str;
+		if (printable) {
+			putchar('"');
+			(void)fn_print(p, p + asnlen);
+			putchar('"');
+		} else
+			for (i = asnlen; i-- > 0; p++) {
+				printf(first ? "%.2x" : "_%.2x", *p);
+				first = 0;
+			}
+		break;
+	}
+
+	case BE_SEQ:
+		printf("Seq(%u)", elem->asnlen);
+		break;
+
+	case BE_INETADDR: {
+		char sep;
+		if (asnlen != ASNLEN_INETADDR)
+			printf("[inetaddr len!=%d]", ASNLEN_INETADDR);
+		sep='[';
+		for (i = asnlen; i-- > 0; p++) {
+			printf("%c%u", sep, *p);
+			sep='.';
+		}
+		putchar(']');
+		break;
+	}
+
+	case BE_PDU:
+		printf("%s(%u)",
+			Class[CONTEXT].Id[elem->id], elem->asnlen);
+		break;
+
+	case BE_ANY:
+		fputs("[BE_ANY!?]", stdout);
+		break;
+
+	default:
+		fputs("[be!?]", stdout);
+		break;
+	}
+}
+
+#ifdef notdef
+/*
+ * This is a brute force ASN.1 printer: recurses to dump an entire structure.
+ * This will work for any ASN.1 stream, not just an SNMP PDU.
+ *
+ * By adding newlines and spaces at the correct places, this would print in
+ * Rose-Normal-Form.
+ *
+ * This is not currently used.
+ */
+static void
+asn1_decode(u_char *p, u_int length)
+{
+	struct be elem;
+	int i = 0;
+
+	while (i >= 0 && length > 0) {
+		i = asn1_parse(p, length, &elem);
+		if (i >= 0) {
+			fputs(" ", stdout);
+			asn1_print(&elem);
+			if (elem.type == BE_SEQ || elem.type == BE_PDU) {
+				fputs(" {", stdout);
+				asn1_decode(elem.data.raw, elem.asnlen);
+				fputs(" }", stdout);
+			}
+			length -= i;
+			p += i;
+		}
+	}
+}
+#endif
+
+/*
+ * General SNMP header
+ *	SEQUENCE {
+ *		version INTEGER {version-1(0)},
+ *		community OCTET STRING,
+ *		data ANY	-- PDUs
+ *	}
+ * PDUs for all but Trap: (see rfc1157 from page 15 on)
+ *	SEQUENCE {
+ *		request-id INTEGER,
+ *		error-status INTEGER,
+ *		error-index INTEGER,
+ *		varbindlist SEQUENCE OF
+ *			SEQUENCE {
+ *				name ObjectName,
+ *				value ObjectValue
+ *			}
+ *	}
+ * PDU for Trap:
+ *	SEQUENCE {
+ *		enterprise OBJECT IDENTIFIER,
+ *		agent-addr NetworkAddress,
+ *		generic-trap INTEGER,
+ *		specific-trap INTEGER,
+ *		time-stamp TimeTicks,
+ *		varbindlist SEQUENCE OF
+ *			SEQUENCE {
+ *				name ObjectName,
+ *				value ObjectValue
+ *			}
+ *	}
+ */
+
+/*
+ * Decode SNMP varBind
+ */
+static void
+varbind_print(u_char pduid, const u_char *np, u_int length, int error)
+{
+	struct be elem;
+	int count = 0, ind;
+
+	/* Sequence of varBind */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_SEQ) {
+		fputs("[!SEQ of varbind]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	if (count < length)
+		printf("[%d extra after SEQ of varbind]", length - count);
+	/* descend */
+	length = elem.asnlen;
+	np = (u_char *)elem.data.raw;
+
+	for (ind = 1; length > 0; ind++) {
+		const u_char *vbend;
+		u_int vblength;
+
+		if (!error || ind == error)
+			fputs(" ", stdout);
+
+		/* Sequence */
+		if ((count = asn1_parse(np, length, &elem)) < 0)
+			return;
+		if (elem.type != BE_SEQ) {
+			fputs("[!varbind]", stdout);
+			asn1_print(&elem);
+			return;
+		}
+		vbend = np + count;
+		vblength = length - count;
+		/* descend */
+		length = elem.asnlen;
+		np = (u_char *)elem.data.raw;
+
+		/* objName (OID) */
+		if ((count = asn1_parse(np, length, &elem)) < 0)
+			return;
+		if (elem.type != BE_OID) {
+			fputs("[objName!=OID]", stdout);
+			asn1_print(&elem);
+			return;
+		}
+		if (!error || ind == error)
+			asn1_print(&elem);
+		length -= count;
+		np += count;
+
+		if (pduid != GETREQ && pduid != GETNEXTREQ && !error)
+				fputs("=", stdout);
+
+		/* objVal (ANY) */
+		if ((count = asn1_parse(np, length, &elem)) < 0)
+			return;
+		if (pduid == GETREQ || pduid == GETNEXTREQ) {
+			if (elem.type != BE_NULL) {
+				fputs("[objVal!=NULL]", stdout);
+				asn1_print(&elem);
+			}
+		} else
+			if (error && ind == error && elem.type != BE_NULL)
+				fputs("[err objVal!=NULL]", stdout);
+			if (!error || ind == error)
+				asn1_print(&elem);
+
+		length = vblength;
+		np = vbend;
+	}
+}
+
+/*
+ * Decode SNMP PDUs: GetRequest, GetNextRequest, GetResponse, and SetRequest
+ */
+static void
+snmppdu_print(u_char pduid, const u_char *np, u_int length)
+{
+	struct be elem;
+	int count = 0, error;
+
+	/* reqId (Integer) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_INT) {
+		fputs("[reqId!=INT]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	/* ignore the reqId */
+	length -= count;
+	np += count;
+
+	/* errorStatus (Integer) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_INT) {
+		fputs("[errorStatus!=INT]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	error = 0;
+	if ((pduid == GETREQ || pduid == GETNEXTREQ)
+	    && elem.data.integer != 0) {
+		char errbuf[10];
+		printf("[errorStatus(%s)!=0]",
+			DECODE_ErrorStatus(elem.data.integer));
+	} else if (elem.data.integer != 0) {
+		char errbuf[10];
+		printf(" %s", DECODE_ErrorStatus(elem.data.integer));
+		error = elem.data.integer;
+	}
+	length -= count;
+	np += count;
+
+	/* errorIndex (Integer) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_INT) {
+		fputs("[errorIndex!=INT]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	if ((pduid == GETREQ || pduid == GETNEXTREQ)
+	    && elem.data.integer != 0)
+		printf("[errorIndex(%d)!=0]", elem.data.integer);
+	else if (elem.data.integer != 0) {
+		if (!error)
+			printf("[errorIndex(%d) w/o errorStatus]",
+				elem.data.integer);
+		else {
+			printf("@%d", elem.data.integer);
+			error = elem.data.integer;
+		}
+	} else if (error) {
+		fputs("[errorIndex==0]", stdout);
+		error = 0;
+	}
+	length -= count;
+	np += count;
+
+	varbind_print(pduid, np, length, error);
+	return;
+}
+
+/*
+ * Decode SNMP Trap PDU
+ */
+static void
+trap_print(const u_char *np, u_int length)
+{
+	struct be elem;
+	int count = 0, generic;
+
+	putchar(' ');
+
+	/* enterprise (oid) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_OID) {
+		fputs("[enterprise!=OID]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	asn1_print(&elem);
+	length -= count;
+	np += count;
+
+	putchar(' ');
+
+	/* agent-addr (inetaddr) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_INETADDR) {
+		fputs("[agent-addr!=INETADDR]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	asn1_print(&elem);
+	length -= count;
+	np += count;
+
+	/* generic-trap (Integer) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_INT) {
+		fputs("[generic-trap!=INT]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	generic = elem.data.integer;
+	{
+		char buf[10];
+		printf(" %s", DECODE_GenericTrap(generic));
+	}
+	length -= count;
+	np += count;
+
+	/* specific-trap (Integer) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_INT) {
+		fputs("[specific-trap!=INT]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	if (generic != GT_ENTERPRISE) {
+		if (elem.data.integer != 0)
+			printf("[specific-trap(%d)!=0]", elem.data.integer);
+	} else
+		printf(" s=%d", elem.data.integer);
+	length -= count;
+	np += count;
+
+	putchar(' ');
+
+	/* time-stamp (TimeTicks) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_UNS) {			/* XXX */
+		fputs("[time-stamp!=TIMETICKS]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	asn1_print(&elem);
+	length -= count;
+	np += count;
+
+	varbind_print (TRAP, np, length, 0);
+	return;
+}
+
+/*
+ * Decode SNMP header and pass on to PDU printing routines
+ */
+void
+snmp_print(const u_char *np, u_int length)
+{
+	struct be elem, pdu;
+	int count = 0;
+
+	truncated = 0;
+
+	/* truncated packet? */
+	if (np + length > snapend) {
+		truncated = 1;
+		length = snapend - np;
+	}
+
+	putchar(' ');
+
+	/* initial Sequence */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_SEQ) {
+		fputs("[!init SEQ]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	if (count < length)
+		printf("[%d extra after iSEQ]", length - count);
+	/* descend */
+	length = elem.asnlen;
+	np = (u_char *)elem.data.raw;
+	/* Version (Integer) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_INT) {
+		fputs("[version!=INT]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	/* only handle version==0 */
+	if (elem.data.integer != DEF_VERSION) {
+		printf("[version(%d)!=0]", elem.data.integer);
+		return;
+	}
+	length -= count;
+	np += count;
+
+	/* Community (String) */
+	if ((count = asn1_parse(np, length, &elem)) < 0)
+		return;
+	if (elem.type != BE_STR) {
+		fputs("[comm!=STR]", stdout);
+		asn1_print(&elem);
+		return;
+	}
+	/* default community */
+	if (strncmp((char *)elem.data.str, DEF_COMMUNITY,
+	    sizeof(DEF_COMMUNITY) - 1))
+		/* ! "public" */
+		printf("C=%.*s ", (int)elem.asnlen, elem.data.str);
+	length -= count;
+	np += count;
+
+	/* PDU (Context) */
+	if ((count = asn1_parse(np, length, &pdu)) < 0)
+		return;
+	if (pdu.type != BE_PDU) {
+		fputs("[no PDU]", stdout);
+		return;
+	}
+	if (count < length)
+		printf("[%d extra after PDU]", length - count);
+	asn1_print(&pdu);
+	/* descend into PDU */
+	length = pdu.asnlen;
+	np = (u_char *)pdu.data.raw;
+
+	switch (pdu.id) {
+	case TRAP:
+		trap_print(np, length);
+		break;
+	case GETREQ:
+	case GETNEXTREQ:
+	case GETRESP:
+	case SETREQ:
+		snmppdu_print(pdu.id, np, length);
+		break;
+	}
+	return;
+}
diff --git a/tcpdump.tproj/print-sunrpc.c b/tcpdump.tproj/print-sunrpc.c
new file mode 100644
index 0000000..0c9f696
--- /dev/null
+++ b/tcpdump.tproj/print-sunrpc.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-sunrpc.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <rpc/rpc.h>
+#ifdef HAVE_RPC_RPCENT_H
+#include <rpc/rpcent.h>
+#endif
+#include <rpc/pmap_prot.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+static struct tok proc2str[] = {
+	{ PMAPPROC_NULL,	"null" },
+	{ PMAPPROC_SET,		"set" },
+	{ PMAPPROC_UNSET,	"unset" },
+	{ PMAPPROC_GETPORT,	"getport" },
+	{ PMAPPROC_DUMP,	"dump" },
+	{ PMAPPROC_CALLIT,	"call" },
+	{ 0,			NULL }
+};
+
+/* Forwards */
+static char *progstr(u_int32_t);
+
+void
+sunrpcrequest_print(register const u_char *bp, register u_int length,
+		    register const u_char *bp2)
+{
+	register const struct rpc_msg *rp;
+	register const struct ip *ip;
+	u_int32_t x;
+
+	rp = (struct rpc_msg *)bp;
+	ip = (struct ip *)bp2;
+
+	if (!nflag)
+		(void)printf("%s.%x > %s.sunrpc: %d",
+			     ipaddr_string(&ip->ip_src),
+			     (u_int32_t)ntohl(rp->rm_xid),
+			     ipaddr_string(&ip->ip_dst),
+			     length);
+	else
+		(void)printf("%s.%x > %s.%x: %d",
+			     ipaddr_string(&ip->ip_src),
+			     (u_int32_t)ntohl(rp->rm_xid),
+			     ipaddr_string(&ip->ip_dst),
+			     PMAPPORT,
+			     length);
+	printf(" %s", tok2str(proc2str, " proc #%u",
+	    (u_int32_t)ntohl(rp->rm_call.cb_proc)));
+	x = ntohl(rp->rm_call.cb_rpcvers);
+	if (x != 2)
+		printf(" [rpcver %u]", x);
+
+	switch (ntohl(rp->rm_call.cb_proc)) {
+
+	case PMAPPROC_SET:
+	case PMAPPROC_UNSET:
+	case PMAPPROC_GETPORT:
+	case PMAPPROC_CALLIT:
+		x = ntohl(rp->rm_call.cb_prog);
+		if (!nflag)
+			printf(" %s", progstr(x));
+		else
+			printf(" %u", x);
+		printf(".%u", (u_int32_t)ntohl(rp->rm_call.cb_vers));
+		break;
+	}
+}
+
+static char *
+progstr(prog)
+	u_int32_t prog;
+{
+	register struct rpcent *rp;
+	static char buf[32];
+	static lastprog = 0;
+
+	if (lastprog != 0 && prog == lastprog)
+		return (buf);
+	rp = getrpcbynumber(prog);
+	if (rp == NULL)
+		(void) sprintf(buf, "#%u", prog);
+	else
+		strcpy(buf, rp->r_name);
+	return (buf);
+}
diff --git a/tcpdump.tproj/print-tcp.c b/tcpdump.tproj/print-tcp.c
new file mode 100644
index 0000000..2c0d1e3
--- /dev/null
+++ b/tcpdump.tproj/print-tcp.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-tcp.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+/* Compatibility */
+#ifndef TCPOPT_WSCALE
+#define	TCPOPT_WSCALE		3	/* window scale factor (rfc1072) */
+#endif
+#ifndef TCPOPT_SACKOK
+#define	TCPOPT_SACKOK		4	/* selective ack ok (rfc1072) */
+#endif
+#ifndef TCPOPT_SACK
+#define	TCPOPT_SACK		5	/* selective ack (rfc1072) */
+#endif
+#ifndef TCPOPT_ECHO
+#define	TCPOPT_ECHO		6	/* echo (rfc1072) */
+#endif
+#ifndef TCPOPT_ECHOREPLY
+#define	TCPOPT_ECHOREPLY	7	/* echo (rfc1072) */
+#endif
+#ifndef TCPOPT_TIMESTAMP
+#define TCPOPT_TIMESTAMP	8	/* timestamps (rfc1323) */
+#endif
+#ifndef TCPOPT_CC
+#define TCPOPT_CC		11	/* T/TCP CC options (rfc1644) */
+#endif
+#ifndef TCPOPT_CCNEW
+#define TCPOPT_CCNEW		12	/* T/TCP CC options (rfc1644) */
+#endif
+#ifndef TCPOPT_CCECHO
+#define TCPOPT_CCECHO		13	/* T/TCP CC options (rfc1644) */
+#endif
+
+struct tha {
+	struct in_addr src;
+	struct in_addr dst;
+	u_int port;
+};
+
+struct tcp_seq_hash {
+	struct tcp_seq_hash *nxt;
+	struct tha addr;
+	tcp_seq seq;
+	tcp_seq ack;
+};
+
+#define TSEQ_HASHSIZE 919
+
+/* These tcp optinos do not have the size octet */
+#define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP)
+
+static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
+
+
+void
+tcp_print(register const u_char *bp, register u_int length,
+	  register const u_char *bp2)
+{
+	register const struct tcphdr *tp;
+	register const struct ip *ip;
+	register u_char flags;
+	register int hlen;
+	register char ch;
+	u_short sport, dport, win, urp;
+	u_int32_t seq, ack;
+
+	tp = (struct tcphdr *)bp;
+	ip = (struct ip *)bp2;
+	ch = '\0';
+	TCHECK(*tp);
+	if (length < sizeof(*tp)) {
+		(void)printf("truncated-tcp %d", length);
+		return;
+	}
+
+	sport = ntohs(tp->th_sport);
+	dport = ntohs(tp->th_dport);
+	seq = ntohl(tp->th_seq);
+	ack = ntohl(tp->th_ack);
+	win = ntohs(tp->th_win);
+	urp = ntohs(tp->th_urp);
+
+	(void)printf("%s.%s > %s.%s: ",
+		ipaddr_string(&ip->ip_src), tcpport_string(sport),
+		ipaddr_string(&ip->ip_dst), tcpport_string(dport));
+
+	if (qflag) {
+		(void)printf("tcp %d", length - tp->th_off * 4);
+		return;
+	}
+	if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH)) {
+		if (flags & TH_SYN)
+			putchar('S');
+		if (flags & TH_FIN)
+			putchar('F');
+		if (flags & TH_RST)
+			putchar('R');
+		if (flags & TH_PUSH)
+			putchar('P');
+	} else
+		putchar('.');
+
+	if (!Sflag && (flags & TH_ACK)) {
+		register struct tcp_seq_hash *th;
+		register int rev;
+		struct tha tha;
+		/*
+		 * Find (or record) the initial sequence numbers for
+		 * this conversation.  (we pick an arbitrary
+		 * collating order so there's only one entry for
+		 * both directions).
+		 */
+		if (sport < dport ||
+		    (sport == dport &&
+		     ip->ip_src.s_addr < ip->ip_dst.s_addr)) {
+			tha.src = ip->ip_src, tha.dst = ip->ip_dst;
+			tha.port = sport << 16 | dport;
+			rev = 0;
+		} else {
+			tha.src = ip->ip_dst, tha.dst = ip->ip_src;
+			tha.port = dport << 16 | sport;
+			rev = 1;
+		}
+
+		for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
+		     th->nxt; th = th->nxt)
+			if (!memcmp((char *)&tha, (char *)&th->addr,
+				  sizeof(th->addr)))
+				break;
+
+		if (!th->nxt || flags & TH_SYN) {
+			/* didn't find it or new conversation */
+			if (th->nxt == NULL) {
+				th->nxt = (struct tcp_seq_hash *)
+					calloc(1, sizeof(*th));
+				if (th->nxt == NULL)
+					error("tcp_print: calloc");
+			}
+			th->addr = tha;
+			if (rev)
+				th->ack = seq, th->seq = ack - 1;
+			else
+				th->seq = seq, th->ack = ack - 1;
+		} else {
+			if (rev)
+				seq -= th->ack, ack -= th->seq;
+			else
+				seq -= th->seq, ack -= th->ack;
+		}
+	}
+	hlen = tp->th_off * 4;
+	if (hlen > length) {
+		(void)printf(" [bad hdr length]");
+		return;
+	}
+	length -= hlen;
+	if (length > 0 || flags & (TH_SYN | TH_FIN | TH_RST))
+		(void)printf(" %u:%u(%d)", seq, seq + length, length);
+	if (flags & TH_ACK)
+		(void)printf(" ack %u", ack);
+
+	(void)printf(" win %d", win);
+
+	if (flags & TH_URG)
+		(void)printf(" urg %d", urp);
+	/*
+	 * Handle any options.
+	 */
+	if ((hlen -= sizeof(*tp)) > 0) {
+		register const u_char *cp;
+		register int i, opt, len, datalen;
+
+		cp = (const u_char *)tp + sizeof(*tp);
+		putchar(' ');
+		ch = '<';
+		while (hlen > 0) {
+			putchar(ch);
+			TCHECK(*cp);
+			opt = *cp++;
+			if (ZEROLENOPT(opt))
+				len = 1;
+			else {
+				TCHECK(*cp);
+				len = *cp++;	/* total including type, len */
+				if (len < 2 || len > hlen)
+					goto bad;
+				--hlen;		/* account for length byte */
+			}
+			--hlen;			/* account for type byte */
+			datalen = 0;
+
+/* Bail if "l" bytes of data are not left or were not captured  */
+#define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); }
+
+			switch (opt) {
+
+			case TCPOPT_MAXSEG:
+				(void)printf("mss");
+				datalen = 2;
+				LENCHECK(datalen);
+				(void)printf(" %u", EXTRACT_16BITS(cp));
+
+				break;
+
+			case TCPOPT_EOL:
+				(void)printf("eol");
+				break;
+
+			case TCPOPT_NOP:
+				(void)printf("nop");
+				break;
+
+			case TCPOPT_WSCALE:
+				(void)printf("wscale");
+				datalen = 1;
+				LENCHECK(datalen);
+				(void)printf(" %u", *cp);
+				break;
+
+			case TCPOPT_SACKOK:
+				(void)printf("sackOK");
+				break;
+
+			case TCPOPT_SACK:
+				(void)printf("sack");
+				datalen = len - 2;
+				for (i = 0; i < datalen; i += 4) {
+					LENCHECK(i + 4);
+					/* block-size@relative-origin */
+					(void)printf(" %u@%u",
+					    EXTRACT_16BITS(cp + i + 2),
+					    EXTRACT_16BITS(cp + i));
+				}
+				if (datalen % 4)
+					(void)printf("[len %d]", len);
+				break;
+
+			case TCPOPT_ECHO:
+				(void)printf("echo");
+				datalen = 4;
+				LENCHECK(datalen);
+				(void)printf(" %u", EXTRACT_32BITS(cp));
+				break;
+
+			case TCPOPT_ECHOREPLY:
+				(void)printf("echoreply");
+				datalen = 4;
+				LENCHECK(datalen);
+				(void)printf(" %u", EXTRACT_32BITS(cp));
+				break;
+
+			case TCPOPT_TIMESTAMP:
+				(void)printf("timestamp");
+				datalen = 8;
+				LENCHECK(4);
+				(void)printf(" %u", EXTRACT_32BITS(cp));
+				LENCHECK(datalen);
+				(void)printf(" %u", EXTRACT_32BITS(cp + 4));
+				break;
+
+			case TCPOPT_CC:
+				(void)printf("cc");
+				datalen = 4;
+				LENCHECK(datalen);
+				(void)printf(" %u", EXTRACT_32BITS(cp));
+				break;
+
+			case TCPOPT_CCNEW:
+				(void)printf("ccnew");
+				datalen = 4;
+				LENCHECK(datalen);
+				(void)printf(" %u", EXTRACT_32BITS(cp));
+				break;
+
+			case TCPOPT_CCECHO:
+				(void)printf("ccecho");
+				datalen = 4;
+				LENCHECK(datalen);
+				(void)printf(" %u", EXTRACT_32BITS(cp));
+				break;
+
+			default:
+				(void)printf("opt-%d:", opt);
+				datalen = len - 2;
+				for (i = 0; i < datalen; ++i) {
+					LENCHECK(i);
+					(void)printf("%02x", cp[i]);
+				}
+				break;
+			}
+
+			/* Account for data printed */
+			cp += datalen;
+			hlen -= datalen;
+
+			/* Check specification against observed length */
+			++datalen;			/* option octet */
+			if (!ZEROLENOPT(opt))
+				++datalen;		/* size octet */
+			if (datalen != len)
+				(void)printf("[len %d]", len);
+			ch = ',';
+			if (opt == TCPOPT_EOL)
+				break;
+		}
+		putchar('>');
+	}
+	return;
+bad:
+	fputs("[bad opt]", stdout);
+	if (ch != '\0')
+		putchar('>');
+	return;
+trunc:
+	fputs("[|tcp]", stdout);
+	if (ch != '\0')
+		putchar('>');
+}
+
diff --git a/tcpdump.tproj/print-tftp.c b/tcpdump.tproj/print-tftp.c
new file mode 100644
index 0000000..9db5775
--- /dev/null
+++ b/tcpdump.tproj/print-tftp.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print trivial file transfer protocol packets.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-tftp.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <arpa/tftp.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/* op code to string mapping */
+static struct tok op2str[] = {
+	{ RRQ,		"RRQ" },	/* read request */
+	{ WRQ,		"WRQ" },	/* write request */
+	{ DATA,		"DATA" },	/* data packet */
+	{ ACK,		"ACK" },	/* acknowledgement */
+	{ ERROR,	"ERROR" },	/* error code */
+	{ 0,		NULL }
+};
+
+/* error code to string mapping */
+static struct tok err2str[] = {
+	{ EUNDEF,	"EUNDEF" },	/* not defined */
+	{ ENOTFOUND,	"ENOTFOUND" },	/* file not found */
+	{ EACCESS,	"EACCESS" },	/* access violation */
+	{ ENOSPACE,	"ENOSPACE" },	/* disk full or allocation exceeded */
+	{ EBADOP,	"EBADOP" },	/* illegal TFTP operation */
+	{ EBADID,	"EBADID" },	/* unknown transfer ID */
+	{ EEXISTS,	"EEXISTS" },	/* file already exists */
+	{ ENOUSER,	"ENOUSER" },	/* no such user */
+	{ 0,		NULL }
+};
+
+/*
+ * Print trivial file transfer program requests
+ */
+void
+tftp_print(register const u_char *bp, u_int length)
+{
+	register const struct tftphdr *tp;
+	register const char *cp;
+	register const u_char *p;
+	register int opcode, i;
+	static char tstr[] = " [|tftp]";
+
+	tp = (const struct tftphdr *)bp;
+
+	/* Print length */
+	printf(" %d", length);
+
+	/* Print tftp request type */
+	TCHECK(tp->th_opcode);
+	opcode = ntohs(tp->th_opcode);
+	cp = tok2str(op2str, "tftp-#%d", opcode);
+	printf(" %s", cp);
+	/* Bail if bogus opcode */
+	if (*cp == 't')
+		return;
+
+	switch (opcode) {
+
+	case RRQ:
+	case WRQ:
+		/*
+		 * XXX Not all arpa/tftp.h's specify th_stuff as any
+		 * array; use address of th_block instead
+		 */
+#ifdef notdef
+		p = (u_char *)tp->th_stuff;
+#else
+		p = (u_char *)&tp->th_block;
+#endif
+		fputs(" \"", stdout);
+		i = fn_print(p, snapend);
+		putchar('"');
+		if (i)
+			goto trunc;
+		break;
+
+	case ACK:
+	case DATA:
+		TCHECK(tp->th_block);
+		printf(" block %d", ntohs(tp->th_block));
+		break;
+
+	case ERROR:
+		/* Print error code string */
+		TCHECK(tp->th_code);
+		printf(" %s ", tok2str(err2str, "tftp-err-#%d \"",
+				       ntohs(tp->th_code)));
+		/* Print error message string */
+		i = fn_print((const u_char *)tp->th_data, snapend);
+		putchar('"');
+		if (i)
+			goto trunc;
+		break;
+
+	default:
+		/* We shouldn't get here */
+		printf("(unknown #%d)", opcode);
+		break;
+	}
+	return;
+trunc:
+	fputs(tstr, stdout);
+	return;
+}
diff --git a/tcpdump.tproj/print-udp.c b/tcpdump.tproj/print-udp.c
new file mode 100644
index 0000000..f8e4366
--- /dev/null
+++ b/tcpdump.tproj/print-udp.c
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-udp.c,v 1.1.1.1 1999/05/02 03:58:35 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#undef NOERROR					/* Solaris sucks */
+#undef T_UNSPEC					/* SINIX does too */
+#include <arpa/nameser.h>
+#include <arpa/tftp.h>
+
+#include <rpc/rpc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "appletalk.h"
+
+#include "nfsv2.h"
+#include "bootp.h"
+
+struct rtcphdr {
+	u_short rh_flags;	/* T:2 P:1 CNT:5 PT:8 */
+	u_short rh_len;		/* length of message (in words) */
+	u_int rh_ssrc;		/* synchronization src id */
+};
+
+typedef struct {
+	u_int upper;		/* more significant 32 bits */
+	u_int lower;		/* less significant 32 bits */
+} ntp64;
+
+/*
+ * Sender report.
+ */
+struct rtcp_sr {
+	ntp64 sr_ntp;		/* 64-bit ntp timestamp */
+	u_int sr_ts;		/* reference media timestamp */
+	u_int sr_np;		/* no. packets sent */
+	u_int sr_nb;		/* no. bytes sent */
+};
+
+/*
+ * Receiver report.
+ * Time stamps are middle 32-bits of ntp timestamp.
+ */
+struct rtcp_rr {
+	u_int rr_srcid;		/* sender being reported */
+	u_int rr_nl;		/* no. packets lost */
+	u_int rr_ls;		/* extended last seq number received */
+	u_int rr_dv;		/* jitter (delay variance) */
+	u_int rr_lsr;		/* orig. ts from last rr from this src  */
+	u_int rr_dlsr;		/* time from recpt of last rr to xmit time */
+};
+
+/*XXX*/
+#define RTCP_PT_SR	200
+#define RTCP_PT_RR	201
+#define RTCP_PT_SDES	202
+#define 	RTCP_SDES_CNAME	1
+#define 	RTCP_SDES_NAME	2
+#define 	RTCP_SDES_EMAIL	3
+#define 	RTCP_SDES_PHONE	4
+#define 	RTCP_SDES_LOC	5
+#define 	RTCP_SDES_TOOL	6
+#define 	RTCP_SDES_NOTE	7
+#define 	RTCP_SDES_PRIV	8
+#define RTCP_PT_BYE	203
+#define RTCP_PT_APP	204
+
+static void
+vat_print(const void *hdr, u_int len, register const struct udphdr *up)
+{
+	/* vat/vt audio */
+	u_int ts = *(u_short *)hdr;
+	if ((ts & 0xf060) != 0) {
+		/* probably vt */
+		(void)printf(" udp/vt %u %d / %d",
+			     (u_int32_t)(ntohs(up->uh_ulen) - sizeof(*up)),
+			     ts & 0x3ff, ts >> 10);
+	} else {
+		/* probably vat */
+		u_int i0 = ntohl(((u_int *)hdr)[0]);
+		u_int i1 = ntohl(((u_int *)hdr)[1]);
+		printf(" udp/vat %u c%d %u%s",
+			(u_int32_t)(ntohs(up->uh_ulen) - sizeof(*up) - 8),
+			i0 & 0xffff,
+			i1, i0 & 0x800000? "*" : "");
+		/* audio format */
+		if (i0 & 0x1f0000)
+			printf(" f%d", (i0 >> 16) & 0x1f);
+		if (i0 & 0x3f000000)
+			printf(" s%d", (i0 >> 24) & 0x3f);
+	}
+}
+
+static void
+rtp_print(const void *hdr, u_int len, register const struct udphdr *up)
+{
+	/* rtp v1 or v2 */
+	u_int *ip = (u_int *)hdr;
+	u_int hasopt, hasext, contype, hasmarker;
+	u_int i0 = ntohl(((u_int *)hdr)[0]);
+	u_int i1 = ntohl(((u_int *)hdr)[1]);
+	u_int dlen = ntohs(up->uh_ulen) - sizeof(*up) - 8;
+	const char * ptype;
+
+	ip += 2;
+	len >>= 2;
+	len -= 2;
+	hasopt = 0;
+	hasext = 0;
+	if ((i0 >> 30) == 1) {
+		/* rtp v1 */
+		hasopt = i0 & 0x800000;
+		contype = (i0 >> 16) & 0x3f;
+		hasmarker = i0 & 0x400000;
+		ptype = "rtpv1";
+	} else {
+		/* rtp v2 */
+		hasext = i0 & 0x10000000;
+		contype = (i0 >> 16) & 0x7f;
+		hasmarker = i0 & 0x800000;
+		dlen -= 4;
+		ptype = "rtp";
+		ip += 1;
+		len -= 1;
+	}
+	printf(" udp/%s %d c%d %s%s %d %u",
+		ptype,
+		dlen,
+		contype,
+		(hasopt || hasext)? "+" : "",
+		hasmarker? "*" : "",
+		i0 & 0xffff,
+		i1);
+	if (vflag) {
+		printf(" %u", i1);
+		if (hasopt) {
+			u_int i2, optlen;
+			do {
+				i2 = ip[0];
+				optlen = (i2 >> 16) & 0xff;
+				if (optlen == 0 || optlen > len) {
+					printf(" !opt");
+					return;
+				}
+				ip += optlen;
+				len -= optlen;
+			} while ((int)i2 >= 0);
+		}
+		if (hasext) {
+			u_int i2, extlen;
+			i2 = ip[0];
+			extlen = (i2 & 0xffff) + 1;
+			if (extlen > len) {
+				printf(" !ext");
+				return;
+			}
+			ip += extlen;
+		}
+		if (contype == 0x1f) /*XXX H.261 */
+			printf(" 0x%04x", ip[0] >> 16);
+	}
+}
+
+static const u_char *
+rtcp_print(const u_char *hdr, const u_char *ep)
+{
+	/* rtp v2 control (rtcp) */
+	struct rtcp_rr *rr = 0;
+	struct rtcp_sr *sr;
+	struct rtcphdr *rh = (struct rtcphdr *)hdr;
+	u_int len;
+	u_short flags;
+	int cnt;
+	double ts, dts;
+	if ((u_char *)(rh + 1) > ep) {
+		printf(" [|rtcp]");
+		return (ep);
+	}
+	len = (ntohs(rh->rh_len) + 1) * 4;
+	flags = ntohs(rh->rh_flags);
+	cnt = (flags >> 8) & 0x1f;
+	switch (flags & 0xff) {
+	case RTCP_PT_SR:
+		sr = (struct rtcp_sr *)(rh + 1);
+		printf(" sr");
+		if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh))
+			printf(" [%d]", len);
+		if (vflag)
+		  printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
+		if ((u_char *)(sr + 1) > ep) {
+			printf(" [|rtcp]");
+			return (ep);
+		}
+		ts = (double)((u_int32_t)ntohl(sr->sr_ntp.upper)) +
+		    ((double)((u_int32_t)ntohl(sr->sr_ntp.lower)) /
+		    4294967296.0);
+		printf(" @%.2f %u %up %ub", ts, (u_int32_t)ntohl(sr->sr_ts),
+		    (u_int32_t)ntohl(sr->sr_np), (u_int32_t)ntohl(sr->sr_nb));
+		rr = (struct rtcp_rr *)(sr + 1);
+		break;
+	case RTCP_PT_RR:
+		printf(" rr");
+		if (len != cnt * sizeof(*rr) + sizeof(*rh))
+			printf(" [%d]", len);
+		rr = (struct rtcp_rr *)(rh + 1);
+		if (vflag)
+		  printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
+		break;
+	case RTCP_PT_SDES:
+		printf(" sdes %d", len);
+		if (vflag)
+		  printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
+		cnt = 0;
+		break;
+	case RTCP_PT_BYE:
+		printf(" bye %d", len);
+		if (vflag)
+		  printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
+		cnt = 0;
+		break;
+	default:
+		printf(" type-0x%x %d", flags & 0xff, len);
+		cnt = 0;
+		break;
+	}
+	if (cnt > 1)
+		printf(" c%d", cnt);
+	while (--cnt >= 0) {
+		if ((u_char *)(rr + 1) > ep) {
+			printf(" [|rtcp]");
+			return (ep);
+		}
+		if (vflag)
+			printf(" %u", (u_int32_t)ntohl(rr->rr_srcid));
+		ts = (double)((u_int32_t)ntohl(rr->rr_lsr)) / 65536.;
+		dts = (double)((u_int32_t)ntohl(rr->rr_dlsr)) / 65536.;
+		printf(" %ul %us %uj @%.2f+%.2f",
+		    (u_int32_t)ntohl(rr->rr_nl) & 0x00ffffff,
+		    (u_int32_t)ntohl(rr->rr_ls),
+		    (u_int32_t)ntohl(rr->rr_dv), ts, dts);
+	}
+	return (hdr + len);
+}
+
+/* XXX probably should use getservbyname() and cache answers */
+#define TFTP_PORT 69		/*XXX*/
+#define KERBEROS_PORT 88	/*XXX*/
+#define SUNRPC_PORT 111		/*XXX*/
+#define SNMP_PORT 161		/*XXX*/
+#define NTP_PORT 123		/*XXX*/
+#define SNMPTRAP_PORT 162	/*XXX*/
+#define RIP_PORT 520		/*XXX*/
+#define KERBEROS_SEC_PORT 750	/*XXX*/
+
+void
+udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
+{
+	register const struct udphdr *up;
+	register const struct ip *ip;
+	register const u_char *cp;
+	register const u_char *ep = bp + length;
+	u_short sport, dport, ulen;
+
+	if (ep > snapend)
+		ep = snapend;
+	up = (struct udphdr *)bp;
+	ip = (struct ip *)bp2;
+	cp = (u_char *)(up + 1);
+	if (cp > snapend) {
+		printf("[|udp]");
+		return;
+	}
+	if (length < sizeof(struct udphdr)) {
+		(void)printf(" truncated-udp %d", length);
+		return;
+	}
+	length -= sizeof(struct udphdr);
+
+	sport = ntohs(up->uh_sport);
+	dport = ntohs(up->uh_dport);
+	ulen = ntohs(up->uh_ulen);
+	if (packettype) {
+		register struct rpc_msg *rp;
+		enum msg_type direction;
+
+		switch (packettype) {
+
+		case PT_VAT:
+			(void)printf("%s.%s > %s.%s:",
+				ipaddr_string(&ip->ip_src),
+				udpport_string(sport),
+				ipaddr_string(&ip->ip_dst),
+				udpport_string(dport));
+			vat_print((void *)(up + 1), length, up);
+			break;
+
+		case PT_WB:
+			(void)printf("%s.%s > %s.%s:",
+				ipaddr_string(&ip->ip_src),
+				udpport_string(sport),
+				ipaddr_string(&ip->ip_dst),
+				udpport_string(dport));
+			wb_print((void *)(up + 1), length);
+			break;
+
+		case PT_RPC:
+			rp = (struct rpc_msg *)(up + 1);
+			direction = (enum msg_type)ntohl(rp->rm_direction);
+			if (direction == CALL)
+				sunrpcrequest_print((u_char *)rp, length,
+				    (u_char *)ip);
+			else
+				nfsreply_print((u_char *)rp, length,
+				    (u_char *)ip);			/*XXX*/
+			break;
+
+		case PT_RTP:
+			(void)printf("%s.%s > %s.%s:",
+				ipaddr_string(&ip->ip_src),
+				udpport_string(sport),
+				ipaddr_string(&ip->ip_dst),
+				udpport_string(dport));
+			rtp_print((void *)(up + 1), length, up);
+			break;
+
+		case PT_RTCP:
+			(void)printf("%s.%s > %s.%s:",
+				ipaddr_string(&ip->ip_src),
+				udpport_string(sport),
+				ipaddr_string(&ip->ip_dst),
+				udpport_string(dport));
+			while (cp < ep)
+				cp = rtcp_print(cp, ep);
+			break;
+		}
+		return;
+	}
+
+	if (!qflag) {
+		register struct rpc_msg *rp;
+		enum msg_type direction;
+
+		rp = (struct rpc_msg *)(up + 1);
+		if (TTEST(rp->rm_direction)) {
+			direction = (enum msg_type)ntohl(rp->rm_direction);
+			if (dport == NFS_PORT && direction == CALL) {
+				nfsreq_print((u_char *)rp, length,
+				    (u_char *)ip);
+				return;
+			}
+			if (sport == NFS_PORT && direction == REPLY) {
+				nfsreply_print((u_char *)rp, length,
+				    (u_char *)ip);
+				return;
+			}
+#ifdef notdef
+			if (dport == SUNRPC_PORT && direction == CALL) {
+				sunrpcrequest_print((u_char *)rp, length, (u_char *)ip);
+				return;
+			}
+#endif
+		}
+		if (TTEST(((struct LAP *)cp)->type) &&
+		    ((struct LAP *)cp)->type == lapDDP &&
+		    (atalk_port(sport) || atalk_port(dport))) {
+			if (vflag)
+				fputs("kip ", stdout);
+			atalk_print(cp, length);
+			return;
+		}
+	}
+	(void)printf("%s.%s > %s.%s:",
+		ipaddr_string(&ip->ip_src), udpport_string(sport),
+		ipaddr_string(&ip->ip_dst), udpport_string(dport));
+
+	if (!qflag) {
+#define ISPORT(p) (dport == (p) || sport == (p))
+		if (ISPORT(NAMESERVER_PORT))
+			ns_print((const u_char *)(up + 1), length);
+		else if (ISPORT(TFTP_PORT))
+			tftp_print((const u_char *)(up + 1), length);
+		else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS))
+			bootp_print((const u_char *)(up + 1), length,
+			    sport, dport);
+		else if (ISPORT(RIP_PORT))
+			rip_print((const u_char *)(up + 1), length);
+		else if (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT))
+			snmp_print((const u_char *)(up + 1), length);
+		else if (ISPORT(NTP_PORT))
+			ntp_print((const u_char *)(up + 1), length);
+		else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT))
+			krb_print((const void *)(up + 1), length);
+		else if (dport == 3456)
+			vat_print((const void *)(up + 1), length, up);
+		/*
+		 * Kludge in test for whiteboard packets.
+		 */
+		else if (dport == 4567)
+			wb_print((const void *)(up + 1), length);
+		else
+			(void)printf(" udp %u",
+			    (u_int32_t)(ulen - sizeof(*up)));
+#undef ISPORT
+	} else
+		(void)printf(" udp %u", (u_int32_t)(ulen - sizeof(*up)));
+}
diff --git a/tcpdump.tproj/print-wb.c b/tcpdump.tproj/print-wb.c
new file mode 100644
index 0000000..3b0c160
--- /dev/null
+++ b/tcpdump.tproj/print-wb.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-wb.c,v 1.1.1.1 1999/05/02 03:58:35 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/* XXX need to add byte-swapping macros! */
+
+/*
+ * Largest packet size.  Everything should fit within this space.
+ * For instance, multiline objects are sent piecewise.
+ */
+#define MAXFRAMESIZE 1024
+
+/*
+ * Multiple drawing ops can be sent in one packet.  Each one starts on a
+ * an even multiple of DOP_ALIGN bytes, which must be a power of two.
+ */
+#define DOP_ALIGN 4
+#define DOP_ROUNDUP(x)	((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
+#define DOP_NEXT(d)\
+	((struct dophdr *)((u_char *)(d) + \
+			  DOP_ROUNDUP(ntohs((d)->dh_len) + sizeof(*(d)))))
+
+/*
+ * Format of the whiteboard packet header.
+ * The transport level header.
+ */
+struct pkt_hdr {
+	u_int32_t ph_src;		/* site id of source */
+	u_int32_t ph_ts;		/* time stamp (for skew computation) */
+	u_short ph_version;	/* version number */
+	u_char ph_type;		/* message type */
+	u_char ph_flags;	/* message flags */
+};
+
+/* Packet types */
+#define PT_DRAWOP	0	/* drawing operation */
+#define PT_ID		1	/* announcement packet */
+#define PT_RREQ		2	/* repair request */
+#define PT_RREP		3	/* repair reply */
+#define PT_KILL		4	/* terminate participation */
+#define PT_PREQ         5       /* page vector request */
+#define PT_PREP         7       /* page vector reply */
+
+/* flags */
+#define PF_USER		0x01	/* hint that packet has interactive data */
+#define PF_VIS		0x02	/* only visible ops wanted */
+
+struct PageID {
+	u_int32_t p_sid;		/* session id of initiator */
+	u_int32_t p_uid;		/* page number */
+};
+
+struct dophdr {
+	u_int32_t  dh_ts;		/* sender's timestamp */
+	u_short	dh_len;		/* body length */
+	u_char	dh_flags;
+	u_char	dh_type;	/* body type */
+	/* body follows */
+};
+/*
+ * Drawing op sub-types.
+ */
+#define DT_RECT         2
+#define DT_LINE         3
+#define DT_ML           4
+#define DT_DEL          5
+#define DT_XFORM        6
+#define DT_ELL          7
+#define DT_CHAR         8
+#define DT_STR          9
+#define DT_NOP          10
+#define DT_PSCODE       11
+#define DT_PSCOMP       12
+#define DT_REF          13
+#define DT_SKIP         14
+#define DT_HOLE         15
+#define DT_MAXTYPE      15
+
+/*
+ * A drawing operation.
+ */
+struct pkt_dop {
+	struct PageID pd_page;	/* page that operations apply to */
+	u_int32_t	pd_sseq;	/* start sequence number */
+	u_int32_t	pd_eseq;	/* end sequence number */
+	/* drawing ops follow */
+};
+
+/*
+ * A repair request.
+ */
+struct pkt_rreq {
+        u_int32_t pr_id;           /* source id of drawops to be repaired */
+        struct PageID pr_page;           /* page of drawops */
+        u_int32_t pr_sseq;         /* start seqno */
+        u_int32_t pr_eseq;         /* end seqno */
+};
+
+/*
+ * A repair reply.
+ */
+struct pkt_rrep {
+	u_int32_t pr_id;	/* original site id of ops  */
+	struct pkt_dop pr_dop;
+	/* drawing ops follow */
+};
+
+struct id_off {
+        u_int32_t id;
+        u_int32_t off;
+};
+
+struct pgstate {
+	u_int32_t slot;
+	struct PageID page;
+	u_short nid;
+	u_short rsvd;
+        /* seqptr's */
+};
+
+/*
+ * An announcement packet.
+ */
+struct pkt_id {
+	u_int32_t pi_mslot;
+        struct PageID    pi_mpage;        /* current page */
+	struct pgstate pi_ps;
+        /* seqptr's */
+        /* null-terminated site name */
+};
+
+struct pkt_preq {
+        struct PageID  pp_page;
+        u_int32_t  pp_low;
+        u_int32_t  pp_high;
+};
+
+struct pkt_prep {
+        u_int32_t  pp_n;           /* size of pageid array */
+        /* pgstate's follow */
+};
+
+static int
+wb_id(const struct pkt_id *id, u_int len)
+{
+	int i;
+	const char *cp;
+	const struct id_off *io;
+	char c;
+	int nid;
+
+	printf(" wb-id:");
+	len -= sizeof(*id);
+	if (len < 0 || (u_char *)(id + 1) > snapend)
+		return (-1);
+
+	printf(" %u/%s:%u (max %u/%s:%u) ",
+	       (u_int32_t)ntohl(id->pi_ps.slot),
+	       ipaddr_string(&id->pi_ps.page.p_sid),
+	       (u_int32_t)ntohl(id->pi_ps.page.p_uid),
+	       (u_int32_t)ntohl(id->pi_mslot),
+	       ipaddr_string(&id->pi_mpage.p_sid),
+	       (u_int32_t)ntohl(id->pi_mpage.p_uid));
+
+	nid = ntohs(id->pi_ps.nid);
+	len -= sizeof(*io) * nid;
+	io = (struct id_off *)(id + 1);
+	cp = (char *)(io + nid);
+	if ((u_char *)cp + len <= snapend) {
+		putchar('"');
+		(void)fn_print((u_char *)cp, (u_char *)cp + len);
+		putchar('"');
+	}
+
+	c = '<';
+	for (i = 0; i < nid && (u_char *)io < snapend; ++io, ++i) {
+		printf("%c%s:%u",
+		    c, ipaddr_string(&io->id), (u_int32_t)ntohl(io->off));
+		c = ',';
+	}
+	if (i >= nid) {
+		printf(">");
+		return (0);
+	}
+	return (-1);
+}
+
+static int
+wb_rreq(const struct pkt_rreq *rreq, u_int len)
+{
+	printf(" wb-rreq:");
+	if (len < sizeof(*rreq) || (u_char *)(rreq + 1) > snapend)
+		return (-1);
+
+	printf(" please repair %s %s:%u<%u:%u>",
+	       ipaddr_string(&rreq->pr_id),
+	       ipaddr_string(&rreq->pr_page.p_sid),
+	       (u_int32_t)ntohl(rreq->pr_page.p_uid),
+	       (u_int32_t)ntohl(rreq->pr_sseq),
+	       (u_int32_t)ntohl(rreq->pr_eseq));
+	return (0);
+}
+
+static int
+wb_preq(const struct pkt_preq *preq, u_int len)
+{
+	printf(" wb-preq:");
+	if (len < sizeof(*preq) || (u_char *)(preq + 1) > snapend)
+		return (-1);
+
+	printf(" need %u/%s:%u",
+	       (u_int32_t)ntohl(preq->pp_low),
+	       ipaddr_string(&preq->pp_page.p_sid),
+	       (u_int32_t)ntohl(preq->pp_page.p_uid));
+	return (0);
+}
+
+static int
+wb_prep(const struct pkt_prep *prep, u_int len)
+{
+	int n;
+	const struct pgstate *ps;
+	const u_char *ep = snapend;
+
+	printf(" wb-prep:");
+	if (len < sizeof(*prep)) {
+		return (-1);
+	}
+	n = ntohl(prep->pp_n);
+	ps = (const struct pgstate *)(prep + 1);
+	while (--n >= 0 && (u_char *)ps < ep) {
+		const struct id_off *io, *ie;
+		char c = '<';
+
+		printf(" %u/%s:%u",
+		    (u_int32_t)ntohl(ps->slot),
+		    ipaddr_string(&ps->page.p_sid),
+		    (u_int32_t)ntohl(ps->page.p_uid));
+		io = (struct id_off *)(ps + 1);
+		for (ie = io + ps->nid; io < ie && (u_char *)io < ep; ++io) {
+			printf("%c%s:%u", c, ipaddr_string(&io->id),
+			    (u_int32_t)ntohl(io->off));
+			c = ',';
+		}
+		printf(">");
+		ps = (struct pgstate *)io;
+	}
+	return ((u_char *)ps <= ep? 0 : -1);
+}
+
+
+char *dopstr[] = {
+	"dop-0!",
+	"dop-1!",
+	"RECT",
+	"LINE",
+	"ML",
+	"DEL",
+	"XFORM",
+	"ELL",
+	"CHAR",
+	"STR",
+	"NOP",
+	"PSCODE",
+	"PSCOMP",
+	"REF",
+	"SKIP",
+	"HOLE",
+};
+
+static int
+wb_dops(const struct dophdr *dh, u_int32_t ss, u_int32_t es)
+{
+	printf(" <");
+	for ( ; ss <= es; ++ss) {
+		register int t = dh->dh_type;
+
+		if (t > DT_MAXTYPE)
+			printf(" dop-%d!", t);
+		else {
+			printf(" %s", dopstr[t]);
+			if (t == DT_SKIP || t == DT_HOLE) {
+				int ts = ntohl(dh->dh_ts);
+				printf("%d", ts - ss + 1);
+				if (ss > ts || ts > es) {
+					printf("[|]");
+					if (ts < ss)
+						return (0);
+				}
+				ss = ts;
+			}
+		}
+		dh = DOP_NEXT(dh);
+		if ((u_char *)dh > snapend) {
+			printf("[|wb]");
+			break;
+		}
+	}
+	printf(" >");
+	return (0);
+}
+
+static int
+wb_rrep(const struct pkt_rrep *rrep, u_int len)
+{
+	const struct pkt_dop *dop = &rrep->pr_dop;
+
+	printf(" wb-rrep:");
+	len -= sizeof(*rrep);
+	if (len < 0 || (u_char *)(rrep + 1) > snapend)
+		return (-1);
+
+	printf(" for %s %s:%u<%u:%u>",
+	    ipaddr_string(&rrep->pr_id),
+	    ipaddr_string(&dop->pd_page.p_sid),
+	    (u_int32_t)ntohl(dop->pd_page.p_uid),
+	    (u_int32_t)ntohl(dop->pd_sseq),
+	    (u_int32_t)ntohl(dop->pd_eseq));
+
+	if (vflag)
+		return (wb_dops((const struct dophdr *)(dop + 1),
+		    ntohl(dop->pd_sseq), ntohl(dop->pd_eseq)));
+	return (0);
+}
+
+static int
+wb_drawop(const struct pkt_dop *dop, u_int len)
+{
+	printf(" wb-dop:");
+	len -= sizeof(*dop);
+	if (len < 0 || (u_char *)(dop + 1) > snapend)
+		return (-1);
+
+	printf(" %s:%u<%u:%u>",
+	    ipaddr_string(&dop->pd_page.p_sid),
+	    (u_int32_t)ntohl(dop->pd_page.p_uid),
+	    (u_int32_t)ntohl(dop->pd_sseq),
+	    (u_int32_t)ntohl(dop->pd_eseq));
+
+	if (vflag)
+		return (wb_dops((const struct dophdr *)(dop + 1),
+				ntohl(dop->pd_sseq), ntohl(dop->pd_eseq)));
+	return (0);
+}
+
+/*
+ * Print whiteboard multicast packets.
+ */
+void
+wb_print(register const void *hdr, register u_int len)
+{
+	register const struct pkt_hdr *ph;
+
+	ph = (const struct pkt_hdr *)hdr;
+	len -= sizeof(*ph);
+	if (len < 0 || (u_char *)(ph + 1) <= snapend) {
+		if (ph->ph_flags)
+			printf("*");
+		switch (ph->ph_type) {
+
+		case PT_KILL:
+			printf(" wb-kill");
+			return;
+
+		case PT_ID:
+			if (wb_id((struct pkt_id *)(ph + 1), len) >= 0)
+				return;
+			break;
+
+		case PT_RREQ:
+			if (wb_rreq((struct pkt_rreq *)(ph + 1), len) >= 0)
+				return;
+			break;
+
+		case PT_RREP:
+			if (wb_rrep((struct pkt_rrep *)(ph + 1), len) >= 0)
+				return;
+			break;
+
+		case PT_DRAWOP:
+			if (wb_drawop((struct pkt_dop *)(ph + 1), len) >= 0)
+				return;
+			break;
+
+		case PT_PREQ:
+			if (wb_preq((struct pkt_preq *)(ph + 1), len) >= 0)
+				return;
+			break;
+
+		case PT_PREP:
+			if (wb_prep((struct pkt_prep *)(ph + 1), len) >= 0)
+				return;
+			break;
+
+		default:
+			printf(" wb-%d!", ph->ph_type);
+			return;
+		}
+	}
+	printf("[|wb]");
+}
diff --git a/tcpdump.tproj/strcasecmp.c b/tcpdump.tproj/strcasecmp.c
new file mode 100644
index 0000000..edb886a
--- /dev/null
+++ b/tcpdump.tproj/strcasecmp.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * 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 California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific written prior permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)strcasecmp.c	5.5 (Berkeley) 11/24/87";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include "interface.h"
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison.  The mappings are
+ * based upon ascii character sequences.
+ */
+static u_char charmap[] = {
+	'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+	'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+	'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+	'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+	'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+	'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+	'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+	'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+	'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+	'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+	'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+	'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+	'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+	'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+	'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+	'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+	'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+	'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+	'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+	'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+	'\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+	'\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
+	'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+	'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+__private_extern__
+int
+strcasecmp(s1, s2)
+	const char *s1, *s2;
+{
+	register u_char	*cm = charmap,
+			*us1 = (u_char *)s1,
+			*us2 = (u_char *)s2;
+
+	while (cm[*us1] == cm[*us2++])
+		if (*us1++ == '\0')
+			return(0);
+	return(cm[*us1] - cm[*--us2]);
+}
+
+int
+strncasecmp(s1, s2, n)
+	const char *s1, *s2;
+	register int n;
+{
+	register u_char	*cm = charmap,
+			*us1 = (u_char *)s1,
+			*us2 = (u_char *)s2;
+
+	while (--n >= 0 && cm[*us1] == cm[*us2++])
+		if (*us1++ == '\0')
+			return(0);
+	return(n < 0 ? 0 : cm[*us1] - cm[*--us2]);
+}
diff --git a/tcpdump.tproj/tcpdump.c b/tcpdump.tproj/tcpdump.c
new file mode 100644
index 0000000..5ad2561
--- /dev/null
+++ b/tcpdump.tproj/tcpdump.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char copyright[] =
+    "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996\n\
+The Regents of the University of California.  All rights reserved.\n";
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/tcpdump.c,v 1.1.1.1 1999/05/02 03:58:35 wsanchez Exp $ (LBL)";
+#endif
+
+/*
+ * tcpdump - monitor tcp/ip traffic on an ethernet.
+ *
+ * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory.
+ * Mercilessly hacked and occasionally improved since then via the
+ * combined efforts of Van, Steve McCanne and Craig Leres of LBL.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "machdep.h"
+
+int fflag;			/* don't translate "foreign" IP address */
+int nflag;			/* leave addresses as numbers */
+int Nflag;			/* remove domains from printed host names */
+int pflag;			/* don't go promiscuous */
+int qflag;			/* quick (shorter) output */
+int tflag = 1;			/* print packet arrival time */
+int eflag;			/* print ethernet header */
+int vflag;			/* verbose */
+int xflag;			/* print packet in hex */
+int Oflag = 1;			/* run filter code optimizer */
+int Sflag;			/* print raw TCP sequence numbers */
+int packettype;
+
+int dflag;			/* print filter code */
+
+char *program_name;
+
+int32_t thiszone;		/* seconds offset from gmt to local time */
+
+/* Externs */
+extern void bpf_dump(struct bpf_program *, int);
+
+/* Forwards */
+RETSIGTYPE cleanup(int);
+extern __dead void usage(void) __attribute__((volatile));
+
+/* Length of saved portion of packet. */
+int snaplen = DEFAULT_SNAPLEN;
+
+struct printer {
+	pcap_handler f;
+	int type;
+};
+
+/* XXX needed if using old bpf.h */
+#ifndef DLT_ATM_RFC1483
+#define DLT_ATM_RFC1483 11
+#endif
+
+static struct printer printers[] = {
+	{ ether_if_print,	DLT_EN10MB },
+	{ ether_if_print,	DLT_IEEE802 },
+	{ sl_if_print,		DLT_SLIP },
+	{ ppp_if_print,		DLT_PPP },
+	{ fddi_if_print,	DLT_FDDI },
+	{ null_if_print,	DLT_NULL },
+	{ atm_if_print,		DLT_ATM_RFC1483 },
+	{ NULL,			0 },
+};
+
+static pcap_handler
+lookup_printer(int type)
+{
+	struct printer *p;
+
+	for (p = printers; p->f; ++p)
+		if (type == p->type)
+			return p->f;
+
+	error("unknown data link type 0x%x", type);
+	/* NOTREACHED */
+}
+
+static pcap_t *pd;
+
+extern int optind;
+extern int opterr;
+extern char *optarg;
+
+int
+main(int argc, char **argv)
+{
+	register int cnt, op, i;
+	bpf_u_int32 localnet, netmask;
+	register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
+	pcap_handler printer;
+	struct bpf_program fcode;
+	u_char *pcap_userdata;
+	char ebuf[PCAP_ERRBUF_SIZE];
+
+	cnt = -1;
+	device = NULL;
+	infile = NULL;
+	RFileName = NULL;
+	WFileName = NULL;
+	if ((cp = strrchr(argv[0], '/')) != NULL)
+		program_name = cp + 1;
+	else
+		program_name = argv[0];
+
+	if (abort_on_misalignment(ebuf) < 0)
+		error("%s", ebuf);
+
+	opterr = 0;
+	while ((op = getopt(argc, argv, "c:defF:i:lnNOpqr:s:StT:vw:xY")) != -1)
+		switch (op) {
+		case 'c':
+			cnt = atoi(optarg);
+			if (cnt <= 0)
+				error("invalid packet count %s", optarg);
+			break;
+
+		case 'd':
+			++dflag;
+			break;
+
+		case 'e':
+			++eflag;
+			break;
+
+		case 'f':
+			++fflag;
+			break;
+
+		case 'F':
+			infile = optarg;
+			break;
+
+		case 'i':
+			device = optarg;
+			break;
+
+		case 'l':
+#ifdef HAVE_SETLINEBUF
+			setlinebuf(stdout);
+#else
+			setvbuf(stdout, NULL, _IOLBF, 0);
+#endif
+			break;
+
+		case 'n':
+			++nflag;
+			break;
+
+		case 'N':
+			++Nflag;
+			break;
+
+		case 'O':
+			Oflag = 0;
+			break;
+
+		case 'p':
+			++pflag;
+			break;
+
+		case 'q':
+			++qflag;
+			break;
+
+		case 'r':
+			RFileName = optarg;
+			break;
+
+		case 's':
+			snaplen = atoi(optarg);
+			if (snaplen <= 0)
+				error("invalid snaplen %s", optarg);
+			break;
+
+		case 'S':
+			++Sflag;
+			break;
+
+		case 't':
+			--tflag;
+			break;
+
+		case 'T':
+			if (strcasecmp(optarg, "vat") == 0)
+				packettype = PT_VAT;
+			else if (strcasecmp(optarg, "wb") == 0)
+				packettype = PT_WB;
+			else if (strcasecmp(optarg, "rpc") == 0)
+				packettype = PT_RPC;
+			else if (strcasecmp(optarg, "rtp") == 0)
+				packettype = PT_RTP;
+			else if (strcasecmp(optarg, "rtcp") == 0)
+				packettype = PT_RTCP;
+			else
+				error("unknown packet type `%s'", optarg);
+			break;
+
+		case 'v':
+			++vflag;
+			break;
+
+		case 'w':
+			WFileName = optarg;
+			break;
+#ifdef YYDEBUG
+		case 'Y':
+			{
+			/* Undocumented flag */
+			extern int yydebug;
+			yydebug = 1;
+			}
+			break;
+#endif
+		case 'x':
+			++xflag;
+			break;
+
+		default:
+			usage();
+			/* NOTREACHED */
+		}
+
+	if (tflag > 0)
+		thiszone = gmt2local();
+
+	if (RFileName != NULL) {
+		/*
+		 * We don't need network access, so set it back to the user id.
+		 * Also, this prevents the user from reading anyone's
+		 * trace file.
+		 */
+		setuid(getuid());
+
+		pd = pcap_open_offline(RFileName, ebuf);
+		if (pd == NULL)
+			error("%s", ebuf);
+		localnet = 0;
+		netmask = 0;
+		if (fflag != 0)
+			error("-f and -r options are incompatible");
+	} else {
+		if (device == NULL) {
+			device = pcap_lookupdev(ebuf);
+			if (device == NULL)
+				error("%s", ebuf);
+		}
+		pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf);
+		if (pd == NULL)
+			error("%s", ebuf);
+		i = pcap_snapshot(pd);
+		if (snaplen < i) {
+			warning("snaplen raised from %d to %d", snaplen, i);
+			snaplen = i;
+		}
+		if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0)
+			error("%s", ebuf);
+		/*
+		 * Let user own process after socket has been opened.
+		 */
+		setuid(getuid());
+	}
+	if (infile)
+		cmdbuf = read_infile(infile);
+	else
+		cmdbuf = copy_argv(&argv[optind]);
+
+	if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
+		error("%s", pcap_geterr(pd));
+	if (dflag) {
+		bpf_dump(&fcode, dflag);
+		exit(0);
+	}
+	init_addrtoname(fflag, localnet, netmask);
+
+	(void)signal(SIGTERM, cleanup);
+	(void)signal(SIGINT, cleanup);
+	(void)signal(SIGHUP, cleanup);
+
+	if (pcap_setfilter(pd, &fcode) < 0)
+		error("%s", pcap_geterr(pd));
+	if (WFileName) {
+		pcap_dumper_t *p = pcap_dump_open(pd, WFileName);
+		if (p == NULL)
+			error("%s", pcap_geterr(pd));
+		printer = pcap_dump;
+		pcap_userdata = (u_char *)p;
+	} else {
+		printer = lookup_printer(pcap_datalink(pd));
+		pcap_userdata = 0;
+	}
+	if (RFileName == NULL) {
+		(void)fprintf(stderr, "%s: listening on %s\n",
+		    program_name, device);
+		(void)fflush(stderr);
+	}
+	if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) {
+		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
+		    program_name, pcap_geterr(pd));
+		exit(1);
+	}
+	pcap_close(pd);
+	exit(0);
+}
+
+/* make a clean exit on interrupts */
+RETSIGTYPE
+cleanup(int signo)
+{
+	struct pcap_stat stat;
+
+	/* Can't print the summary if reading from a savefile */
+	if (pd != NULL && pcap_file(pd) == NULL) {
+		(void)fflush(stdout);
+		putc('\n', stderr);
+		if (pcap_stats(pd, &stat) < 0)
+			(void)fprintf(stderr, "pcap_stats: %s\n",
+			    pcap_geterr(pd));
+		else {
+			(void)fprintf(stderr, "%d packets received by filter\n",
+			    stat.ps_recv);
+			(void)fprintf(stderr, "%d packets dropped by kernel\n",
+			    stat.ps_drop);
+		}
+	}
+	exit(0);
+}
+
+/* Like default_print() but data need not be aligned */
+void
+default_print_unaligned(register const u_char *cp, register u_int length)
+{
+	register u_int i, s;
+	register int nshorts;
+
+	nshorts = (u_int) length / sizeof(u_short);
+	i = 0;
+	while (--nshorts >= 0) {
+		if ((i++ % 8) == 0)
+			(void)printf("\n\t\t\t");
+		s = *cp++;
+		(void)printf(" %02x%02x", s, *cp++);
+	}
+	if (length & 1) {
+		if ((i % 8) == 0)
+			(void)printf("\n\t\t\t");
+		(void)printf(" %02x", *cp);
+	}
+}
+
+void
+default_print(register const u_char *bp, register u_int length)
+{
+	register const u_short *sp;
+	register u_int i;
+	register int nshorts;
+
+	if ((long)bp & 1) {
+		default_print_unaligned(bp, length);
+		return;
+	}
+	sp = (u_short *)bp;
+	nshorts = (u_int) length / sizeof(u_short);
+	i = 0;
+	while (--nshorts >= 0) {
+		if ((i++ % 8) == 0)
+			(void)printf("\n\t\t\t");
+		(void)printf(" %04x", ntohs(*sp++));
+	}
+	if (length & 1) {
+		if ((i % 8) == 0)
+			(void)printf("\n\t\t\t");
+		(void)printf(" %02x", *(u_char *)sp);
+	}
+}
+
+__dead void
+usage(void)
+{
+	extern char version[];
+
+	(void)fprintf(stderr, "Version %s\n", version);
+	(void)fprintf(stderr,
+"Usage: tcpdump [-deflnNOpqStvx] [-c count] [ -F file ]\n");
+	(void)fprintf(stderr,
+"\t\t[ -i interface ] [ -r file ] [ -s snaplen ]\n");
+	(void)fprintf(stderr,
+"\t\t[ -T type ] [ -w file ] [ expression ]\n");
+	exit(-1);
+}
diff --git a/tcpdump.tproj/util.c b/tcpdump.tproj/util.c
new file mode 100644
index 0000000..6df0352
--- /dev/null
+++ b/tcpdump.tproj/util.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/util.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <pcap.h>
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+#include <unistd.h>
+
+#include "interface.h"
+
+/*
+ * Print out a filename (or other ascii string).
+ * If ep is NULL, assume no truncation check is needed.
+ * Return true if truncated.
+ */
+int
+fn_print(register const u_char *s, register const u_char *ep)
+{
+	register int ret;
+	register u_char c;
+
+	ret = 1;			/* assume truncated */
+	while (ep == NULL || s < ep) {
+		c = *s++;
+		if (c == '\0') {
+			ret = 0;
+			break;
+		}
+		if (!isascii(c)) {
+			c = toascii(c);
+			putchar('M');
+			putchar('-');
+		}
+		if (!isprint(c)) {
+			c ^= 0x40;	/* DEL to ?, others to alpha */
+			putchar('^');
+		}
+		putchar(c);
+	}
+	return(ret);
+}
+
+/*
+ * Print out a counted filename (or other ascii string).
+ * If ep is NULL, assume no truncation check is needed.
+ * Return true if truncated.
+ */
+int
+fn_printn(register const u_char *s, register u_int n,
+	  register const u_char *ep)
+{
+	register int ret;
+	register u_char c;
+
+	ret = 1;			/* assume truncated */
+	while (ep == NULL || s < ep) {
+		if (n-- <= 0) {
+			ret = 0;
+			break;
+		}
+		c = *s++;
+		if (!isascii(c)) {
+			c = toascii(c);
+			putchar('M');
+			putchar('-');
+		}
+		if (!isprint(c)) {
+			c ^= 0x40;	/* DEL to ?, others to alpha */
+			putchar('^');
+		}
+		putchar(c);
+	}
+	return(ret);
+}
+
+/*
+ * Print the timestamp
+ */
+void
+ts_print(register const struct timeval *tvp)
+{
+	register int s;
+
+	if (tflag > 0) {
+		/* Default */
+		s = (tvp->tv_sec + thiszone) % 86400;
+		(void)printf("%02d:%02d:%02d.%06u ",
+		    s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec);
+	} else if (tflag < 0) {
+		/* Unix timeval style */
+		(void)printf("%u.%06u ",
+		    (u_int32_t)tvp->tv_sec, (u_int32_t)tvp->tv_usec);
+	}
+}
+
+/*
+ * Convert a token value to a string; use "fmt" if not found.
+ */
+const char *
+tok2str(register const struct tok *lp, register const char *fmt,
+	register int v)
+{
+	static char buf[128];
+
+	while (lp->s != NULL) {
+		if (lp->v == v)
+			return (lp->s);
+		++lp;
+	}
+	if (fmt == NULL)
+		fmt = "#%d";
+	(void)sprintf(buf, fmt, v);
+	return (buf);
+}
+
+
+/* VARARGS */
+__dead void
+#if __STDC__
+error(const char *fmt, ...)
+#else
+error(fmt, va_alist)
+	const char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+	(void)fprintf(stderr, "%s: ", program_name);
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	(void)vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	if (*fmt) {
+		fmt += strlen(fmt);
+		if (fmt[-1] != '\n')
+			(void)fputc('\n', stderr);
+	}
+	exit(1);
+	/* NOTREACHED */
+}
+
+/* VARARGS */
+void
+#if __STDC__
+warning(const char *fmt, ...)
+#else
+warning(fmt, va_alist)
+	const char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+	(void)fprintf(stderr, "%s: WARNING: ", program_name);
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	(void)vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	if (*fmt) {
+		fmt += strlen(fmt);
+		if (fmt[-1] != '\n')
+			(void)fputc('\n', stderr);
+	}
+}
+
+/*
+ * Copy arg vector into a new buffer, concatenating arguments with spaces.
+ */
+char *
+copy_argv(register char **argv)
+{
+	register char **p;
+	register u_int len = 0;
+	char *buf;
+	char *src, *dst;
+
+	p = argv;
+	if (*p == 0)
+		return 0;
+
+	while (*p)
+		len += strlen(*p++) + 1;
+
+	buf = (char *)malloc(len);
+	if (buf == NULL)
+		error("copy_argv: malloc");
+
+	p = argv;
+	dst = buf;
+	while ((src = *p++) != NULL) {
+		while ((*dst++ = *src++) != '\0')
+			;
+		dst[-1] = ' ';
+	}
+	dst[-1] = '\0';
+
+	return buf;
+}
+
+/* A replacement for strdup() that cuts down on malloc() overhead */
+char *
+savestr(register const char *str)
+{
+	register u_int size;
+	register char *p;
+	static char *strptr = NULL;
+	static u_int strsize = 0;
+
+	size = strlen(str) + 1;
+	if (size > strsize) {
+		strsize = 1024;
+		if (strsize < size)
+			strsize = size;
+		strptr = (char *)malloc(strsize);
+		if (strptr == NULL)
+			error("savestr: malloc");
+	}
+	(void)strcpy(strptr, str);
+	p = strptr;
+	strptr += size;
+	strsize -= size;
+	return (p);
+}
+
+char *
+read_infile(char *fname)
+{
+	register int fd, cc;
+	register char *cp;
+	struct stat buf;
+
+	fd = open(fname, O_RDONLY);
+	if (fd < 0)
+		error("can't open %s: %s", fname, pcap_strerror(errno));
+
+	if (fstat(fd, &buf) < 0)
+		error("can't stat %s: %s", fname, pcap_strerror(errno));
+
+	cp = malloc((u_int)buf.st_size + 1);
+	cc = read(fd, cp, (int)buf.st_size);
+	if (cc < 0)
+		error("read %s: %s", fname, pcap_strerror(errno));
+	if (cc != buf.st_size)
+		error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
+	cp[(int)buf.st_size] = '\0';
+
+	return (cp);
+}
+
+/*
+ * Returns the difference between gmt and local time in seconds.
+ * Use gmtime() and localtime() to keep things simple.
+ */
+int32_t
+gmt2local(void)
+{
+	register int dt, dir;
+	register struct tm *gmt, *loc;
+	time_t t;
+	struct tm sgmt;
+
+	t = time(NULL);
+	gmt = &sgmt;
+	*gmt = *gmtime(&t);
+	loc = localtime(&t);
+	dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 +
+	    (loc->tm_min - gmt->tm_min) * 60;
+
+	/*
+	 * If the year or julian day is different, we span 00:00 GMT
+	 * and must add or subtract a day. Check the year first to
+	 * avoid problems when the julian day wraps.
+	 */
+	dir = loc->tm_year - gmt->tm_year;
+	if (dir == 0)
+		dir = loc->tm_yday - gmt->tm_yday;
+	dt += dir * 24 * 60 * 60;
+
+	return (dt);
+}
diff --git a/tcpdump.tproj/version.c b/tcpdump.tproj/version.c
new file mode 100644
index 0000000..2ee34ff
--- /dev/null
+++ b/tcpdump.tproj/version.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: version.c,v 1.4 1996/07/13 11:01:35 mickey Exp $	*/
+/*	$NetBSD: version.c,v 1.3 1996/05/20 00:41:20 fvdl Exp $	*/
+
+char version[] = "3.2.0";
diff --git a/tcpdump.tproj/vfprintf.c b/tcpdump.tproj/vfprintf.c
new file mode 100644
index 0000000..3d5e80c
--- /dev/null
+++ b/tcpdump.tproj/vfprintf.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/vfprintf.c,v 1.1.1.1 1999/05/02 03:58:35 wsanchez Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "interface.h"
+
+#if 0
+
+/*
+ * Stock 4.3 doesn't have vfprintf.
+ * This routine is due to Chris Torek.
+ */
+vfprintf(f, fmt, args)
+	FILE *f;
+	char *fmt;
+	va_list args;
+{
+	int ret;
+
+	if ((f->_flag & _IOWRT) == 0) {
+		if (f->_flag & _IORW)
+			f->_flag |= _IOWRT;
+		else
+			return EOF;
+	}
+	ret = _doprnt(fmt, args, f);
+	return ferror(f) ? EOF : ret;
+}
+#endif /* 0 */
\ No newline at end of file
diff --git a/telnet.tproj/Makefile b/telnet.tproj/Makefile
new file mode 100644
index 0000000..0a096f6
--- /dev/null
+++ b/telnet.tproj/Makefile
@@ -0,0 +1,57 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = telnet
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = externs.h fdset.h general.h krb4-proto.h ring.h types.h\
+         defines.h
+
+CFILES = authenc.c commands.c main.c network.c ring.c sys_bsd.c\
+         telnet.c terminal.c tn3270.c utilities.c
+
+OTHERSRCS = Makefile.preamble Makefile README telnet.1 Makefile.dist
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DENV_HACK # -DAUTHENTICATION -DENCRYPTION -DKRB4
+WINDOWS_PB_CFLAGS = -DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DENV_HACK # -DAUTHENTICATION -DENCRYPTION -DKRB4
+PDO_UNIX_PB_CFLAGS = -DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DENV_HACK # -DAUTHENTICATION -DENCRYPTION -DKRB4
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/telnet.tproj/Makefile.dist b/telnet.tproj/Makefile.dist
new file mode 100644
index 0000000..2e38a28
--- /dev/null
+++ b/telnet.tproj/Makefile.dist
@@ -0,0 +1,73 @@
+#
+# Copyright (c) 1990 The Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+#    must display the following acknowledgement:
+#	This product includes software developed by the University of
+#	California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+#    may be used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#	@(#)Makefile	8.1 (Berkeley) 6/6/93
+#
+
+PROG=	telnet
+
+CFLAGS+=-DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DAUTHENTICATION -DENCRYPTION
+CFLAGS+=-DENV_HACK
+CFLAGS+=-I${.CURDIR}/../../lib
+
+CFLAGS+= -DKRB4
+
+LDADD=	-ltermcap -ltelnet
+LDADD+=	-lkrb -ldes
+DPADD=	${LIBTERMCAP}
+
+SRCS=	authenc.c commands.c main.c network.c ring.c sys_bsd.c telnet.c \
+	terminal.c tn3270.c utilities.c
+
+# These are the sources that have encryption stuff in them.
+CRYPT_SRC= authenc.c commands.c externs.h main.c network.c
+CRYPT_SRC+= ring.c ring.h telnet.c terminal.c utilities.c Makefile
+NOCRYPT_DIR=${.CURDIR}/Nocrypt
+
+.include <bsd.prog.mk>
+
+nocrypt:
+#ifdef	ENCRYPTION
+	@for i in ${CRYPT_SRC}; do \
+	    if [ ! -d ${NOCRYPT_DIR} ]; then \
+		echo Creating subdirectory ${NOCRYPT_DIR}; \
+		mkdir ${NOCRYPT_DIR}; \
+	    fi; \
+	    echo ${NOCRYPT_DIR}/$$i; \
+	    unifdef -UENCRYPTION ${.CURDIR}/$$i | \
+		sed "s/ || defined(ENCRYPTION)//" > ${NOCRYPT_DIR}/$$i; \
+	done
+
+placeholder:
+#else	/* ENCRYPTION */
+	@echo "Encryption code already removed."
+#endif	/* ENCRYPTION */
diff --git a/telnet.tproj/Makefile.preamble b/telnet.tproj/Makefile.preamble
new file mode 100644
index 0000000..0f58055
--- /dev/null
+++ b/telnet.tproj/Makefile.preamble
@@ -0,0 +1,4 @@
+CLEAN_ALL_SUBPROJECTS = YES
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+OTHER_LIBS = -ltelnet
+-include ../Makefile.include
diff --git a/telnet.tproj/PB.project b/telnet.tproj/PB.project
new file mode 100644
index 0000000..23bd9c5
--- /dev/null
+++ b/telnet.tproj/PB.project
@@ -0,0 +1,47 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (externs.h, fdset.h, general.h, "krb4-proto.h", ring.h, types.h, defines.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (
+            authenc.c, 
+            commands.c, 
+            main.c, 
+            network.c, 
+            ring.c, 
+            sys_bsd.c, 
+            telnet.c, 
+            terminal.c, 
+            tn3270.c, 
+            utilities.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, README, telnet.1, Makefile.dist); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DENV_HACK # -DAUTHENTICATION -DENCRYPTION -DKRB4"; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = "-DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DENV_HACK # -DAUTHENTICATION -DENCRYPTION -DKRB4"; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = telnet; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = "-DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DENV_HACK # -DAUTHENTICATION -DENCRYPTION -DKRB4"; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/telnet.tproj/README b/telnet.tproj/README
new file mode 100644
index 0000000..37b588f
--- /dev/null
+++ b/telnet.tproj/README
@@ -0,0 +1,743 @@
+
+This is a distribution of both client and server telnet.  These programs
+have been compiled on:
+			telnet	telnetd
+	4.4 BSD-Lite	  x	  x
+	4.3 BSD Reno	  X	  X
+	UNICOS 9.1	  X	  X
+	UNICOS 9.0	  X	  X
+	UNICOS 8.0	  X	  X
+	BSDI 2.0	  X	  X
+	Solaris 2.4       x       x (no linemode in server)
+	SunOs 4.1.4	  X	  X (no linemode in server)
+	Ultrix 4.3	  X	  X (no linemode in server)
+	Ultrix 4.1	  X	  X (no linemode in server)
+
+In addition, previous versions have been compiled on the following
+machines, but were not available for testing this version.
+			telnet	telnetd
+	Next1.0		  X	  X
+	UNICOS 8.3	  X	  X
+	UNICOS 7.C	  X	  X
+	UNICOS 7.0	  X	  X
+	SunOs 4.0.3c	  X	  X (no linemode in server)
+	4.3 BSD		  X  	  X (no linemode in server)
+	DYNIX V3.0.12	  X	  X (no linemode in server)
+	Ultrix 3.1	  X	  X (no linemode in server)
+	Ultrix 4.0	  X	  X (no linemode in server)
+	SunOs 3.5	  X	  X (no linemode in server)
+	SunOs 4.1.3	  X	  X (no linemode in server)
+	Solaris 2.2       x       x (no linemode in server)
+	Solaris 2.3       x       x (no linemode in server)
+	BSDI 1.0	  X	  X
+	BSDI 1.1	  X	  X
+	DYNIX V3.0.17.9	  X	  X (no linemode in server)
+	HP-UX 8.0	  x       x (no linemode in server)
+
+This code should work, but there are no guarantees.
+
+May 30, 1995
+
+This release represents what is on the 4.4BSD-Lite2 release, which
+should be the final BSD release.  I will continue to support of
+telnet, The code (without encryption) is available via anonymous ftp
+from ftp.cray.com, in src/telnet/telnet.YY.MM.DD.NE.tar.Z, where
+YY.MM.DD is replaced with the year, month and day of the release.
+If you can't find it at one of these places, at some point in the
+near future information about the latest releases should be available
+from ftp.borman.com.
+
+In addition, the version with the encryption code is available via
+ftp from net-dist.mit.edu, in the directory /pub/telnet.  There
+is a README file there that gives further information on how
+to get the distribution.
+
+Questions, comments, bug reports and bug fixes can be sent to
+one of these addresses:
+		dab@borman.com
+		dab@cray.com
+		dab@bsdi.com
+
+This release is mainly bug fixes and code cleanup.
+
+	Replace all calls to bcopy()/bzero() with calls to
+	memmove()/memset() and all calls to index()/rindex()
+	with calls to strchr()/strrchr().
+
+	Add some missing diagnostics for option tracing
+	to telnetd.
+
+	Add support for BSDI 2.0 and Solaris 2.4.
+
+	Add support for UNICOS 8.0
+
+	Get rid of expanded tabs and trailing white spaces.
+
+	From Paul Vixie:
+		Fix for telnet going into an endless spin
+		when the session dies abnormally.
+
+	From Jef Poskanzer:
+		Changes to allow telnet to compile
+		under SunOS 3.5.
+
+	From Philip Guenther:
+		makeutx() doesn't expand utmpx,
+		use pututxline() instead.
+
+	From Chris Torek:
+		Add a sleep(1) before execing login
+		to avoid race condition that can eat
+		up the login prompt.
+		Use terminal speed directly if it is
+		not an encoded value.
+
+	From Steve Parker:
+		Fix to realloc() call.  Fix for execing
+		login on solaris with no user name.
+
+January 19, 1994
+
+This is a list of some of the changes since the last tar release
+of telnet/telnetd.  There are probably other changes that aren't
+listed here, but this should hit a lot of the main ones.
+
+   General:
+	Changed #define for AUTHENTICATE to AUTHENTICATION
+	Changed #define for ENCRYPT to ENCRYPTION
+	Changed #define for DES_ENCRYPT to DES_ENCRYPTION
+
+	Added support for SPX authentication: -DSPX
+
+	Added support for Kerberos Version 5 authentication: -DKRB5
+
+	Added support for ANSI C function prototypes
+
+	Added support for the NEW-ENVIRON option (RFC-1572)
+	including support for USERVAR.
+
+	Made support for the old Environment Option (RFC-1408)
+	conditional on -DOLD_ENVIRON
+
+	Added #define ENV_HACK - support for RFC 1571
+
+	The encryption code is removed from the public distributions.
+	Domestic 4.4 BSD distributions contain the encryption code.
+
+	ENV_HACK: Code to deal with systems that only implement
+		the old ENVIRON option, and have reversed definitions
+		of ENV_VAR and ENV_VAL.  Also fixes ENV processing in
+		client to handle things besides just the default set...
+
+	NO_BSD_SETJMP: UNICOS configuration for
+		UNICOS 6.1/6.0/5.1/5.0 systems.
+
+	STREAMSPTY: Use /dev/ptmx to get a clean pty.  This
+		is for SVr4 derivatives (Like Solaris)
+
+	UTMPX: For systems that have /etc/utmpx. This is for
+		SVr4 derivatives (Like Solaris)
+
+	Definitions for BSDI 1.0
+
+	Definitions for 4.3 Reno and 4.4 BSD.
+
+	Definitions for UNICOS 8.0 and UNICOS 7.C
+
+	Definitions for Solaris 2.0
+
+	Definitions for HP-UX 8.0
+
+	Latest Copyright notices from Berkeley.
+
+	FLOW-CONTROL: support for RFC-XXXx
+
+
+   Client Specific:
+
+	Fix the "send" command to not send garbage...
+
+	Fix status message for "skiprc"
+
+	Make sure to send NAWS after telnet has been suspended
+	or an external command has been run, if the window size
+	has changed.
+
+	sysV88 support.
+
+   Server Specific:
+
+	Support flowcontrol option in non-linemode servers.
+
+	-k Server supports Kludge Linemode, but will default to
+	   either single character mode or real Linemode support.
+	   The user will have to explicitly ask to switch into
+	   kludge linemode. ("stty extproc", or escape back to
+	   to telnet and say "mode line".)
+
+	-u Specify the length of the hostname field in the utmp
+	   file.  Hostname longer than this length will be put
+	   into the utmp file in dotted decimal notation, rather
+	   than putting in a truncated hostname.
+	
+	-U Registered hosts only.  If a reverse hostname lookup
+	   fails, the connection will be refused.
+
+	-f/-F
+	   Allows forwarding of credentials for KRB5.
+
+Februrary 22, 1991:
+
+    Features:
+
+	This version of telnet/telnetd has support for both
+	the AUTHENTICATION and ENCRYPTION options.  The
+	AUTHENTICATION option is fairly well defined, and
+	an option number has been assigned to it.  The
+	ENCRYPTION option is still in a state of flux; an
+	option number has been assigned to, but it is still
+	subject to change.  The code is provided in this release
+	for experimental and testing purposes.
+
+	The telnet "send" command can now be used to send
+	do/dont/will/wont commands, with any telnet option
+	name.  The rules for when do/dont/will/wont are sent
+	are still followed, so just because the user requests
+	that one of these be sent doesn't mean that it will
+	be sent...
+
+	The telnet "getstatus" command no longer requires
+	that option printing be enabled to see the response
+	to the "DO STATUS" command.
+
+	A -n flag has been added to telnetd to disable
+	keepalives.
+
+	A new telnet command, "auth" has been added (if
+	AUTHENTICATE is defined).  It has four sub-commands,
+	"status", "disable", "enable" and "help".
+
+	A new telnet command, "encrypt" has been added (if
+	ENCRYPT is defined).  It has many sub-commands:
+	"enable", "type", "start", "stop", "input",
+	"-input", "output", "-output", "status", and "help".
+
+	The LOGOUT option is now supported by both telnet
+	and telnetd, a new command, "logout", was added
+	to support this.
+
+	Several new toggle options were added:
+	    "autoencrypt", "autodecrypt", "autologin", "authdebug",
+	    "encdebug", "skiprc", "verbose_encrypt"
+
+	An "rlogin" interface has been added.  If the program
+	is named "rlogin", or the "-r" flag is given, then
+	an rlogin type of interface will be used.
+		~.	Terminates the session
+		~<susp> Suspend the session
+		~^]	Escape to telnet command mode
+		~~	Pass through the ~.
+	    BUG: If you type the rlogin escape character
+		 in the middle of a line while in rlogin
+		 mode, you cannot erase it or any characters
+		 before it.  Hopefully this can be fixed
+		 in a future release...
+
+    General changes:
+
+	A "libtelnet.a" has now been created.  This libraray
+	contains code that is common to both telnet and
+	telnetd.  This is also where library routines that
+	are needed, but are not in the standard C library,
+	are placed.
+
+	The makefiles have been re-done.  All of the site
+	specific configuration information has now been put
+	into a single "Config.generic" file, in the top level
+	directory.  Changing this one file will take care of
+	all three subdirectories.  Also, to add a new/local
+	definition, a "Config.local" file may be created
+	at the top level; if that file exists, the subdirectories
+	will use that file instead of "Config.generic".
+
+	Many 1-2 line functions in commands.c have been
+	removed, and just inserted in-line, or replaced
+	with a macro.
+
+    Bug Fixes:
+
+	The non-termio code in both telnet and telnetd was
+	setting/clearing CTLECH in the sg_flags word.  This
+	was incorrect, and has been changed to set/clear the
+	LCTLECH bit in the local mode word.
+
+	The SRCRT #define has been removed.  If IP_OPTIONS
+	and IPPROTO_IP are defined on the system, then the
+	source route code is automatically enabled.
+
+	The NO_GETTYTAB #define has been removed; there
+	is a compatability routine that can be built into
+	libtelnet to achive the same results.
+
+	The server, telnetd, has been switched to use getopt()
+	for parsing the argument list.
+
+	The code for getting the input/output speeds via
+	cfgetispeed()/cfgetospeed() was still not quite
+	right in telnet.  Posix says if the ispeed is 0,
+	then it is really equal to the ospeed.
+
+	The suboption processing code in telnet now has
+	explicit checks to make sure that we received
+	the entire suboption (telnetd was already doing this).
+
+	The telnet code for processing the terminal type
+	could cause a core dump if an existing connection
+	was closed, and a new connection opened without
+	exiting telnet.
+
+	Telnetd was doing a TCSADRAIN when setting the new
+	terminal settings;  This is not good, because it means
+	that the tcsetattr() will hang waiting for output to
+	drain, and telnetd is the only one that will drain
+	the output...  The fix is to use TCSANOW which does
+	not wait.
+
+	Telnetd was improperly setting/clearing the ISTRIP
+	flag in the c_lflag field, it should be using the
+	c_iflag field. 
+
+	When the child process of telnetd was opening the
+	slave side of the pty, it was re-setting the EXTPROC
+	bit too early, and some of the other initialization
+	code was wiping it out.  This would cause telnetd
+	to go out of linemode and into single character mode.
+
+	One instance of leaving linemode in telnetd forgot
+	to send a WILL ECHO to the client, the net result
+	would be that the user would see double character
+	echo.
+
+	If the MODE was being changed several times very
+	quickly, telnetd could get out of sync with the
+	state changes and the returning acks; and wind up
+	being left in the wrong state.
+
+September 14, 1990:
+
+	Switch the client to use getopt() for parsing the
+	argument list.  The 4.3Reno getopt.c is included for
+	systems that don't have getopt().
+
+	Use the posix _POSIX_VDISABLE value for what value
+	to use when disabling special characters.  If this
+	is undefined, it defaults to 0x3ff.
+
+	For non-termio systems, TIOCSETP was being used to
+	change the state of the terminal.  This causes the
+	input queue to be flushed, which we don't want.  This
+	is now changed to TIOCSETN.
+
+	Take out the "#ifdef notdef" around the code in the
+	server that generates a "sync" when the pty oputput
+	is flushed.  The potential problem is that some older
+	telnet clients may go into an infinate loop when they
+	receive a "sync", if so, the server can be compiled
+	with "NO_URGENT" defined.
+
+	Fix the client where it was setting/clearing the OPOST
+	bit in the c_lflag field, not the c_oflag field.
+
+	Fix the client where it was setting/clearing the ISTRIP
+	bit in the c_lflag field, not the c_iflag field.  (On
+	4.3Reno, this is the ECHOPRT bit in the c_lflag field.)
+	The client also had its interpretation of WILL BINARY
+	and DO BINARY reversed.
+
+	Fix a bug in client that would cause a core dump when
+	attempting to remove the last environment variable.
+
+	In the client, there were a few places were switch()
+	was being passed a character, and if it was a negative
+	value, it could get sign extended, and not match
+	the 8 bit case statements.  The fix is to and the
+	switch value with 0xff.
+
+	Add a couple more printoption() calls in the client, I
+	don't think there are any more places were a telnet
+	command can be received and not printed out when
+	"options" is on.
+
+	A new flag has been added to the client, "-a".  Currently,
+	this just causes the USER name to be sent across, in
+	the future this may be used to signify that automatic
+	authentication is requested.
+
+	The USER variable is now only sent by the client if
+	the "-a" or "-l user" options are explicity used, or
+	if the user explicitly asks for the "USER" environment
+	variable to be exported.  In the server, if it receives
+	the "USER" environment variable, it won't print out the
+	banner message, so that only "Password:" will be printed.
+	This makes the symantics more like rlogin, and should be
+	more familiar to the user.  (People are not used to
+	getting a banner message, and then getting just a
+	"Password:" prompt.)
+
+	Re-vamp the code for starting up the child login
+	process.  The code was getting ugly, and it was
+	hard to tell what was really going on.  What we
+	do now is after the fork(), in the child:
+		1) make sure we have no controlling tty
+		2) open and initialize the tty
+		3) do a setsid()/setpgrp()
+		4) makes the tty our controlling tty.
+	On some systems, #2 makes the tty our controlling
+	tty, and #4 is a no-op.  The parent process does
+	a gets rid of any controlling tty after the child
+	is fork()ed.
+
+	Use the strdup() library routine in telnet, instead
+	of the local savestr() routine.  If you don't have
+	strdup(), you need to define NO_STRDUP.
+
+	Add support for ^T (SIGINFO/VSTATUS), found in the
+	4.3Reno distribution.  This maps to the AYT character.
+	You need a 4-line bugfix in the kernel to get this
+	to work properly:
+
+	> *** tty_pty.c.ORG	Tue Sep 11 09:41:53 1990
+	> --- tty_pty.c	Tue Sep 11 17:48:03 1990
+	> ***************
+	> *** 609,613 ****
+	> 			if ((tp->t_lflag&NOFLSH) == 0)
+	> 				ttyflush(tp, FREAD|FWRITE);
+	> ! 			pgsignal(tp->t_pgrp, *(unsigned int *)data);
+	> 			return(0);
+	> 		}
+	> --- 609,616 ----
+	> 			if ((tp->t_lflag&NOFLSH) == 0)
+	> 				ttyflush(tp, FREAD|FWRITE);
+	> ! 			pgsignal(tp->t_pgrp, *(unsigned int *)data, 1);
+	> ! 			if ((*(unsigned int *)data == SIGINFO) &&
+	> ! 			    ((tp->t_lflag&NOKERNINFO) == 0))
+	> ! 				ttyinfo(tp);
+	> 			return(0);
+	> 		}
+
+	The client is now smarter when setting the telnet escape
+	character; it only sets it to one of VEOL and VEOL2 if
+	one of them is undefined, and the other one is not already
+	defined to the telnet escape character.
+
+	Handle TERMIOS systems that have seperate input and output
+	line speed settings imbedded in the flags.
+
+	Many other minor bug fixes.
+
+June 20, 1990:
+	Re-organize makefiles and source tree.  The telnet/Source
+	directory is now gone, and all the source that was in
+	telnet/Source is now just in the telnet directory.
+
+	Seperate makefile for each system are now gone.  There
+	are two makefiles, Makefile and Makefile.generic.
+	The "Makefile" has the definitions for the various
+	system, and "Makefile.generic" does all the work.
+	There is a variable called "WHAT" that is used to
+	specify what to make.  For example, in the telnet
+	directory, you might say:
+		make 4.4bsd WHAT=clean
+	to clean out the directory.
+
+	Add support for the ENVIRON and XDISPLOC options.
+	In order for the server to work, login has to have
+	the "-p" option to preserve environment variables.
+
+	Add the SOFT_TAB and LIT_ECHO modes in the LINEMODE support.
+
+	Add the "-l user" option to command line and open command
+	(This is passed through the ENVIRON option).
+
+	Add the "-e" command line option, for setting the escape
+	character.
+
+	Add the "-D", diagnostic, option to the server.  This allows
+	the server to print out debug information, which is very
+	useful when trying to debug a telnet that doesn't have any
+	debugging ability.
+
+	Turn off the literal next character when not in LINEMODE.
+
+	Don't recognize ^Y locally, just pass it through.
+
+	Make minor modifications for Sun4.0 and Sun4.1
+
+	Add support for both FORW1 and FORW2 characters.  The
+	telnet escpape character is set to whichever of the
+	two is not being used.  If both are in use, the escape
+	character is not set, so when in linemode the user will
+	have to follow the escape character with a <CR> or <EOF)
+	to get it passed through.
+
+	Commands can now be put in single and double quotes, and
+	a backslash is now an escape character.  This is needed
+	for allowing arbitrary strings to be assigned to environment
+	variables.
+
+	Switch telnetd to use macros like telnet for keeping
+	track of the state of all the options.
+
+	Fix telnetd's processing of options so that we always do
+	the right processing of the LINEMODE option, regardless
+	of who initiates the request to turn it on.  Also, make
+	sure that if the other side went "WILL ECHO" in response
+	to our "DO ECHO", that we send a "DONT ECHO" to get the
+	option turned back off!
+
+	Fix the TERMIOS setting of the terminal speed to handle both
+	BSD's seperate fields, and the SYSV method of CBAUD bits.
+
+	Change how we deal with the other side refusing to enable
+	an option.  The sequence used to be: send DO option; receive
+	WONT option; send DONT option.  Now, the sequence is: send
+	DO option; receive WONT option.  Both should be valid
+	according to the spec, but there has been at least one
+	client implementation of telnet identified that can get
+	really confused by this.  (The exact sequence, from a trace
+	on the server side, is (numbers are number of responses that
+	we expect to get after that line...):
+
+		send WILL ECHO	1 (initial request)
+		send WONT ECHO	2 (server is changing state)
+		recv DO ECHO	1 (first reply, ok.  expect DONT ECHO next)
+		send WILL ECHO	2 (server changes state again)
+		recv DONT ECHO	1 (second reply, ok.  expect DO ECHO next)
+		recv DONT ECHO	0 (third reply, wrong answer. got DONT!!!)
+	***	send WONT ECHO	  (send WONT to acknowledge the DONT)
+		send WILL ECHO	1 (ask again to enable option)
+		recv DO ECHO	0
+
+		recv DONT ECHO	0
+		send WONT ECHO	1
+		recv DONT ECHO	0
+		recv DO ECHO	1
+		send WILL ECHO	0
+		(and the last 5 lines loop forever)
+
+	The line with the "***" is last of the WILL/DONT/WONT sequence.
+	The change to the server to not generate that makes this same
+	example become:
+
+		send will ECHO	1
+		send wont ECHO	2
+		recv do ECHO	1
+		send will ECHO	2
+		recv dont ECHO	1
+		recv dont ECHO	0
+		recv do ECHO	1
+		send will ECHO	0
+
+	There is other option negotiation going on, and not sending
+	the third part changes some of the timings, but this specific
+	example no longer gets stuck in a loop.  The "telnet.state"
+	file has been modified to reflect this change to the algorithm.
+
+	A bunch of miscellaneous bug fixes and changes to make
+	lint happier.
+
+	This version of telnet also has some KERBEROS stuff in
+	it. This has not been tested, it uses an un-authorized
+	telnet option number, and uses an out-of-date version
+	of the (still being defined) AUTHENTICATION option.
+	There is no support for this code, do not enable it.
+
+
+March 1, 1990:
+CHANGES/BUGFIXES SINCE LAST RELEASE:
+	Some support for IP TOS has been added.  Requires that the
+	kernel support the IP_TOS socket option (currently this
+	is only in UNICOS 6.0).
+
+	Both telnet and telnetd now use the cc_t typedef.  typedefs are
+	included for systems that don't have it (in termios.h).
+
+	SLC_SUSP was not supported properly before.  It is now.
+
+	IAC EOF was not translated  properly in telnetd for SYSV_TERMIO
+	when not in linemode.  It now saves a copy of the VEOF character,
+	so that when ICANON is turned off and we can't trust it anymore
+	(because it is now the VMIN character) we use the saved value.
+
+	There were two missing "break" commands in the linemode
+	processing code in telnetd.
+
+	Telnetd wasn't setting the kernel window size information
+	properly.  It was using the rows for both rows and columns...
+
+Questions/comments go to
+		David Borman
+		Cray Research, Inc.
+		655F Lone Oak Drive
+		Eagan, MN 55123
+		dab@cray.com.
+
+README:	You are reading it.
+
+Config.generic:
+	This file contains all the OS specific definitions.  It
+	has pre-definitions for many common system types, and is
+	in standard makefile fromat.  See the comments at the top
+	of the file for more information.
+
+Config.local:
+	This is not part of the distribution, but if this file exists,
+	it is used instead of "Config.generic".  This allows site
+	specific configuration without having to modify the distributed
+	"Config.generic" file.
+
+kern.diff:
+	This file contains the diffs for the changes needed for the
+	kernel to support LINEMODE is the server.  These changes are
+	for a 4.3BSD system.  You may need to make some changes for
+	your particular system.
+
+	There is a new bit in the terminal state word, TS_EXTPROC.
+	When this bit is set, several aspects of the terminal driver
+	are disabled.  Input line editing, character echo, and
+	mapping of signals are all disabled.  This allows the telnetd
+	to turn of these functions when in linemode, but still keep
+	track of what state the user wants the terminal to be in.
+
+	New ioctl()s:
+
+		TIOCEXT		Turn on/off the TS_EXTPROC bit
+		TIOCGSTATE	Get t_state of tty to look at TS_EXTPROC bit
+		TIOCSIG		Generate a signal to processes in the
+				current process group of the pty.
+
+	There is a new mode for packet driver, the TIOCPKT_IOCTL bit.
+	When packet mode is turned on in the pty, and the TS_EXTPROC
+	bit is set, then whenever the state of the pty is changed, the
+	next read on the master side of the pty will have the TIOCPKT_IOCTL
+	bit set, and the data will contain the following:
+		struct xx {
+			struct sgttyb a;
+			struct tchars b;
+			struct ltchars c;
+			int t_state;
+			int t_flags;
+		}
+	This allows the process on the server side of the pty to know
+	when the state of the terminal has changed, and what the new
+	state is.
+
+	However, if you define USE_TERMIO or SYSV_TERMIO, the code will
+	expect that the structure returned in the TIOCPKT_IOCTL is
+	the termio/termios structure.
+
+stty.diff:
+	This file contains the changes needed for the stty(1) program
+	to report on the current status of the TS_EXTPROC bit.  It also
+	allows the user to turn on/off the TS_EXTPROC bit.  This is useful
+	because it allows the user to say "stty -extproc", and the
+	LINEMODE option will be automatically disabled, and saying "stty
+	extproc" will re-enable the LINEMODE option.
+
+telnet.state:
+	Both the client and server have code in them to deal
+	with option negotiation loops.  The algorithm that is
+	used is described in this file.
+
+telnet:
+	This directory contains the client code.  No kernel changes are
+	needed to use this code.
+
+telnetd:
+	This directory contains the server code.  If LINEMODE or KLUDGELINEMODE
+	are defined, then the kernel modifications listed above are needed.
+
+libtelnet:
+	This directory contains code that is common to both the client
+	and the server.
+
+arpa:
+	This directory has a new <arpa/telnet.h>
+
+libtelnet/Makefile.4.4:
+telnet/Makefile.4.4:
+telnetd/Makefile.4.4:
+	These are the makefiles that can be used on a 4.3Reno
+	system when this software is installed in /usr/src/lib/libtelnet,
+	/usr/src/libexec/telnetd, and /usr/src/usr.bin/telnet.
+
+
+The following TELNET options are supported:
+	
+	LINEMODE:
+		The LINEMODE option is supported as per RFC1116.  The
+		FORWARDMASK option is not currently supported.
+
+	BINARY: The client has the ability to turn on/off the BINARY
+		option in each direction.  Turning on BINARY from
+		server to client causes the LITOUT bit to get set in
+		the terminal driver on both ends,  turning on BINARY
+		from the client to the server causes the PASS8 bit
+		to get set in the terminal driver on both ends.
+
+	TERMINAL-TYPE:
+		This is supported as per RFC1091.  On the server side,
+		when a terminal type is received, termcap/terminfo
+		is consulted to determine if it is a known terminal
+		type.  It keeps requesting terminal types until it
+		gets one that it recongnizes, or hits the end of the
+		list.  The server side looks up the entry in the
+		termcap/terminfo data base, and generates a list of
+		names which it then passes one at a time to each
+		request for a terminal type, duplicating the last
+		entry in the list before cycling back to the beginning.
+
+	NAWS:	The Negotiate about Window Size, as per RFC 1073.
+
+	TERMINAL-SPEED:
+		Implemented as per RFC 1079
+
+	TOGGLE-FLOW-CONTROL:
+		Implemented as per RFC 1080
+
+	TIMING-MARK:
+		As per RFC 860
+
+	SGA:	As per RFC 858
+
+	ECHO:	As per RFC 857
+
+	LOGOUT: As per RFC 727
+
+	STATUS:
+		The server will send its current status upon
+		request.  It does not ask for the clients status.
+		The client will request the servers current status
+		from the "send getstatus" command.
+
+	ENVIRON:
+		This option is currently being defined by the IETF
+		Telnet Working Group, and an RFC has not yet been
+		issued, but should be in the near future...
+
+	X-DISPLAY-LOCATION:
+		This functionality can be done through the ENVIRON
+		option, it is added here for completeness.
+
+	AUTHENTICATION:
+		This option is currently being defined by the IETF
+		Telnet Working Group, and an RFC has not yet been
+		issued.  The basic framework is pretty much decided,
+		but the definitions for the specific authentication
+		schemes is still in a state of flux.
+
+	ENCRYPTION:
+		This option is currently being defined by the IETF
+		Telnet Working Group, and an RFC has not yet been
+		issued.  The draft RFC is still in a state of flux,
+		so this code may change in the future.
diff --git a/telnet.tproj/authenc.c b/telnet.tproj/authenc.c
new file mode 100644
index 0000000..9d5330d
--- /dev/null
+++ b/telnet.tproj/authenc.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)authenc.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
+#include <sys/types.h>
+#include <arpa/telnet.h>
+#include <libtelnet/encrypt.h>
+#include <libtelnet/misc.h>
+
+#include "general.h"
+#include "ring.h"
+#include "externs.h"
+#include "defines.h"
+#include "types.h"
+
+	int
+net_write(str, len)
+	unsigned char *str;
+	int len;
+{
+	if (NETROOM() > len) {
+		ring_supply_data(&netoring, str, len);
+		if (str[0] == IAC && str[1] == SE)
+			printsub('>', &str[2], len-2);
+		return(len);
+	}
+	return(0);
+}
+
+	void
+net_encrypt()
+{
+#ifdef	ENCRYPTION
+	if (encrypt_output)
+		ring_encrypt(&netoring, encrypt_output);
+	else
+		ring_clearto(&netoring);
+#endif	/* ENCRYPTION */
+}
+
+	int
+telnet_spin()
+{
+	return(-1);
+}
+
+	char *
+telnet_getenv(val)
+	char *val;
+{
+	return((char *)env_getvalue((unsigned char *)val));
+}
+
+	char *
+telnet_gets(prompt, result, length, echo)
+	char *prompt;
+	char *result;
+	int length;
+	int echo;
+{
+	extern char *getpass();
+	extern int globalmode;
+	int om = globalmode;
+	char *res;
+
+	TerminalNewMode(-1);
+	if (echo) {
+		printf("%s", prompt);
+		res = fgets(result, length, stdin);
+	} else if (res = getpass(prompt)) {
+		strncpy(result, res, length);
+		res = result;
+	}
+	TerminalNewMode(om);
+	return(res);
+}
+#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION) */
diff --git a/telnet.tproj/commands.c b/telnet.tproj/commands.c
new file mode 100644
index 0000000..903bda3
--- /dev/null
+++ b/telnet.tproj/commands.c
@@ -0,0 +1,2990 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)commands.c	8.4 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#if	defined(unix) || defined(__APPLE__)
+#include <sys/param.h>
+#if	defined(CRAY) || defined(sysV88)
+#include <sys/types.h>
+#endif
+#include <sys/file.h>
+#else
+#include <sys/types.h>
+#endif	/* defined(unix) || defined(__APPLE__) */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#ifdef	CRAY
+#include <fcntl.h>
+#endif	/* CRAY */
+
+#include <signal.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <pwd.h>
+#if !defined(__APPLE__)
+#include <varargs.h>
+#endif
+#include <errno.h>
+
+#include <arpa/telnet.h>
+
+#include "general.h"
+
+#include "ring.h"
+
+#include "externs.h"
+#include "defines.h"
+#include "types.h"
+
+#if !defined(CRAY) && !defined(sysV88)
+#include <netinet/in_systm.h>
+# if (defined(vax) || defined(tahoe) || defined(hp300)) && !defined(ultrix)
+# include <machine/endian.h>
+# endif /* vax */
+#endif /* !defined(CRAY) && !defined(sysV88) */
+#include <netinet/ip.h>
+
+
+#ifndef	MAXHOSTNAMELEN
+#define	MAXHOSTNAMELEN 64
+#endif	MAXHOSTNAMELEN
+
+#if	defined(IPPROTO_IP) && defined(IP_TOS)
+int tos = -1;
+#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */
+
+char	*hostname;
+static char _hostname[MAXHOSTNAMELEN];
+
+extern char *getenv();
+
+extern int isprefix();
+extern char **genget();
+extern int Ambiguous();
+
+typedef int (*intrtn_t)();
+#if __STDC__
+static call(intrtn_t routine, ...);
+#else
+static call();
+#endif
+
+typedef struct {
+	char	*name;		/* command name */
+	char	*help;		/* help string (NULL for no help) */
+	int	(*handler)();	/* routine which executes command */
+	int	needconnect;	/* Do we need to be connected to execute? */
+} Command;
+
+static char line[256];
+static char saveline[256];
+static int margc;
+static char *margv[20];
+
+    static void
+makeargv()
+{
+    register char *cp, *cp2, c;
+    register char **argp = margv;
+
+    margc = 0;
+    cp = line;
+    if (*cp == '!') {		/* Special case shell escape */
+	strcpy(saveline, line);	/* save for shell command */
+	*argp++ = "!";		/* No room in string to get this */
+	margc++;
+	cp++;
+    }
+    while (c = *cp) {
+	register int inquote = 0;
+	while (isspace(c))
+	    c = *++cp;
+	if (c == '\0')
+	    break;
+	*argp++ = cp;
+	margc += 1;
+	for (cp2 = cp; c != '\0'; c = *++cp) {
+	    if (inquote) {
+		if (c == inquote) {
+		    inquote = 0;
+		    continue;
+		}
+	    } else {
+		if (c == '\\') {
+		    if ((c = *++cp) == '\0')
+			break;
+		} else if (c == '"') {
+		    inquote = '"';
+		    continue;
+		} else if (c == '\'') {
+		    inquote = '\'';
+		    continue;
+		} else if (isspace(c))
+		    break;
+	    }
+	    *cp2++ = c;
+	}
+	*cp2 = '\0';
+	if (c == '\0')
+	    break;
+	cp++;
+    }
+    *argp++ = 0;
+}
+
+/*
+ * Make a character string into a number.
+ *
+ * Todo:  1.  Could take random integers (12, 0x12, 012, 0b1).
+ */
+
+	static
+special(s)
+	register char *s;
+{
+	register char c;
+	char b;
+
+	switch (*s) {
+	case '^':
+		b = *++s;
+		if (b == '?') {
+		    c = b | 0x40;		/* DEL */
+		} else {
+		    c = b & 0x1f;
+		}
+		break;
+	default:
+		c = *s;
+		break;
+	}
+	return c;
+}
+
+/*
+ * Construct a control character sequence
+ * for a special character.
+ */
+	static char *
+control(c)
+	register cc_t c;
+{
+	static char buf[5];
+	/*
+	 * The only way I could get the Sun 3.5 compiler
+	 * to shut up about
+	 *	if ((unsigned int)c >= 0x80)
+	 * was to assign "c" to an unsigned int variable...
+	 * Arggg....
+	 */
+	register unsigned int uic = (unsigned int)c;
+
+	if (uic == 0x7f)
+		return ("^?");
+	if (c == (cc_t)_POSIX_VDISABLE) {
+		return "off";
+	}
+	if (uic >= 0x80) {
+		buf[0] = '\\';
+		buf[1] = ((c>>6)&07) + '0';
+		buf[2] = ((c>>3)&07) + '0';
+		buf[3] = (c&07) + '0';
+		buf[4] = 0;
+	} else if (uic >= 0x20) {
+		buf[0] = c;
+		buf[1] = 0;
+	} else {
+		buf[0] = '^';
+		buf[1] = '@'+c;
+		buf[2] = 0;
+	}
+	return (buf);
+}
+
+
+
+/*
+ *	The following are data structures and routines for
+ *	the "send" command.
+ *
+ */
+
+struct sendlist {
+    char	*name;		/* How user refers to it (case independent) */
+    char	*help;		/* Help information (0 ==> no help) */
+    int		needconnect;	/* Need to be connected */
+    int		narg;		/* Number of arguments */
+    int		(*handler)();	/* Routine to perform (for special ops) */
+    int		nbyte;		/* Number of bytes to send this command */
+    int		what;		/* Character to be sent (<0 ==> special) */
+};
+
+
+static int
+	send_esc P((void)),
+	send_help P((void)),
+	send_docmd P((char *)),
+	send_dontcmd P((char *)),
+	send_willcmd P((char *)),
+	send_wontcmd P((char *));
+
+static struct sendlist Sendlist[] = {
+    { "ao",	"Send Telnet Abort output",		1, 0, 0, 2, AO },
+    { "ayt",	"Send Telnet 'Are You There'",		1, 0, 0, 2, AYT },
+    { "brk",	"Send Telnet Break",			1, 0, 0, 2, BREAK },
+    { "break",	0,					1, 0, 0, 2, BREAK },
+    { "ec",	"Send Telnet Erase Character",		1, 0, 0, 2, EC },
+    { "el",	"Send Telnet Erase Line",		1, 0, 0, 2, EL },
+    { "escape",	"Send current escape character",	1, 0, send_esc, 1, 0 },
+    { "ga",	"Send Telnet 'Go Ahead' sequence",	1, 0, 0, 2, GA },
+    { "ip",	"Send Telnet Interrupt Process",	1, 0, 0, 2, IP },
+    { "intp",	0,					1, 0, 0, 2, IP },
+    { "interrupt", 0,					1, 0, 0, 2, IP },
+    { "intr",	0,					1, 0, 0, 2, IP },
+    { "nop",	"Send Telnet 'No operation'",		1, 0, 0, 2, NOP },
+    { "eor",	"Send Telnet 'End of Record'",		1, 0, 0, 2, EOR },
+    { "abort",	"Send Telnet 'Abort Process'",		1, 0, 0, 2, ABORT },
+    { "susp",	"Send Telnet 'Suspend Process'",	1, 0, 0, 2, SUSP },
+    { "eof",	"Send Telnet End of File Character",	1, 0, 0, 2, xEOF },
+    { "synch",	"Perform Telnet 'Synch operation'",	1, 0, dosynch, 2, 0 },
+    { "getstatus", "Send request for STATUS",		1, 0, get_status, 6, 0 },
+    { "?",	"Display send options",			0, 0, send_help, 0, 0 },
+    { "help",	0,					0, 0, send_help, 0, 0 },
+    { "do",	0,					0, 1, send_docmd, 3, 0 },
+    { "dont",	0,					0, 1, send_dontcmd, 3, 0 },
+    { "will",	0,					0, 1, send_willcmd, 3, 0 },
+    { "wont",	0,					0, 1, send_wontcmd, 3, 0 },
+    { 0 }
+};
+
+#define	GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \
+				sizeof(struct sendlist)))
+
+    static int
+sendcmd(argc, argv)
+    int  argc;
+    char **argv;
+{
+    int count;		/* how many bytes we are going to need to send */
+    int i;
+    int question = 0;	/* was at least one argument a question */
+    struct sendlist *s;	/* pointer to current command */
+    int success = 0;
+    int needconnect = 0;
+
+    if (argc < 2) {
+	printf("need at least one argument for 'send' command\n");
+	printf("'send ?' for help\n");
+	return 0;
+    }
+    /*
+     * First, validate all the send arguments.
+     * In addition, we see how much space we are going to need, and
+     * whether or not we will be doing a "SYNCH" operation (which
+     * flushes the network queue).
+     */
+    count = 0;
+    for (i = 1; i < argc; i++) {
+	s = GETSEND(argv[i]);
+	if (s == 0) {
+	    printf("Unknown send argument '%s'\n'send ?' for help.\n",
+			argv[i]);
+	    return 0;
+	} else if (Ambiguous(s)) {
+	    printf("Ambiguous send argument '%s'\n'send ?' for help.\n",
+			argv[i]);
+	    return 0;
+	}
+	if (i + s->narg >= argc) {
+	    fprintf(stderr,
+	    "Need %d argument%s to 'send %s' command.  'send %s ?' for help.\n",
+		s->narg, s->narg == 1 ? "" : "s", s->name, s->name);
+	    return 0;
+	}
+	count += s->nbyte;
+	if (s->handler == send_help) {
+	    send_help();
+	    return 0;
+	}
+
+	i += s->narg;
+	needconnect += s->needconnect;
+    }
+    if (!connected && needconnect) {
+	printf("?Need to be connected first.\n");
+	printf("'send ?' for help\n");
+	return 0;
+    }
+    /* Now, do we have enough room? */
+    if (NETROOM() < count) {
+	printf("There is not enough room in the buffer TO the network\n");
+	printf("to process your request.  Nothing will be done.\n");
+	printf("('send synch' will throw away most data in the network\n");
+	printf("buffer, if this might help.)\n");
+	return 0;
+    }
+    /* OK, they are all OK, now go through again and actually send */
+    count = 0;
+    for (i = 1; i < argc; i++) {
+	if ((s = GETSEND(argv[i])) == 0) {
+	    fprintf(stderr, "Telnet 'send' error - argument disappeared!\n");
+	    (void) quit();
+	    /*NOTREACHED*/
+	}
+	if (s->handler) {
+	    count++;
+	    success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0,
+				  (s->narg > 1) ? argv[i+2] : 0);
+	    i += s->narg;
+	} else {
+	    NET2ADD(IAC, s->what);
+	    printoption("SENT", IAC, s->what);
+	}
+    }
+    return (count == success);
+}
+
+    static int
+send_esc()
+{
+    NETADD(escape);
+    return 1;
+}
+
+    static int
+send_docmd(name)
+    char *name;
+{
+    return(send_tncmd(send_do, "do", name));
+}
+
+    static int
+send_dontcmd(name)
+    char *name;
+{
+    return(send_tncmd(send_dont, "dont", name));
+}
+    static int
+send_willcmd(name)
+    char *name;
+{
+    return(send_tncmd(send_will, "will", name));
+}
+    static int
+send_wontcmd(name)
+    char *name;
+{
+    return(send_tncmd(send_wont, "wont", name));
+}
+
+    int
+send_tncmd(func, cmd, name)
+    void	(*func)();
+    char	*cmd, *name;
+{
+    char **cpp;
+    extern char *telopts[];
+    register int val = 0;
+
+    if (isprefix(name, "help") || isprefix(name, "?")) {
+	register int col, len;
+
+	printf("Usage: send %s <value|option>\n", cmd);
+	printf("\"value\" must be from 0 to 255\n");
+	printf("Valid options are:\n\t");
+
+	col = 8;
+	for (cpp = telopts; *cpp; cpp++) {
+	    len = strlen(*cpp) + 3;
+	    if (col + len > 65) {
+		printf("\n\t");
+		col = 8;
+	    }
+	    printf(" \"%s\"", *cpp);
+	    col += len;
+	}
+	printf("\n");
+	return 0;
+    }
+    cpp = (char **)genget(name, telopts, sizeof(char *));
+    if (Ambiguous(cpp)) {
+	fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n",
+					name, cmd);
+	return 0;
+    }
+    if (cpp) {
+	val = cpp - telopts;
+    } else {
+	register char *cp = name;
+
+	while (*cp >= '0' && *cp <= '9') {
+	    val *= 10;
+	    val += *cp - '0';
+	    cp++;
+	}
+	if (*cp != 0) {
+	    fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n",
+					name, cmd);
+	    return 0;
+	} else if (val < 0 || val > 255) {
+	    fprintf(stderr, "'%s': bad value ('send %s ?' for help).\n",
+					name, cmd);
+	    return 0;
+	}
+    }
+    if (!connected) {
+	printf("?Need to be connected first.\n");
+	return 0;
+    }
+    (*func)(val, 1);
+    return 1;
+}
+
+    static int
+send_help()
+{
+    struct sendlist *s;	/* pointer to current command */
+    for (s = Sendlist; s->name; s++) {
+	if (s->help)
+	    printf("%-15s %s\n", s->name, s->help);
+    }
+    return(0);
+}
+
+/*
+ * The following are the routines and data structures referred
+ * to by the arguments to the "toggle" command.
+ */
+
+    static int
+lclchars()
+{
+    donelclchars = 1;
+    return 1;
+}
+
+    static int
+togdebug()
+{
+#ifndef	NOT43
+    if (net > 0 &&
+	(SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) {
+	    perror("setsockopt (SO_DEBUG)");
+    }
+#else	/* NOT43 */
+    if (debug) {
+	if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
+	    perror("setsockopt (SO_DEBUG)");
+    } else
+	printf("Cannot turn off socket debugging\n");
+#endif	/* NOT43 */
+    return 1;
+}
+
+
+    static int
+togcrlf()
+{
+    if (crlf) {
+	printf("Will send carriage returns as telnet <CR><LF>.\n");
+    } else {
+	printf("Will send carriage returns as telnet <CR><NUL>.\n");
+    }
+    return 1;
+}
+
+int binmode;
+
+    static int
+togbinary(val)
+    int val;
+{
+    donebinarytoggle = 1;
+
+    if (val >= 0) {
+	binmode = val;
+    } else {
+	if (my_want_state_is_will(TELOPT_BINARY) &&
+				my_want_state_is_do(TELOPT_BINARY)) {
+	    binmode = 1;
+	} else if (my_want_state_is_wont(TELOPT_BINARY) &&
+				my_want_state_is_dont(TELOPT_BINARY)) {
+	    binmode = 0;
+	}
+	val = binmode ? 0 : 1;
+    }
+
+    if (val == 1) {
+	if (my_want_state_is_will(TELOPT_BINARY) &&
+					my_want_state_is_do(TELOPT_BINARY)) {
+	    printf("Already operating in binary mode with remote host.\n");
+	} else {
+	    printf("Negotiating binary mode with remote host.\n");
+	    tel_enter_binary(3);
+	}
+    } else {
+	if (my_want_state_is_wont(TELOPT_BINARY) &&
+					my_want_state_is_dont(TELOPT_BINARY)) {
+	    printf("Already in network ascii mode with remote host.\n");
+	} else {
+	    printf("Negotiating network ascii mode with remote host.\n");
+	    tel_leave_binary(3);
+	}
+    }
+    return 1;
+}
+
+    static int
+togrbinary(val)
+    int val;
+{
+    donebinarytoggle = 1;
+
+    if (val == -1)
+	val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1;
+
+    if (val == 1) {
+	if (my_want_state_is_do(TELOPT_BINARY)) {
+	    printf("Already receiving in binary mode.\n");
+	} else {
+	    printf("Negotiating binary mode on input.\n");
+	    tel_enter_binary(1);
+	}
+    } else {
+	if (my_want_state_is_dont(TELOPT_BINARY)) {
+	    printf("Already receiving in network ascii mode.\n");
+	} else {
+	    printf("Negotiating network ascii mode on input.\n");
+	    tel_leave_binary(1);
+	}
+    }
+    return 1;
+}
+
+    static int
+togxbinary(val)
+    int val;
+{
+    donebinarytoggle = 1;
+
+    if (val == -1)
+	val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1;
+
+    if (val == 1) {
+	if (my_want_state_is_will(TELOPT_BINARY)) {
+	    printf("Already transmitting in binary mode.\n");
+	} else {
+	    printf("Negotiating binary mode on output.\n");
+	    tel_enter_binary(2);
+	}
+    } else {
+	if (my_want_state_is_wont(TELOPT_BINARY)) {
+	    printf("Already transmitting in network ascii mode.\n");
+	} else {
+	    printf("Negotiating network ascii mode on output.\n");
+	    tel_leave_binary(2);
+	}
+    }
+    return 1;
+}
+
+
+static int togglehelp P((void));
+#if	defined(AUTHENTICATION)
+extern int auth_togdebug P((int));
+#endif
+#ifdef	ENCRYPTION
+extern int EncryptAutoEnc P((int));
+extern int EncryptAutoDec P((int));
+extern int EncryptDebug P((int));
+extern int EncryptVerbose P((int));
+#endif	/* ENCRYPTION */
+
+struct togglelist {
+    char	*name;		/* name of toggle */
+    char	*help;		/* help message */
+    int		(*handler)();	/* routine to do actual setting */
+    int		*variable;
+    char	*actionexplanation;
+};
+
+static struct togglelist Togglelist[] = {
+    { "autoflush",
+	"flushing of output when sending interrupt characters",
+	    0,
+		&autoflush,
+		    "flush output when sending interrupt characters" },
+    { "autosynch",
+	"automatic sending of interrupt characters in urgent mode",
+	    0,
+		&autosynch,
+		    "send interrupt characters in urgent mode" },
+#if	defined(AUTHENTICATION)
+    { "autologin",
+	"automatic sending of login and/or authentication info",
+	    0,
+		&autologin,
+		    "send login name and/or authentication information" },
+    { "authdebug",
+	"Toggle authentication debugging",
+	    auth_togdebug,
+		0,
+		     "print authentication debugging information" },
+#endif
+#ifdef	ENCRYPTION
+    { "autoencrypt",
+	"automatic encryption of data stream",
+	    EncryptAutoEnc,
+		0,
+		    "automatically encrypt output" },
+    { "autodecrypt",
+	"automatic decryption of data stream",
+	    EncryptAutoDec,
+		0,
+		    "automatically decrypt input" },
+    { "verbose_encrypt",
+	"Toggle verbose encryption output",
+	    EncryptVerbose,
+		0,
+		    "print verbose encryption output" },
+    { "encdebug",
+	"Toggle encryption debugging",
+	    EncryptDebug,
+		0,
+		    "print encryption debugging information" },
+#endif	/* ENCRYPTION */
+    { "skiprc",
+	"don't read ~/.telnetrc file",
+	    0,
+		&skiprc,
+		    "skip reading of ~/.telnetrc file" },
+    { "binary",
+	"sending and receiving of binary data",
+	    togbinary,
+		0,
+		    0 },
+    { "inbinary",
+	"receiving of binary data",
+	    togrbinary,
+		0,
+		    0 },
+    { "outbinary",
+	"sending of binary data",
+	    togxbinary,
+		0,
+		    0 },
+    { "crlf",
+	"sending carriage returns as telnet <CR><LF>",
+	    togcrlf,
+		&crlf,
+		    0 },
+    { "crmod",
+	"mapping of received carriage returns",
+	    0,
+		&crmod,
+		    "map carriage return on output" },
+    { "localchars",
+	"local recognition of certain control characters",
+	    lclchars,
+		&localchars,
+		    "recognize certain control characters" },
+    { " ", "", 0 },		/* empty line */
+#if	(defined(unix) || defined(__APPLE__)) && defined(TN3270)
+    { "apitrace",
+	"(debugging) toggle tracing of API transactions",
+	    0,
+		&apitrace,
+		    "trace API transactions" },
+    { "cursesdata",
+	"(debugging) toggle printing of hexadecimal curses data",
+	    0,
+		&cursesdata,
+		    "print hexadecimal representation of curses data" },
+#endif	/* (defined(unix) || defined(__APPLE__)) && defined(TN3270) */
+    { "debug",
+	"debugging",
+	    togdebug,
+		&debug,
+		    "turn on socket level debugging" },
+    { "netdata",
+	"printing of hexadecimal network data (debugging)",
+	    0,
+		&netdata,
+		    "print hexadecimal representation of network traffic" },
+    { "prettydump",
+	"output of \"netdata\" to user readable format (debugging)",
+	    0,
+		&prettydump,
+		    "print user readable output for \"netdata\"" },
+    { "options",
+	"viewing of options processing (debugging)",
+	    0,
+		&showoptions,
+		    "show option processing" },
+#if	defined(unix) || defined(__APPLE__)
+    { "termdata",
+	"(debugging) toggle printing of hexadecimal terminal data",
+	    0,
+		&termdata,
+		    "print hexadecimal representation of terminal traffic" },
+#endif	/* defined(unix) || defined(__APPLE__) */
+    { "?",
+	0,
+	    togglehelp },
+    { "help",
+	0,
+	    togglehelp },
+    { 0 }
+};
+
+    static int
+togglehelp()
+{
+    struct togglelist *c;
+
+    for (c = Togglelist; c->name; c++) {
+	if (c->help) {
+	    if (*c->help)
+		printf("%-15s toggle %s\n", c->name, c->help);
+	    else
+		printf("\n");
+	}
+    }
+    printf("\n");
+    printf("%-15s %s\n", "?", "display help information");
+    return 0;
+}
+
+    static void
+settogglehelp(set)
+    int set;
+{
+    struct togglelist *c;
+
+    for (c = Togglelist; c->name; c++) {
+	if (c->help) {
+	    if (*c->help)
+		printf("%-15s %s %s\n", c->name, set ? "enable" : "disable",
+						c->help);
+	    else
+		printf("\n");
+	}
+    }
+}
+
+#define	GETTOGGLE(name) (struct togglelist *) \
+		genget(name, (char **) Togglelist, sizeof(struct togglelist))
+
+    static int
+toggle(argc, argv)
+    int  argc;
+    char *argv[];
+{
+    int retval = 1;
+    char *name;
+    struct togglelist *c;
+
+    if (argc < 2) {
+	fprintf(stderr,
+	    "Need an argument to 'toggle' command.  'toggle ?' for help.\n");
+	return 0;
+    }
+    argc--;
+    argv++;
+    while (argc--) {
+	name = *argv++;
+	c = GETTOGGLE(name);
+	if (Ambiguous(c)) {
+	    fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n",
+					name);
+	    return 0;
+	} else if (c == 0) {
+	    fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n",
+					name);
+	    return 0;
+	} else {
+	    if (c->variable) {
+		*c->variable = !*c->variable;		/* invert it */
+		if (c->actionexplanation) {
+		    printf("%s %s.\n", *c->variable? "Will" : "Won't",
+							c->actionexplanation);
+		}
+	    }
+	    if (c->handler) {
+		retval &= (*c->handler)(-1);
+	    }
+	}
+    }
+    return retval;
+}
+
+/*
+ * The following perform the "set" command.
+ */
+
+#ifdef	USE_TERMIO
+struct termio new_tc = { 0 };
+#endif
+
+struct setlist {
+    char *name;				/* name */
+    char *help;				/* help information */
+    void (*handler)();
+    cc_t *charp;			/* where it is located at */
+};
+
+static struct setlist Setlist[] = {
+#ifdef	KLUDGELINEMODE
+    { "echo", 	"character to toggle local echoing on/off", 0, &echoc },
+#endif
+    { "escape",	"character to escape back to telnet command mode", 0, &escape },
+    { "rlogin", "rlogin escape character", 0, &rlogin },
+    { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile},
+    { " ", "" },
+    { " ", "The following need 'localchars' to be toggled true", 0, 0 },
+    { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp },
+    { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp },
+    { "quit",	"character to cause an Abort process", 0, termQuitCharp },
+    { "eof",	"character to cause an EOF ", 0, termEofCharp },
+    { " ", "" },
+    { " ", "The following are for local editing in linemode", 0, 0 },
+    { "erase",	"character to use to erase a character", 0, termEraseCharp },
+    { "kill",	"character to use to erase a line", 0, termKillCharp },
+    { "lnext",	"character to use for literal next", 0, termLiteralNextCharp },
+    { "susp",	"character to cause a Suspend Process", 0, termSuspCharp },
+    { "reprint", "character to use for line reprint", 0, termRprntCharp },
+    { "worderase", "character to use to erase a word", 0, termWerasCharp },
+    { "start",	"character to use for XON", 0, termStartCharp },
+    { "stop",	"character to use for XOFF", 0, termStopCharp },
+    { "forw1",	"alternate end of line character", 0, termForw1Charp },
+    { "forw2",	"alternate end of line character", 0, termForw2Charp },
+    { "ayt",	"alternate AYT character", 0, termAytCharp },
+    { 0 }
+};
+
+#if	defined(CRAY) && !defined(__STDC__)
+/* Work around compiler bug in pcc 4.1.5 */
+    void
+_setlist_init()
+{
+#ifndef	KLUDGELINEMODE
+#define	N 5
+#else
+#define	N 6
+#endif
+	Setlist[N+0].charp = &termFlushChar;
+	Setlist[N+1].charp = &termIntChar;
+	Setlist[N+2].charp = &termQuitChar;
+	Setlist[N+3].charp = &termEofChar;
+	Setlist[N+6].charp = &termEraseChar;
+	Setlist[N+7].charp = &termKillChar;
+	Setlist[N+8].charp = &termLiteralNextChar;
+	Setlist[N+9].charp = &termSuspChar;
+	Setlist[N+10].charp = &termRprntChar;
+	Setlist[N+11].charp = &termWerasChar;
+	Setlist[N+12].charp = &termStartChar;
+	Setlist[N+13].charp = &termStopChar;
+	Setlist[N+14].charp = &termForw1Char;
+	Setlist[N+15].charp = &termForw2Char;
+	Setlist[N+16].charp = &termAytChar;
+#undef	N
+}
+#endif	/* defined(CRAY) && !defined(__STDC__) */
+
+    static struct setlist *
+getset(name)
+    char *name;
+{
+    return (struct setlist *)
+		genget(name, (char **) Setlist, sizeof(struct setlist));
+}
+
+    void
+set_escape_char(s)
+    char *s;
+{
+	if (rlogin != _POSIX_VDISABLE) {
+		rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE;
+		printf("Telnet rlogin escape character is '%s'.\n",
+					control(rlogin));
+	} else {
+		escape = (s && *s) ? special(s) : _POSIX_VDISABLE;
+		printf("Telnet escape character is '%s'.\n", control(escape));
+	}
+}
+
+    static int
+setcmd(argc, argv)
+    int  argc;
+    char *argv[];
+{
+    int value;
+    struct setlist *ct;
+    struct togglelist *c;
+
+    if (argc < 2 || argc > 3) {
+	printf("Format is 'set Name Value'\n'set ?' for help.\n");
+	return 0;
+    }
+    if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) {
+	for (ct = Setlist; ct->name; ct++)
+	    printf("%-15s %s\n", ct->name, ct->help);
+	printf("\n");
+	settogglehelp(1);
+	printf("%-15s %s\n", "?", "display help information");
+	return 0;
+    }
+
+    ct = getset(argv[1]);
+    if (ct == 0) {
+	c = GETTOGGLE(argv[1]);
+	if (c == 0) {
+	    fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n",
+			argv[1]);
+	    return 0;
+	} else if (Ambiguous(c)) {
+	    fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n",
+			argv[1]);
+	    return 0;
+	}
+	if (c->variable) {
+	    if ((argc == 2) || (strcmp("on", argv[2]) == 0))
+		*c->variable = 1;
+	    else if (strcmp("off", argv[2]) == 0)
+		*c->variable = 0;
+	    else {
+		printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n");
+		return 0;
+	    }
+	    if (c->actionexplanation) {
+		printf("%s %s.\n", *c->variable? "Will" : "Won't",
+							c->actionexplanation);
+	    }
+	}
+	if (c->handler)
+	    (*c->handler)(1);
+    } else if (argc != 3) {
+	printf("Format is 'set Name Value'\n'set ?' for help.\n");
+	return 0;
+    } else if (Ambiguous(ct)) {
+	fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n",
+			argv[1]);
+	return 0;
+    } else if (ct->handler) {
+	(*ct->handler)(argv[2]);
+	printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp);
+    } else {
+	if (strcmp("off", argv[2])) {
+	    value = special(argv[2]);
+	} else {
+	    value = _POSIX_VDISABLE;
+	}
+	*(ct->charp) = (cc_t)value;
+	printf("%s character is '%s'.\n", ct->name, control(*(ct->charp)));
+    }
+    slc_check();
+    return 1;
+}
+
+    static int
+unsetcmd(argc, argv)
+    int  argc;
+    char *argv[];
+{
+    struct setlist *ct;
+    struct togglelist *c;
+    register char *name;
+
+    if (argc < 2) {
+	fprintf(stderr,
+	    "Need an argument to 'unset' command.  'unset ?' for help.\n");
+	return 0;
+    }
+    if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) {
+	for (ct = Setlist; ct->name; ct++)
+	    printf("%-15s %s\n", ct->name, ct->help);
+	printf("\n");
+	settogglehelp(0);
+	printf("%-15s %s\n", "?", "display help information");
+	return 0;
+    }
+
+    argc--;
+    argv++;
+    while (argc--) {
+	name = *argv++;
+	ct = getset(name);
+	if (ct == 0) {
+	    c = GETTOGGLE(name);
+	    if (c == 0) {
+		fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n",
+			name);
+		return 0;
+	    } else if (Ambiguous(c)) {
+		fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n",
+			name);
+		return 0;
+	    }
+	    if (c->variable) {
+		*c->variable = 0;
+		if (c->actionexplanation) {
+		    printf("%s %s.\n", *c->variable? "Will" : "Won't",
+							c->actionexplanation);
+		}
+	    }
+	    if (c->handler)
+		(*c->handler)(0);
+	} else if (Ambiguous(ct)) {
+	    fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n",
+			name);
+	    return 0;
+	} else if (ct->handler) {
+	    (*ct->handler)(0);
+	    printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp);
+	} else {
+	    *(ct->charp) = _POSIX_VDISABLE;
+	    printf("%s character is '%s'.\n", ct->name, control(*(ct->charp)));
+	}
+    }
+    return 1;
+}
+
+/*
+ * The following are the data structures and routines for the
+ * 'mode' command.
+ */
+#ifdef	KLUDGELINEMODE
+extern int kludgelinemode;
+
+    static int
+dokludgemode()
+{
+    kludgelinemode = 1;
+    send_wont(TELOPT_LINEMODE, 1);
+    send_dont(TELOPT_SGA, 1);
+    send_dont(TELOPT_ECHO, 1);
+}
+#endif
+
+    static int
+dolinemode()
+{
+#ifdef	KLUDGELINEMODE
+    if (kludgelinemode)
+	send_dont(TELOPT_SGA, 1);
+#endif
+    send_will(TELOPT_LINEMODE, 1);
+    send_dont(TELOPT_ECHO, 1);
+    return 1;
+}
+
+    static int
+docharmode()
+{
+#ifdef	KLUDGELINEMODE
+    if (kludgelinemode)
+	send_do(TELOPT_SGA, 1);
+    else
+#endif
+    send_wont(TELOPT_LINEMODE, 1);
+    send_do(TELOPT_ECHO, 1);
+    return 1;
+}
+
+    static int
+dolmmode(bit, on)
+    int bit, on;
+{
+    unsigned char c;
+    extern int linemode;
+
+    if (my_want_state_is_wont(TELOPT_LINEMODE)) {
+	printf("?Need to have LINEMODE option enabled first.\n");
+	printf("'mode ?' for help.\n");
+	return 0;
+    }
+
+    if (on)
+	c = (linemode | bit);
+    else
+	c = (linemode & ~bit);
+    lm_mode(&c, 1, 1);
+    return 1;
+}
+
+    int
+setmode(bit)
+{
+    return dolmmode(bit, 1);
+}
+
+    int
+clearmode(bit)
+{
+    return dolmmode(bit, 0);
+}
+
+struct modelist {
+	char	*name;		/* command name */
+	char	*help;		/* help string */
+	int	(*handler)();	/* routine which executes command */
+	int	needconnect;	/* Do we need to be connected to execute? */
+	int	arg1;
+};
+
+extern int modehelp();
+
+static struct modelist ModeList[] = {
+    { "character", "Disable LINEMODE option",	docharmode, 1 },
+#ifdef	KLUDGELINEMODE
+    { "",	"(or disable obsolete line-by-line mode)", 0 },
+#endif
+    { "line",	"Enable LINEMODE option",	dolinemode, 1 },
+#ifdef	KLUDGELINEMODE
+    { "",	"(or enable obsolete line-by-line mode)", 0 },
+#endif
+    { "", "", 0 },
+    { "",	"These require the LINEMODE option to be enabled", 0 },
+    { "isig",	"Enable signal trapping",	setmode, 1, MODE_TRAPSIG },
+    { "+isig",	0,				setmode, 1, MODE_TRAPSIG },
+    { "-isig",	"Disable signal trapping",	clearmode, 1, MODE_TRAPSIG },
+    { "edit",	"Enable character editing",	setmode, 1, MODE_EDIT },
+    { "+edit",	0,				setmode, 1, MODE_EDIT },
+    { "-edit",	"Disable character editing",	clearmode, 1, MODE_EDIT },
+    { "softtabs", "Enable tab expansion",	setmode, 1, MODE_SOFT_TAB },
+    { "+softtabs", 0,				setmode, 1, MODE_SOFT_TAB },
+    { "-softtabs", "Disable character editing",	clearmode, 1, MODE_SOFT_TAB },
+    { "litecho", "Enable literal character echo", setmode, 1, MODE_LIT_ECHO },
+    { "+litecho", 0,				setmode, 1, MODE_LIT_ECHO },
+    { "-litecho", "Disable literal character echo", clearmode, 1, MODE_LIT_ECHO },
+    { "help",	0,				modehelp, 0 },
+#ifdef	KLUDGELINEMODE
+    { "kludgeline", 0,				dokludgemode, 1 },
+#endif
+    { "", "", 0 },
+    { "?",	"Print help information",	modehelp, 0 },
+    { 0 },
+};
+
+
+    int
+modehelp()
+{
+    struct modelist *mt;
+
+    printf("format is:  'mode Mode', where 'Mode' is one of:\n\n");
+    for (mt = ModeList; mt->name; mt++) {
+	if (mt->help) {
+	    if (*mt->help)
+		printf("%-15s %s\n", mt->name, mt->help);
+	    else
+		printf("\n");
+	}
+    }
+    return 0;
+}
+
+#define	GETMODECMD(name) (struct modelist *) \
+		genget(name, (char **) ModeList, sizeof(struct modelist))
+
+    static int
+modecmd(argc, argv)
+    int  argc;
+    char *argv[];
+{
+    struct modelist *mt;
+
+    if (argc != 2) {
+	printf("'mode' command requires an argument\n");
+	printf("'mode ?' for help.\n");
+    } else if ((mt = GETMODECMD(argv[1])) == 0) {
+	fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]);
+    } else if (Ambiguous(mt)) {
+	fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]);
+    } else if (mt->needconnect && !connected) {
+	printf("?Need to be connected first.\n");
+	printf("'mode ?' for help.\n");
+    } else if (mt->handler) {
+	return (*mt->handler)(mt->arg1);
+    }
+    return 0;
+}
+
+/*
+ * The following data structures and routines implement the
+ * "display" command.
+ */
+
+    static int
+display(argc, argv)
+    int  argc;
+    char *argv[];
+{
+    struct togglelist *tl;
+    struct setlist *sl;
+
+#define	dotog(tl)	if (tl->variable && tl->actionexplanation) { \
+			    if (*tl->variable) { \
+				printf("will"); \
+			    } else { \
+				printf("won't"); \
+			    } \
+			    printf(" %s.\n", tl->actionexplanation); \
+			}
+
+#define	doset(sl)   if (sl->name && *sl->name != ' ') { \
+			if (sl->handler == 0) \
+			    printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \
+			else \
+			    printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \
+		    }
+
+    if (argc == 1) {
+	for (tl = Togglelist; tl->name; tl++) {
+	    dotog(tl);
+	}
+	printf("\n");
+	for (sl = Setlist; sl->name; sl++) {
+	    doset(sl);
+	}
+    } else {
+	int i;
+
+	for (i = 1; i < argc; i++) {
+	    sl = getset(argv[i]);
+	    tl = GETTOGGLE(argv[i]);
+	    if (Ambiguous(sl) || Ambiguous(tl)) {
+		printf("?Ambiguous argument '%s'.\n", argv[i]);
+		return 0;
+	    } else if (!sl && !tl) {
+		printf("?Unknown argument '%s'.\n", argv[i]);
+		return 0;
+	    } else {
+		if (tl) {
+		    dotog(tl);
+		}
+		if (sl) {
+		    doset(sl);
+		}
+	    }
+	}
+    }
+/*@*/optionstatus();
+#ifdef	ENCRYPTION
+    EncryptStatus();
+#endif	/* ENCRYPTION */
+    return 1;
+#undef	doset
+#undef	dotog
+}
+
+/*
+ * The following are the data structures, and many of the routines,
+ * relating to command processing.
+ */
+
+/*
+ * Set the escape character.
+ */
+	static int
+setescape(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register char *arg;
+	char buf[50];
+
+	printf(
+	    "Deprecated usage - please use 'set escape%s%s' in the future.\n",
+				(argc > 2)? " ":"", (argc > 2)? argv[1]: "");
+	if (argc > 2)
+		arg = argv[1];
+	else {
+		printf("new escape character: ");
+		(void) fgets(buf, sizeof(buf), stdin);
+		arg = buf;
+	}
+	if (arg[0] != '\0')
+		escape = arg[0];
+	if (!In3270) {
+		printf("Escape character is '%s'.\n", control(escape));
+	}
+	(void) fflush(stdout);
+	return 1;
+}
+
+    /*VARARGS*/
+    static int
+togcrmod()
+{
+    crmod = !crmod;
+    printf("Deprecated usage - please use 'toggle crmod' in the future.\n");
+    printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't");
+    (void) fflush(stdout);
+    return 1;
+}
+
+    /*VARARGS*/
+    int
+suspend()
+{
+#ifdef	SIGTSTP
+    setcommandmode();
+    {
+	long oldrows, oldcols, newrows, newcols, err;
+
+	err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0;
+	(void) kill(0, SIGTSTP);
+	/*
+	 * If we didn't get the window size before the SUSPEND, but we
+	 * can get them now (?), then send the NAWS to make sure that
+	 * we are set up for the right window size.
+	 */
+	if (TerminalWindowSize(&newrows, &newcols) && connected &&
+	    (err || ((oldrows != newrows) || (oldcols != newcols)))) {
+		sendnaws();
+	}
+    }
+    /* reget parameters in case they were changed */
+    TerminalSaveState();
+    setconnmode(0);
+#else
+    printf("Suspend is not supported.  Try the '!' command instead\n");
+#endif
+    return 1;
+}
+
+#if	!defined(TN3270)
+    /*ARGSUSED*/
+    int
+shell(argc, argv)
+    int argc;
+    char *argv[];
+{
+    long oldrows, oldcols, newrows, newcols, err;
+
+    setcommandmode();
+
+    err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0;
+    switch(vfork()) {
+    case -1:
+	perror("Fork failed\n");
+	break;
+
+    case 0:
+	{
+	    /*
+	     * Fire up the shell in the child.
+	     */
+	    register char *shellp, *shellname;
+	    extern char *strrchr();
+
+	    shellp = getenv("SHELL");
+	    if (shellp == NULL)
+		shellp = "/bin/sh";
+	    if ((shellname = strrchr(shellp, '/')) == 0)
+		shellname = shellp;
+	    else
+		shellname++;
+	    if (argc > 1)
+		execl(shellp, shellname, "-c", &saveline[1], 0);
+	    else
+		execl(shellp, shellname, 0);
+	    perror("Execl");
+	    _exit(1);
+	}
+    default:
+	    (void)wait((int *)0);	/* Wait for the shell to complete */
+
+	    if (TerminalWindowSize(&newrows, &newcols) && connected &&
+		(err || ((oldrows != newrows) || (oldcols != newcols)))) {
+		    sendnaws();
+	    }
+	    break;
+    }
+    return 1;
+}
+#else	/* !defined(TN3270) */
+extern int shell();
+#endif	/* !defined(TN3270) */
+
+    /*VARARGS*/
+    static
+bye(argc, argv)
+    int  argc;		/* Number of arguments */
+    char *argv[];	/* arguments */
+{
+    extern int resettermname;
+
+    if (connected) {
+	(void) shutdown(net, 2);
+	printf("Connection closed.\n");
+	(void) NetClose(net);
+	connected = 0;
+	resettermname = 1;
+#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
+	auth_encrypt_connect(connected);
+#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION) */
+	/* reset options */
+	tninit();
+#if	defined(TN3270)
+	SetIn3270();		/* Get out of 3270 mode */
+#endif	/* defined(TN3270) */
+    }
+    if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) {
+	longjmp(toplevel, 1);
+	/* NOTREACHED */
+    }
+    return 1;			/* Keep lint, etc., happy */
+}
+
+/*VARARGS*/
+quit()
+{
+	(void) call(bye, "bye", "fromquit", 0);
+	Exit(0);
+	/*NOTREACHED*/
+}
+
+/*VARARGS*/
+	int
+logout()
+{
+	send_do(TELOPT_LOGOUT, 1);
+	(void) netflush();
+	return 1;
+}
+
+
+/*
+ * The SLC command.
+ */
+
+struct slclist {
+	char	*name;
+	char	*help;
+	void	(*handler)();
+	int	arg;
+};
+
+static void slc_help();
+
+struct slclist SlcList[] = {
+    { "export",	"Use local special character definitions",
+						slc_mode_export,	0 },
+    { "import",	"Use remote special character definitions",
+						slc_mode_import,	1 },
+    { "check",	"Verify remote special character definitions",
+						slc_mode_import,	0 },
+    { "help",	0,				slc_help,		0 },
+    { "?",	"Print help information",	slc_help,		0 },
+    { 0 },
+};
+
+    static void
+slc_help()
+{
+    struct slclist *c;
+
+    for (c = SlcList; c->name; c++) {
+	if (c->help) {
+	    if (*c->help)
+		printf("%-15s %s\n", c->name, c->help);
+	    else
+		printf("\n");
+	}
+    }
+}
+
+    static struct slclist *
+getslc(name)
+    char *name;
+{
+    return (struct slclist *)
+		genget(name, (char **) SlcList, sizeof(struct slclist));
+}
+
+    static
+slccmd(argc, argv)
+    int  argc;
+    char *argv[];
+{
+    struct slclist *c;
+
+    if (argc != 2) {
+	fprintf(stderr,
+	    "Need an argument to 'slc' command.  'slc ?' for help.\n");
+	return 0;
+    }
+    c = getslc(argv[1]);
+    if (c == 0) {
+	fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n",
+    				argv[1]);
+	return 0;
+    }
+    if (Ambiguous(c)) {
+	fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n",
+    				argv[1]);
+	return 0;
+    }
+    (*c->handler)(c->arg);
+    slcstate();
+    return 1;
+}
+
+/*
+ * The ENVIRON command.
+ */
+
+struct envlist {
+	char	*name;
+	char	*help;
+	void	(*handler)();
+	int	narg;
+};
+
+extern struct env_lst *
+	env_define P((unsigned char *, unsigned char *));
+extern void
+	env_undefine P((unsigned char *)),
+	env_export P((unsigned char *)),
+	env_unexport P((unsigned char *)),
+	env_send P((unsigned char *)),
+#if defined(OLD_ENVIRON) && defined(ENV_HACK)
+	env_varval P((unsigned char *)),
+#endif
+	env_list P((void));
+static void
+	env_help P((void));
+
+struct envlist EnvList[] = {
+    { "define",	"Define an environment variable",
+						(void (*)())env_define,	2 },
+    { "undefine", "Undefine an environment variable",
+						env_undefine,	1 },
+    { "export",	"Mark an environment variable for automatic export",
+						env_export,	1 },
+    { "unexport", "Don't mark an environment variable for automatic export",
+						env_unexport,	1 },
+    { "send",	"Send an environment variable", env_send,	1 },
+    { "list",	"List the current environment variables",
+						env_list,	0 },
+#if defined(OLD_ENVIRON) && defined(ENV_HACK)
+    { "varval", "Reverse VAR and VALUE (auto, right, wrong, status)",
+						env_varval,    1 },
+#endif
+    { "help",	0,				env_help,		0 },
+    { "?",	"Print help information",	env_help,		0 },
+    { 0 },
+};
+
+    static void
+env_help()
+{
+    struct envlist *c;
+
+    for (c = EnvList; c->name; c++) {
+	if (c->help) {
+	    if (*c->help)
+		printf("%-15s %s\n", c->name, c->help);
+	    else
+		printf("\n");
+	}
+    }
+}
+
+    static struct envlist *
+getenvcmd(name)
+    char *name;
+{
+    return (struct envlist *)
+		genget(name, (char **) EnvList, sizeof(struct envlist));
+}
+
+env_cmd(argc, argv)
+    int  argc;
+    char *argv[];
+{
+    struct envlist *c;
+
+    if (argc < 2) {
+	fprintf(stderr,
+	    "Need an argument to 'environ' command.  'environ ?' for help.\n");
+	return 0;
+    }
+    c = getenvcmd(argv[1]);
+    if (c == 0) {
+	fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n",
+    				argv[1]);
+	return 0;
+    }
+    if (Ambiguous(c)) {
+	fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n",
+    				argv[1]);
+	return 0;
+    }
+    if (c->narg + 2 != argc) {
+	fprintf(stderr,
+	    "Need %s%d argument%s to 'environ %s' command.  'environ ?' for help.\n",
+		c->narg < argc + 2 ? "only " : "",
+		c->narg, c->narg == 1 ? "" : "s", c->name);
+	return 0;
+    }
+    (*c->handler)(argv[2], argv[3]);
+    return 1;
+}
+
+struct env_lst {
+	struct env_lst *next;	/* pointer to next structure */
+	struct env_lst *prev;	/* pointer to previous structure */
+	unsigned char *var;	/* pointer to variable name */
+	unsigned char *value;	/* pointer to variable value */
+	int export;		/* 1 -> export with default list of variables */
+	int welldefined;	/* A well defined variable */
+};
+
+struct env_lst envlisthead;
+
+	struct env_lst *
+env_find(var)
+	unsigned char *var;
+{
+	register struct env_lst *ep;
+
+	for (ep = envlisthead.next; ep; ep = ep->next) {
+		if (strcmp((char *)ep->var, (char *)var) == 0)
+			return(ep);
+	}
+	return(NULL);
+}
+
+	void
+env_init()
+{
+	extern char **environ;
+	register char **epp, *cp;
+	register struct env_lst *ep;
+	extern char *strchr();
+
+	for (epp = environ; *epp; epp++) {
+		if (cp = strchr(*epp, '=')) {
+			*cp = '\0';
+			ep = env_define((unsigned char *)*epp,
+					(unsigned char *)cp+1);
+			ep->export = 0;
+			*cp = '=';
+		}
+	}
+	/*
+	 * Special case for DISPLAY variable.  If it is ":0.0" or
+	 * "unix:0.0", we have to get rid of "unix" and insert our
+	 * hostname.
+	 */
+	if ((ep = env_find("DISPLAY"))
+	    && ((*ep->value == ':')
+		|| (strncmp((char *)ep->value, "unix:", 5) == 0))) {
+		char hbuf[256+1];
+		char *cp2 = strchr((char *)ep->value, ':');
+
+		gethostname(hbuf, 256);
+		hbuf[256] = '\0';
+		cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1);
+		sprintf((char *)cp, "%s%s", hbuf, cp2);
+		free(ep->value);
+		ep->value = (unsigned char *)cp;
+	}
+	/*
+	 * If USER is not defined, but LOGNAME is, then add
+	 * USER with the value from LOGNAME.  By default, we
+	 * don't export the USER variable.
+	 */
+	if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) {
+		env_define((unsigned char *)"USER", ep->value);
+		env_unexport((unsigned char *)"USER");
+	}
+	env_export((unsigned char *)"DISPLAY");
+	env_export((unsigned char *)"PRINTER");
+}
+
+	struct env_lst *
+env_define(var, value)
+	unsigned char *var, *value;
+{
+	register struct env_lst *ep;
+
+	if (ep = env_find(var)) {
+		if (ep->var)
+			free(ep->var);
+		if (ep->value)
+			free(ep->value);
+	} else {
+		ep = (struct env_lst *)malloc(sizeof(struct env_lst));
+		ep->next = envlisthead.next;
+		envlisthead.next = ep;
+		ep->prev = &envlisthead;
+		if (ep->next)
+			ep->next->prev = ep;
+	}
+	ep->welldefined = opt_welldefined(var);
+	ep->export = 1;
+	ep->var = (unsigned char *)strdup((char *)var);
+	ep->value = (unsigned char *)strdup((char *)value);
+	return(ep);
+}
+
+	void
+env_undefine(var)
+	unsigned char *var;
+{
+	register struct env_lst *ep;
+
+	if (ep = env_find(var)) {
+		ep->prev->next = ep->next;
+		if (ep->next)
+			ep->next->prev = ep->prev;
+		if (ep->var)
+			free(ep->var);
+		if (ep->value)
+			free(ep->value);
+		free(ep);
+	}
+}
+
+	void
+env_export(var)
+	unsigned char *var;
+{
+	register struct env_lst *ep;
+
+	if (ep = env_find(var))
+		ep->export = 1;
+}
+
+	void
+env_unexport(var)
+	unsigned char *var;
+{
+	register struct env_lst *ep;
+
+	if (ep = env_find(var))
+		ep->export = 0;
+}
+
+	void
+env_send(var)
+	unsigned char *var;
+{
+	register struct env_lst *ep;
+
+	if (my_state_is_wont(TELOPT_NEW_ENVIRON)
+#ifdef	OLD_ENVIRON
+	    && my_state_is_wont(TELOPT_OLD_ENVIRON)
+#endif
+		) {
+		fprintf(stderr,
+		    "Cannot send '%s': Telnet ENVIRON option not enabled\n",
+									var);
+		return;
+	}
+	ep = env_find(var);
+	if (ep == 0) {
+		fprintf(stderr, "Cannot send '%s': variable not defined\n",
+									var);
+		return;
+	}
+	env_opt_start_info();
+	env_opt_add(ep->var);
+	env_opt_end(0);
+}
+
+	void
+env_list()
+{
+	register struct env_lst *ep;
+
+	for (ep = envlisthead.next; ep; ep = ep->next) {
+		printf("%c %-20s %s\n", ep->export ? '*' : ' ',
+					ep->var, ep->value);
+	}
+}
+
+	unsigned char *
+env_default(init, welldefined)
+	int init;
+{
+	static struct env_lst *nep = NULL;
+
+	if (init) {
+		nep = &envlisthead;
+		return;
+	}
+	if (nep) {
+		while (nep = nep->next) {
+			if (nep->export && (nep->welldefined == welldefined))
+				return(nep->var);
+		}
+	}
+	return(NULL);
+}
+
+	unsigned char *
+env_getvalue(var)
+	unsigned char *var;
+{
+	register struct env_lst *ep;
+
+	if (ep = env_find(var))
+		return(ep->value);
+	return(NULL);
+}
+
+#if defined(OLD_ENVIRON) && defined(ENV_HACK)
+	void
+env_varval(what)
+	unsigned char *what;
+{
+	extern int old_env_var, old_env_value, env_auto;
+	int len = strlen((char *)what);
+
+	if (len == 0)
+		goto unknown;
+
+	if (strncasecmp((char *)what, "status", len) == 0) {
+		if (env_auto)
+			printf("%s%s", "VAR and VALUE are/will be ",
+					"determined automatically\n");
+		if (old_env_var == OLD_ENV_VAR)
+			printf("VAR and VALUE set to correct definitions\n");
+		else
+			printf("VAR and VALUE definitions are reversed\n");
+	} else if (strncasecmp((char *)what, "auto", len) == 0) {
+		env_auto = 1;
+		old_env_var = OLD_ENV_VALUE;
+		old_env_value = OLD_ENV_VAR;
+	} else if (strncasecmp((char *)what, "right", len) == 0) {
+		env_auto = 0;
+		old_env_var = OLD_ENV_VAR;
+		old_env_value = OLD_ENV_VALUE;
+	} else if (strncasecmp((char *)what, "wrong", len) == 0) {
+		env_auto = 0;
+		old_env_var = OLD_ENV_VALUE;
+		old_env_value = OLD_ENV_VAR;
+	} else {
+unknown:
+		printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\n");
+	}
+}
+#endif
+
+#if	defined(AUTHENTICATION)
+/*
+ * The AUTHENTICATE command.
+ */
+
+struct authlist {
+	char	*name;
+	char	*help;
+	int	(*handler)();
+	int	narg;
+};
+
+extern int
+	auth_enable P((char *)),
+	auth_disable P((char *)),
+	auth_status P((void));
+static int
+	auth_help P((void));
+
+struct authlist AuthList[] = {
+    { "status",	"Display current status of authentication information",
+						auth_status,	0 },
+    { "disable", "Disable an authentication type ('auth disable ?' for more)",
+						auth_disable,	1 },
+    { "enable", "Enable an authentication type ('auth enable ?' for more)",
+						auth_enable,	1 },
+    { "help",	0,				auth_help,		0 },
+    { "?",	"Print help information",	auth_help,		0 },
+    { 0 },
+};
+
+    static int
+auth_help()
+{
+    struct authlist *c;
+
+    for (c = AuthList; c->name; c++) {
+	if (c->help) {
+	    if (*c->help)
+		printf("%-15s %s\n", c->name, c->help);
+	    else
+		printf("\n");
+	}
+    }
+    return 0;
+}
+
+auth_cmd(argc, argv)
+    int  argc;
+    char *argv[];
+{
+    struct authlist *c;
+
+    if (argc < 2) {
+	fprintf(stderr,
+	    "Need an argument to 'auth' command.  'auth ?' for help.\n");
+	return 0;
+    }
+
+    c = (struct authlist *)
+		genget(argv[1], (char **) AuthList, sizeof(struct authlist));
+    if (c == 0) {
+	fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n",
+    				argv[1]);
+	return 0;
+    }
+    if (Ambiguous(c)) {
+	fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n",
+    				argv[1]);
+	return 0;
+    }
+    if (c->narg + 2 != argc) {
+	fprintf(stderr,
+	    "Need %s%d argument%s to 'auth %s' command.  'auth ?' for help.\n",
+		c->narg < argc + 2 ? "only " : "",
+		c->narg, c->narg == 1 ? "" : "s", c->name);
+	return 0;
+    }
+    return((*c->handler)(argv[2], argv[3]));
+}
+#endif
+
+#ifdef	ENCRYPTION
+/*
+ * The ENCRYPT command.
+ */
+
+struct encryptlist {
+	char	*name;
+	char	*help;
+	int	(*handler)();
+	int	needconnect;
+	int	minarg;
+	int	maxarg;
+};
+
+extern int
+	EncryptEnable P((char *, char *)),
+	EncryptDisable P((char *, char *)),
+	EncryptType P((char *, char *)),
+	EncryptStart P((char *)),
+	EncryptStartInput P((void)),
+	EncryptStartOutput P((void)),
+	EncryptStop P((char *)),
+	EncryptStopInput P((void)),
+	EncryptStopOutput P((void)),
+	EncryptStatus P((void));
+static int
+	EncryptHelp P((void));
+
+struct encryptlist EncryptList[] = {
+    { "enable", "Enable encryption. ('encrypt enable ?' for more)",
+						EncryptEnable, 1, 1, 2 },
+    { "disable", "Disable encryption. ('encrypt enable ?' for more)",
+						EncryptDisable, 0, 1, 2 },
+    { "type", "Set encryption type. ('encrypt type ?' for more)",
+						EncryptType, 0, 1, 1 },
+    { "start", "Start encryption. ('encrypt start ?' for more)",
+						EncryptStart, 1, 0, 1 },
+    { "stop", "Stop encryption. ('encrypt stop ?' for more)",
+						EncryptStop, 1, 0, 1 },
+    { "input", "Start encrypting the input stream",
+						EncryptStartInput, 1, 0, 0 },
+    { "-input", "Stop encrypting the input stream",
+						EncryptStopInput, 1, 0, 0 },
+    { "output", "Start encrypting the output stream",
+						EncryptStartOutput, 1, 0, 0 },
+    { "-output", "Stop encrypting the output stream",
+						EncryptStopOutput, 1, 0, 0 },
+
+    { "status",	"Display current status of authentication information",
+						EncryptStatus,	0, 0, 0 },
+    { "help",	0,				EncryptHelp,	0, 0, 0 },
+    { "?",	"Print help information",	EncryptHelp,	0, 0, 0 },
+    { 0 },
+};
+
+    static int
+EncryptHelp()
+{
+    struct encryptlist *c;
+
+    for (c = EncryptList; c->name; c++) {
+	if (c->help) {
+	    if (*c->help)
+		printf("%-15s %s\n", c->name, c->help);
+	    else
+		printf("\n");
+	}
+    }
+    return 0;
+}
+
+encrypt_cmd(argc, argv)
+    int  argc;
+    char *argv[];
+{
+    struct encryptlist *c;
+
+    if (argc < 2) {
+	fprintf(stderr,
+	    "Need an argument to 'encrypt' command.  'encrypt ?' for help.\n");
+	return 0;
+    }
+
+    c = (struct encryptlist *)
+		genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist));
+    if (c == 0) {
+	fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n",
+    				argv[1]);
+	return 0;
+    }
+    if (Ambiguous(c)) {
+	fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n",
+    				argv[1]);
+	return 0;
+    }
+    argc -= 2;
+    if (argc < c->minarg || argc > c->maxarg) {
+	if (c->minarg == c->maxarg) {
+	    fprintf(stderr, "Need %s%d argument%s ",
+		c->minarg < argc ? "only " : "", c->minarg,
+		c->minarg == 1 ? "" : "s");
+	} else {
+	    fprintf(stderr, "Need %s%d-%d arguments ",
+		c->maxarg < argc ? "only " : "", c->minarg, c->maxarg);
+	}
+	fprintf(stderr, "to 'encrypt %s' command.  'encrypt ?' for help.\n",
+		c->name);
+	return 0;
+    }
+    if (c->needconnect && !connected) {
+	if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) {
+	    printf("?Need to be connected first.\n");
+	    return 0;
+	}
+    }
+    return ((*c->handler)(argc > 0 ? argv[2] : 0,
+			argc > 1 ? argv[3] : 0,
+			argc > 2 ? argv[4] : 0));
+}
+#endif	/* ENCRYPTION */
+
+#if	(defined(unix) || defined(__APPLE__)) && defined(TN3270)
+    static void
+filestuff(fd)
+    int fd;
+{
+    int res;
+
+#ifdef	F_GETOWN
+    setconnmode(0);
+    res = fcntl(fd, F_GETOWN, 0);
+    setcommandmode();
+
+    if (res == -1) {
+	perror("fcntl");
+	return;
+    }
+    printf("\tOwner is %d.\n", res);
+#endif
+
+    setconnmode(0);
+    res = fcntl(fd, F_GETFL, 0);
+    setcommandmode();
+
+    if (res == -1) {
+	perror("fcntl");
+	return;
+    }
+#ifdef notdef
+    printf("\tFlags are 0x%x: %s\n", res, decodeflags(res));
+#endif
+}
+#endif /* (defined(unix) || defined(__APPLE__)) && defined(TN3270) */
+
+/*
+ * Print status about the connection.
+ */
+    /*ARGSUSED*/
+    static
+status(argc, argv)
+    int	 argc;
+    char *argv[];
+{
+    if (connected) {
+	printf("Connected to %s.\n", hostname);
+	if ((argc < 2) || strcmp(argv[1], "notmuch")) {
+	    int mode = getconnmode();
+
+	    if (my_want_state_is_will(TELOPT_LINEMODE)) {
+		printf("Operating with LINEMODE option\n");
+		printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No");
+		printf("%s catching of signals\n",
+					(mode&MODE_TRAPSIG) ? "Local" : "No");
+		slcstate();
+#ifdef	KLUDGELINEMODE
+	    } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) {
+		printf("Operating in obsolete linemode\n");
+#endif
+	    } else {
+		printf("Operating in single character mode\n");
+		if (localchars)
+		    printf("Catching signals locally\n");
+	    }
+	    printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote");
+	    if (my_want_state_is_will(TELOPT_LFLOW))
+		printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No");
+#ifdef	ENCRYPTION
+	    encrypt_display();
+#endif	/* ENCRYPTION */
+	}
+    } else {
+	printf("No connection.\n");
+    }
+#   if !defined(TN3270)
+    printf("Escape character is '%s'.\n", control(escape));
+    (void) fflush(stdout);
+#   else /* !defined(TN3270) */
+    if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) {
+	printf("Escape character is '%s'.\n", control(escape));
+    }
+#   if defined(unix) || defined(__APPLE__)
+    if ((argc >= 2) && !strcmp(argv[1], "everything")) {
+	printf("SIGIO received %d time%s.\n",
+				sigiocount, (sigiocount == 1)? "":"s");
+	if (In3270) {
+	    printf("Process ID %d, process group %d.\n",
+					    getpid(), getpgrp(getpid()));
+	    printf("Terminal input:\n");
+	    filestuff(tin);
+	    printf("Terminal output:\n");
+	    filestuff(tout);
+	    printf("Network socket:\n");
+	    filestuff(net);
+	}
+    }
+    if (In3270 && transcom) {
+       printf("Transparent mode command is '%s'.\n", transcom);
+    }
+#   endif /* defined(unix) || defined(__APPLE__) */
+    (void) fflush(stdout);
+    if (In3270) {
+	return 0;
+    }
+#   endif /* defined(TN3270) */
+    return 1;
+}
+
+#ifdef	SIGINFO
+/*
+ * Function that gets called when SIGINFO is received.
+ */
+ayt_status()
+{
+    (void) call(status, "status", "notmuch", 0);
+}
+#endif
+
+unsigned long inet_addr();
+
+    int
+tn(argc, argv)
+    int argc;
+    char *argv[];
+{
+    register struct hostent *host = 0;
+    struct sockaddr_in sin;
+    struct servent *sp = 0;
+    unsigned long temp;
+    extern char *inet_ntoa();
+#if	defined(IP_OPTIONS) && defined(IPPROTO_IP)
+    char *srp = 0, *strrchr();
+    unsigned long sourceroute(), srlen;
+#endif
+    char *cmd, *hostp = 0, *portp = 0, *user = 0;
+
+    /* clear the socket address prior to use */
+    memset((char *)&sin, 0, sizeof(sin));
+
+    if (connected) {
+	printf("?Already connected to %s\n", hostname);
+	setuid(getuid());
+	return 0;
+    }
+    if (argc < 2) {
+	(void) strcpy(line, "open ");
+	printf("(to) ");
+	(void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin);
+	makeargv();
+	argc = margc;
+	argv = margv;
+    }
+    cmd = *argv;
+    --argc; ++argv;
+    while (argc) {
+	if (strcmp(*argv, "help") == 0 || isprefix(*argv, "?"))
+	    goto usage;
+	if (strcmp(*argv, "-l") == 0) {
+	    --argc; ++argv;
+	    if (argc == 0)
+		goto usage;
+	    user = *argv++;
+	    --argc;
+	    continue;
+	}
+	if (strcmp(*argv, "-a") == 0) {
+	    --argc; ++argv;
+	    autologin = 1;
+	    continue;
+	}
+	if (hostp == 0) {
+	    hostp = *argv++;
+	    --argc;
+	    continue;
+	}
+	if (portp == 0) {
+	    portp = *argv++;
+	    --argc;
+	    continue;
+	}
+    usage:
+	printf("usage: %s [-l user] [-a] host-name [port]\n", cmd);
+	setuid(getuid());
+	return 0;
+    }
+    if (hostp == 0)
+	goto usage;
+
+#if	defined(IP_OPTIONS) && defined(IPPROTO_IP)
+    if (hostp[0] == '@' || hostp[0] == '!') {
+	if ((hostname = strrchr(hostp, ':')) == NULL)
+	    hostname = strrchr(hostp, '@');
+	hostname++;
+	srp = 0;
+	temp = sourceroute(hostp, &srp, &srlen);
+	if (temp == 0) {
+	    herror(srp);
+	    setuid(getuid());
+	    return 0;
+	} else if (temp == -1) {
+	    printf("Bad source route option: %s\n", hostp);
+	    setuid(getuid());
+	    return 0;
+	} else {
+	    sin.sin_addr.s_addr = temp;
+	    sin.sin_family = AF_INET;
+	}
+    } else {
+#endif
+	temp = inet_addr(hostp);
+	if (temp != (unsigned long) -1) {
+	    sin.sin_addr.s_addr = temp;
+	    sin.sin_family = AF_INET;
+	    (void) strcpy(_hostname, hostp);
+	    hostname = _hostname;
+	} else {
+	    host = gethostbyname(hostp);
+	    if (host) {
+		sin.sin_family = host->h_addrtype;
+#if	defined(h_addr)		/* In 4.3, this is a #define */
+		memmove((caddr_t)&sin.sin_addr,
+				host->h_addr_list[0], host->h_length);
+#else	/* defined(h_addr) */
+		memmove((caddr_t)&sin.sin_addr, host->h_addr, host->h_length);
+#endif	/* defined(h_addr) */
+		strncpy(_hostname, host->h_name, sizeof(_hostname));
+		_hostname[sizeof(_hostname)-1] = '\0';
+		hostname = _hostname;
+	    } else {
+		herror(hostp);
+		setuid(getuid());
+		return 0;
+	    }
+	}
+#if	defined(IP_OPTIONS) && defined(IPPROTO_IP)
+    }
+#endif
+    if (portp) {
+	if (*portp == '-') {
+	    portp++;
+	    telnetport = 1;
+	} else
+	    telnetport = 0;
+	sin.sin_port = atoi(portp);
+	if (sin.sin_port == 0) {
+	    sp = getservbyname(portp, "tcp");
+	    if (sp)
+		sin.sin_port = sp->s_port;
+	    else {
+		printf("%s: bad port number\n", portp);
+		setuid(getuid());
+		return 0;
+	    }
+	} else {
+#if	!defined(htons)
+	    u_short htons P((unsigned short));
+#endif	/* !defined(htons) */
+	    sin.sin_port = htons(sin.sin_port);
+	}
+    } else {
+	if (sp == 0) {
+	    sp = getservbyname("telnet", "tcp");
+	    if (sp == 0) {
+		fprintf(stderr, "telnet: tcp/telnet: unknown service\n");
+		setuid(getuid());
+		return 0;
+	    }
+	    sin.sin_port = sp->s_port;
+	}
+	telnetport = 1;
+    }
+    printf("Trying %s...\n", inet_ntoa(sin.sin_addr));
+    do {
+	net = socket(AF_INET, SOCK_STREAM, 0);
+	setuid(getuid());
+	if (net < 0) {
+	    perror("telnet: socket");
+	    return 0;
+	}
+#if	defined(IP_OPTIONS) && defined(IPPROTO_IP)
+	if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0)
+		perror("setsockopt (IP_OPTIONS)");
+#endif
+#if	defined(IPPROTO_IP) && defined(IP_TOS)
+	{
+# if	defined(HAS_GETTOS)
+	    struct tosent *tp;
+	    if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
+		tos = tp->t_tos;
+# endif
+	    if (tos < 0)
+		tos = 020;	/* Low Delay bit */
+	    if (tos
+		&& (setsockopt(net, IPPROTO_IP, IP_TOS,
+		    (char *)&tos, sizeof(int)) < 0)
+		&& (errno != ENOPROTOOPT))
+		    perror("telnet: setsockopt (IP_TOS) (ignored)");
+	}
+#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */
+
+	if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) {
+		perror("setsockopt (SO_DEBUG)");
+	}
+
+	if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
+#if	defined(h_addr)		/* In 4.3, this is a #define */
+	    if (host && host->h_addr_list[1]) {
+		int oerrno = errno;
+
+		fprintf(stderr, "telnet: connect to address %s: ",
+						inet_ntoa(sin.sin_addr));
+		errno = oerrno;
+		perror((char *)0);
+		host->h_addr_list++;
+		memmove((caddr_t)&sin.sin_addr,
+			host->h_addr_list[0], host->h_length);
+		(void) NetClose(net);
+		continue;
+	    }
+#endif	/* defined(h_addr) */
+	    perror("telnet: Unable to connect to remote host");
+	    return 0;
+	}
+	connected++;
+#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
+	auth_encrypt_connect(connected);
+#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION) */
+    } while (connected == 0);
+    cmdrc(hostp, hostname);
+    if (autologin && user == NULL) {
+	struct passwd *pw;
+
+	user = getenv("USER");
+	if (user == NULL ||
+	    (pw = getpwnam(user)) && pw->pw_uid != getuid()) {
+		if (pw = getpwuid(getuid()))
+			user = pw->pw_name;
+		else
+			user = NULL;
+	}
+    }
+    if (user) {
+	env_define((unsigned char *)"USER", (unsigned char *)user);
+	env_export((unsigned char *)"USER");
+    }
+    (void) call(status, "status", "notmuch", 0);
+    if (setjmp(peerdied) == 0)
+	telnet(user);
+    (void) NetClose(net);
+    ExitString("Connection closed by foreign host.\n",1);
+    /*NOTREACHED*/
+}
+
+#define HELPINDENT (sizeof ("connect"))
+
+static char
+	openhelp[] =	"connect to a site",
+	closehelp[] =	"close current connection",
+	logouthelp[] =	"forcibly logout remote user and close the connection",
+	quithelp[] =	"exit telnet",
+	statushelp[] =	"print status information",
+	helphelp[] =	"print help information",
+	sendhelp[] =	"transmit special characters ('send ?' for more)",
+	sethelp[] = 	"set operating parameters ('set ?' for more)",
+	unsethelp[] = 	"unset operating parameters ('unset ?' for more)",
+	togglestring[] ="toggle operating parameters ('toggle ?' for more)",
+	slchelp[] =	"change state of special charaters ('slc ?' for more)",
+	displayhelp[] =	"display operating parameters",
+#if	defined(TN3270) && (defined(unix) || defined(__APPLE__))
+	transcomhelp[] = "specify Unix command for transparent mode pipe",
+#endif	/* defined(TN3270) && (defined(unix) || defined(__APPLE__)) */
+#if	defined(AUTHENTICATION)
+	authhelp[] =	"turn on (off) authentication ('auth ?' for more)",
+#endif
+#ifdef	ENCRYPTION
+	encrypthelp[] =	"turn on (off) encryption ('encrypt ?' for more)",
+#endif	/* ENCRYPTION */
+#if	defined(unix) || defined(__APPLE__)
+	zhelp[] =	"suspend telnet",
+#endif	/* defined(unix) || defined(__APPLE__) */
+	shellhelp[] =	"invoke a subshell",
+	envhelp[] =	"change environment variables ('environ ?' for more)",
+	modestring[] = "try to enter line or character mode ('mode ?' for more)";
+
+static int	help();
+
+static Command cmdtab[] = {
+	{ "close",	closehelp,	bye,		1 },
+	{ "logout",	logouthelp,	logout,		1 },
+	{ "display",	displayhelp,	display,	0 },
+	{ "mode",	modestring,	modecmd,	0 },
+	{ "open",	openhelp,	tn,		0 },
+	{ "quit",	quithelp,	quit,		0 },
+	{ "send",	sendhelp,	sendcmd,	0 },
+	{ "set",	sethelp,	setcmd,		0 },
+	{ "unset",	unsethelp,	unsetcmd,	0 },
+	{ "status",	statushelp,	status,		0 },
+	{ "toggle",	togglestring,	toggle,		0 },
+	{ "slc",	slchelp,	slccmd,		0 },
+#if	defined(TN3270) && (defined(unix) || defined(__APPLE__))
+	{ "transcom",	transcomhelp,	settranscom,	0 },
+#endif	/* defined(TN3270) && (defined(unix) || defined(__APPLE__)) */
+#if	defined(AUTHENTICATION)
+	{ "auth",	authhelp,	auth_cmd,	0 },
+#endif
+#ifdef	ENCRYPTION
+	{ "encrypt",	encrypthelp,	encrypt_cmd,	0 },
+#endif	/* ENCRYPTION */
+#if	defined(unix) || defined(__APPLE__)
+	{ "z",		zhelp,		suspend,	0 },
+#endif	/* defined(unix) || defined(__APPLE__) */
+#if	defined(TN3270)
+	{ "!",		shellhelp,	shell,		1 },
+#else
+	{ "!",		shellhelp,	shell,		0 },
+#endif
+	{ "environ",	envhelp,	env_cmd,	0 },
+	{ "?",		helphelp,	help,		0 },
+	{ 0 }
+};
+
+static char	crmodhelp[] =	"deprecated command -- use 'toggle crmod' instead";
+static char	escapehelp[] =	"deprecated command -- use 'set escape' instead";
+
+static Command cmdtab2[] = {
+	{ "help",	0,		help,		0 },
+	{ "escape",	escapehelp,	setescape,	0 },
+	{ "crmod",	crmodhelp,	togcrmod,	0 },
+	{ 0 }
+};
+
+
+/*
+ * Call routine with argc, argv set from args (terminated by 0).
+ */
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+
+    /*VARARGS1*/
+    static
+#if __STDC__
+call(intrtn_t routine, ...)
+{
+#else
+call(va_alist)
+    va_dcl
+{
+    intrtn_t routine;
+#endif
+    va_list ap;
+    char *args[100];
+    int argno = 0;
+
+#if __STDC__
+    va_start(ap, routine);
+#else
+    va_start(ap);
+    routine = (va_arg(ap, intrtn_t));
+#endif
+    while ((args[argno++] = va_arg(ap, char *)) != 0) {
+	;
+    }
+    va_end(ap);
+    return (*routine)(argno-1, args);
+}
+
+
+    static Command *
+getcmd(name)
+    char *name;
+{
+    Command *cm;
+
+    if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command)))
+	return cm;
+    return (Command *) genget(name, (char **) cmdtab2, sizeof(Command));
+}
+
+    void
+command(top, tbuf, cnt)
+    int top;
+    char *tbuf;
+    int cnt;
+{
+    register Command *c;
+
+    setcommandmode();
+    if (!top) {
+	putchar('\n');
+#if	defined(unix) || defined(__APPLE__)
+    } else {
+	(void) signal(SIGINT, SIG_DFL);
+	(void) signal(SIGQUIT, SIG_DFL);
+#endif	/* defined(unix) || defined(__APPLE__) */
+    }
+    for (;;) {
+	if (rlogin == _POSIX_VDISABLE)
+		printf("%s> ", prompt);
+	if (tbuf) {
+	    register char *cp;
+	    cp = line;
+	    while (cnt > 0 && (*cp++ = *tbuf++) != '\n')
+		cnt--;
+	    tbuf = 0;
+	    if (cp == line || *--cp != '\n' || cp == line)
+		goto getline;
+	    *cp = '\0';
+	    if (rlogin == _POSIX_VDISABLE)
+		printf("%s\n", line);
+	} else {
+	getline:
+	    if (rlogin != _POSIX_VDISABLE)
+		printf("%s> ", prompt);
+	    if (fgets(line, sizeof(line), stdin) == NULL) {
+		if (feof(stdin) || ferror(stdin)) {
+		    (void) quit();
+		    /*NOTREACHED*/
+		}
+		break;
+	    }
+	}
+	if (line[0] == 0)
+	    break;
+	makeargv();
+	if (margv[0] == 0) {
+	    break;
+	}
+	c = getcmd(margv[0]);
+	if (Ambiguous(c)) {
+	    printf("?Ambiguous command\n");
+	    continue;
+	}
+	if (c == 0) {
+	    printf("?Invalid command\n");
+	    continue;
+	}
+	if (c->needconnect && !connected) {
+	    printf("?Need to be connected first.\n");
+	    continue;
+	}
+	if ((*c->handler)(margc, margv)) {
+	    break;
+	}
+    }
+    if (!top) {
+	if (!connected) {
+	    longjmp(toplevel, 1);
+	    /*NOTREACHED*/
+	}
+#if	defined(TN3270)
+	if (shell_active == 0) {
+	    setconnmode(0);
+	}
+#else	/* defined(TN3270) */
+	setconnmode(0);
+#endif	/* defined(TN3270) */
+    }
+}
+
+/*
+ * Help command.
+ */
+	static
+help(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register Command *c;
+
+	if (argc == 1) {
+		printf("Commands may be abbreviated.  Commands are:\n\n");
+		for (c = cmdtab; c->name; c++)
+			if (c->help) {
+				printf("%-*s\t%s\n", HELPINDENT, c->name,
+								    c->help);
+			}
+		return 0;
+	}
+	while (--argc > 0) {
+		register char *arg;
+		arg = *++argv;
+		c = getcmd(arg);
+		if (Ambiguous(c))
+			printf("?Ambiguous help command %s\n", arg);
+		else if (c == (Command *)0)
+			printf("?Invalid help command %s\n", arg);
+		else
+			printf("%s\n", c->help);
+	}
+	return 0;
+}
+
+static char *rcname = 0;
+static char rcbuf[128];
+
+cmdrc(m1, m2)
+	char *m1, *m2;
+{
+    register Command *c;
+    FILE *rcfile;
+    int gotmachine = 0;
+    int l1 = strlen(m1);
+    int l2 = strlen(m2);
+    char m1save[64];
+
+    if (skiprc)
+	return;
+
+    strcpy(m1save, m1);
+    m1 = m1save;
+
+    if (rcname == 0) {
+	rcname = getenv("HOME");
+	if (rcname)
+	    strcpy(rcbuf, rcname);
+	else
+	    rcbuf[0] = '\0';
+	strcat(rcbuf, "/.telnetrc");
+	rcname = rcbuf;
+    }
+
+    if ((rcfile = fopen(rcname, "r")) == 0) {
+	return;
+    }
+
+    for (;;) {
+	if (fgets(line, sizeof(line), rcfile) == NULL)
+	    break;
+	if (line[0] == 0)
+	    break;
+	if (line[0] == '#')
+	    continue;
+	if (gotmachine) {
+	    if (!isspace(line[0]))
+		gotmachine = 0;
+	}
+	if (gotmachine == 0) {
+	    if (isspace(line[0]))
+		continue;
+	    if (strncasecmp(line, m1, l1) == 0)
+		strncpy(line, &line[l1], sizeof(line) - l1);
+	    else if (strncasecmp(line, m2, l2) == 0)
+		strncpy(line, &line[l2], sizeof(line) - l2);
+	    else if (strncasecmp(line, "DEFAULT", 7) == 0)
+		strncpy(line, &line[7], sizeof(line) - 7);
+	    else
+		continue;
+	    if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n')
+		continue;
+	    gotmachine = 1;
+	}
+	makeargv();
+	if (margv[0] == 0)
+	    continue;
+	c = getcmd(margv[0]);
+	if (Ambiguous(c)) {
+	    printf("?Ambiguous command: %s\n", margv[0]);
+	    continue;
+	}
+	if (c == 0) {
+	    printf("?Invalid command: %s\n", margv[0]);
+	    continue;
+	}
+	/*
+	 * This should never happen...
+	 */
+	if (c->needconnect && !connected) {
+	    printf("?Need to be connected first for %s.\n", margv[0]);
+	    continue;
+	}
+	(*c->handler)(margc, margv);
+    }
+    fclose(rcfile);
+}
+
+#if	defined(IP_OPTIONS) && defined(IPPROTO_IP)
+
+/*
+ * Source route is handed in as
+ *	[!]@hop1@hop2...[@|:]dst
+ * If the leading ! is present, it is a
+ * strict source route, otherwise it is
+ * assmed to be a loose source route.
+ *
+ * We fill in the source route option as
+ *	hop1,hop2,hop3...dest
+ * and return a pointer to hop1, which will
+ * be the address to connect() to.
+ *
+ * Arguments:
+ *	arg:	pointer to route list to decipher
+ *
+ *	cpp: 	If *cpp is not equal to NULL, this is a
+ *		pointer to a pointer to a character array
+ *		that should be filled in with the option.
+ *
+ *	lenp:	pointer to an integer that contains the
+ *		length of *cpp if *cpp != NULL.
+ *
+ * Return values:
+ *
+ *	Returns the address of the host to connect to.  If the
+ *	return value is -1, there was a syntax error in the
+ *	option, either unknown characters, or too many hosts.
+ *	If the return value is 0, one of the hostnames in the
+ *	path is unknown, and *cpp is set to point to the bad
+ *	hostname.
+ *
+ *	*cpp:	If *cpp was equal to NULL, it will be filled
+ *		in with a pointer to our static area that has
+ *		the option filled in.  This will be 32bit aligned.
+ *
+ *	*lenp:	This will be filled in with how long the option
+ *		pointed to by *cpp is.
+ *
+ */
+	unsigned long
+sourceroute(arg, cpp, lenp)
+	char	*arg;
+	char	**cpp;
+	int	*lenp;
+{
+	static char lsr[44];
+#ifdef	sysV88
+	static IOPTN ipopt;
+#endif
+	char *cp, *cp2, *lsrp, *lsrep;
+	register int tmp;
+	struct in_addr sin_addr;
+	register struct hostent *host = 0;
+	register char c;
+
+	/*
+	 * Verify the arguments, and make sure we have
+	 * at least 7 bytes for the option.
+	 */
+	if (cpp == NULL || lenp == NULL)
+		return((unsigned long)-1);
+	if (*cpp != NULL && *lenp < 7)
+		return((unsigned long)-1);
+	/*
+	 * Decide whether we have a buffer passed to us,
+	 * or if we need to use our own static buffer.
+	 */
+	if (*cpp) {
+		lsrp = *cpp;
+		lsrep = lsrp + *lenp;
+	} else {
+		*cpp = lsrp = lsr;
+		lsrep = lsrp + 44;
+	}
+
+	cp = arg;
+
+	/*
+	 * Next, decide whether we have a loose source
+	 * route or a strict source route, and fill in
+	 * the begining of the option.
+	 */
+#ifndef	sysV88
+	if (*cp == '!') {
+		cp++;
+		*lsrp++ = IPOPT_SSRR;
+	} else
+		*lsrp++ = IPOPT_LSRR;
+#else
+	if (*cp == '!') {
+		cp++;
+		ipopt.io_type = IPOPT_SSRR;
+	} else
+		ipopt.io_type = IPOPT_LSRR;
+#endif
+
+	if (*cp != '@')
+		return((unsigned long)-1);
+
+#ifndef	sysV88
+	lsrp++;		/* skip over length, we'll fill it in later */
+	*lsrp++ = 4;
+#endif
+
+	cp++;
+
+	sin_addr.s_addr = 0;
+
+	for (c = 0;;) {
+		if (c == ':')
+			cp2 = 0;
+		else for (cp2 = cp; c = *cp2; cp2++) {
+			if (c == ',') {
+				*cp2++ = '\0';
+				if (*cp2 == '@')
+					cp2++;
+			} else if (c == '@') {
+				*cp2++ = '\0';
+			} else if (c == ':') {
+				*cp2++ = '\0';
+			} else
+				continue;
+			break;
+		}
+		if (!c)
+			cp2 = 0;
+
+		if ((tmp = inet_addr(cp)) != -1) {
+			sin_addr.s_addr = tmp;
+		} else if (host = gethostbyname(cp)) {
+#if	defined(h_addr)
+			memmove((caddr_t)&sin_addr,
+				host->h_addr_list[0], host->h_length);
+#else
+			memmove((caddr_t)&sin_addr, host->h_addr, host->h_length);
+#endif
+		} else {
+			*cpp = cp;
+			return(0);
+		}
+		memmove(lsrp, (char *)&sin_addr, 4);
+		lsrp += 4;
+		if (cp2)
+			cp = cp2;
+		else
+			break;
+		/*
+		 * Check to make sure there is space for next address
+		 */
+		if (lsrp + 4 > lsrep)
+			return((unsigned long)-1);
+	}
+#ifndef	sysV88
+	if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) {
+		*cpp = 0;
+		*lenp = 0;
+		return((unsigned long)-1);
+	}
+	*lsrp++ = IPOPT_NOP; /* 32 bit word align it */
+	*lenp = lsrp - *cpp;
+#else
+	ipopt.io_len = lsrp - *cpp;
+	if (ipopt.io_len <= 5) {		/* Is 3 better ? */
+		*cpp = 0;
+		*lenp = 0;
+		return((unsigned long)-1);
+	}
+	*lenp = sizeof(ipopt);
+	*cpp = (char *) &ipopt;
+#endif
+	return(sin_addr.s_addr);
+}
+#endif
diff --git a/telnet.tproj/defines.h b/telnet.tproj/defines.h
new file mode 100644
index 0000000..51a9283
--- /dev/null
+++ b/telnet.tproj/defines.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defines.h	8.1 (Berkeley) 6/6/93
+ */
+
+#define	settimer(x)	clocks.x = clocks.system++
+
+#if	!defined(TN3270)
+
+#define	SetIn3270()
+
+#endif	/* !defined(TN3270) */
+
+#define	NETADD(c)	{ *netoring.supply = c; ring_supplied(&netoring, 1); }
+#define	NET2ADD(c1,c2)	{ NETADD(c1); NETADD(c2); }
+#define	NETBYTES()	(ring_full_count(&netoring))
+#define	NETROOM()	(ring_empty_count(&netoring))
+
+#define	TTYADD(c)	if (!(SYNCHing||flushout)) { \
+				*ttyoring.supply = c; \
+				ring_supplied(&ttyoring, 1); \
+			}
+#define	TTYBYTES()	(ring_full_count(&ttyoring))
+#define	TTYROOM()	(ring_empty_count(&ttyoring))
+
+/*	Various modes */
+#define	MODE_LOCAL_CHARS(m)	((m)&(MODE_EDIT|MODE_TRAPSIG))
+#define	MODE_LOCAL_ECHO(m)	((m)&MODE_ECHO)
+#define	MODE_COMMAND_LINE(m)	((m)==-1)
+
+#define	CONTROL(x)	((x)&0x1f)		/* CTRL(x) is not portable */
diff --git a/telnet.tproj/externs.h b/telnet.tproj/externs.h
new file mode 100644
index 0000000..006efac
--- /dev/null
+++ b/telnet.tproj/externs.h
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)externs.h	8.3 (Berkeley) 5/30/95
+ */
+
+#ifndef	BSD
+# define BSD 43
+#endif
+
+/*
+ * ucb stdio.h defines BSD as something wierd
+ */
+#if defined(sun) && defined(__svr4__)
+#define BSD 43
+#endif
+
+#ifndef	USE_TERMIO
+# if BSD > 43 || defined(SYSV_TERMIO)
+#  define USE_TERMIO
+# endif
+#endif
+
+#include <stdio.h>
+#include <setjmp.h>
+#if defined(CRAY) && !defined(NO_BSD_SETJMP)
+#include <bsdsetjmp.h>
+#endif
+#ifndef	FILIO_H
+#include <sys/ioctl.h>
+#else
+#include <sys/filio.h>
+#endif
+#ifdef CRAY
+# include <errno.h>
+#endif /* CRAY */
+#ifdef	USE_TERMIO
+# ifndef	VINTR
+#  ifdef SYSV_TERMIO
+#   include <sys/termio.h>
+#  else
+#   include <sys/termios.h>
+#   define termio termios
+#  endif
+# endif
+#endif
+#if defined(NO_CC_T) || !defined(USE_TERMIO)
+# if !defined(USE_TERMIO)
+typedef char cc_t;
+# else
+typedef unsigned char cc_t;
+# endif
+#endif
+
+#ifndef	NO_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#ifndef	_POSIX_VDISABLE
+# ifdef sun
+#  include <sys/param.h>	/* pick up VDISABLE definition, mayby */
+# endif
+# ifdef VDISABLE
+#  define _POSIX_VDISABLE VDISABLE
+# else
+#  define _POSIX_VDISABLE ((cc_t)'\377')
+# endif
+#endif
+
+#define	SUBBUFSIZE	256
+
+#ifndef CRAY
+extern int errno;		/* outside this world */
+#endif /* !CRAY */
+
+#if	!defined(P)
+# ifdef	__STDC__
+#  define	P(x)	x
+# else
+#  define	P(x)	()
+# endif
+#endif
+
+extern int
+    autologin,		/* Autologin enabled */
+    skiprc,		/* Don't process the ~/.telnetrc file */
+    eight,		/* use eight bit mode (binary in and/or out */
+    flushout,		/* flush output */
+    connected,		/* Are we connected to the other side? */
+    globalmode,		/* Mode tty should be in */
+    In3270,		/* Are we in 3270 mode? */
+    telnetport,		/* Are we connected to the telnet port? */
+    localflow,		/* Flow control handled locally */
+    restartany,		/* If flow control, restart output on any character */
+    localchars,		/* we recognize interrupt/quit */
+    donelclchars,	/* the user has set "localchars" */
+    showoptions,
+    net,		/* Network file descriptor */
+    tin,		/* Terminal input file descriptor */
+    tout,		/* Terminal output file descriptor */
+    crlf,		/* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */
+    autoflush,		/* flush output when interrupting? */
+    autosynch,		/* send interrupt characters with SYNCH? */
+    SYNCHing,		/* Is the stream in telnet SYNCH mode? */
+    donebinarytoggle,	/* the user has put us in binary */
+    dontlecho,		/* do we suppress local echoing right now? */
+    crmod,
+    netdata,		/* Print out network data flow */
+    prettydump,		/* Print "netdata" output in user readable format */
+#if	defined(unix) || defined(__APPLE__)
+#if	defined(TN3270)
+    cursesdata,		/* Print out curses data flow */
+    apitrace,		/* Trace API transactions */
+#endif	/* defined(TN3270) */
+    termdata,		/* Print out terminal data flow */
+#endif	/* defined(unix) || defined(__APPLE__) */
+    debug;		/* Debug level */
+
+extern cc_t escape;	/* Escape to command mode */
+extern cc_t rlogin;	/* Rlogin mode escape character */
+#ifdef	KLUDGELINEMODE
+extern cc_t echoc;	/* Toggle local echoing */
+#endif
+
+extern char
+    *prompt;		/* Prompt for command. */
+
+extern char
+    doopt[],
+    dont[],
+    will[],
+    wont[],
+    options[],		/* All the little options */
+    *hostname;		/* Who are we connected to? */
+#ifdef	ENCRYPTION
+extern void (*encrypt_output) P((unsigned char *, int));
+extern int (*decrypt_input) P((int));
+#endif	/* ENCRYPTION */
+
+/*
+ * We keep track of each side of the option negotiation.
+ */
+
+#define	MY_STATE_WILL		0x01
+#define	MY_WANT_STATE_WILL	0x02
+#define	MY_STATE_DO		0x04
+#define	MY_WANT_STATE_DO	0x08
+
+/*
+ * Macros to check the current state of things
+ */
+
+#define	my_state_is_do(opt)		(options[opt]&MY_STATE_DO)
+#define	my_state_is_will(opt)		(options[opt]&MY_STATE_WILL)
+#define my_want_state_is_do(opt)	(options[opt]&MY_WANT_STATE_DO)
+#define my_want_state_is_will(opt)	(options[opt]&MY_WANT_STATE_WILL)
+
+#define	my_state_is_dont(opt)		(!my_state_is_do(opt))
+#define	my_state_is_wont(opt)		(!my_state_is_will(opt))
+#define my_want_state_is_dont(opt)	(!my_want_state_is_do(opt))
+#define my_want_state_is_wont(opt)	(!my_want_state_is_will(opt))
+
+#define	set_my_state_do(opt)		{options[opt] |= MY_STATE_DO;}
+#define	set_my_state_will(opt)		{options[opt] |= MY_STATE_WILL;}
+#define	set_my_want_state_do(opt)	{options[opt] |= MY_WANT_STATE_DO;}
+#define	set_my_want_state_will(opt)	{options[opt] |= MY_WANT_STATE_WILL;}
+
+#define	set_my_state_dont(opt)		{options[opt] &= ~MY_STATE_DO;}
+#define	set_my_state_wont(opt)		{options[opt] &= ~MY_STATE_WILL;}
+#define	set_my_want_state_dont(opt)	{options[opt] &= ~MY_WANT_STATE_DO;}
+#define	set_my_want_state_wont(opt)	{options[opt] &= ~MY_WANT_STATE_WILL;}
+
+/*
+ * Make everything symetrical
+ */
+
+#define	HIS_STATE_WILL			MY_STATE_DO
+#define	HIS_WANT_STATE_WILL		MY_WANT_STATE_DO
+#define HIS_STATE_DO			MY_STATE_WILL
+#define HIS_WANT_STATE_DO		MY_WANT_STATE_WILL
+
+#define	his_state_is_do			my_state_is_will
+#define	his_state_is_will		my_state_is_do
+#define his_want_state_is_do		my_want_state_is_will
+#define his_want_state_is_will		my_want_state_is_do
+
+#define	his_state_is_dont		my_state_is_wont
+#define	his_state_is_wont		my_state_is_dont
+#define his_want_state_is_dont		my_want_state_is_wont
+#define his_want_state_is_wont		my_want_state_is_dont
+
+#define	set_his_state_do		set_my_state_will
+#define	set_his_state_will		set_my_state_do
+#define	set_his_want_state_do		set_my_want_state_will
+#define	set_his_want_state_will		set_my_want_state_do
+
+#define	set_his_state_dont		set_my_state_wont
+#define	set_his_state_wont		set_my_state_dont
+#define	set_his_want_state_dont		set_my_want_state_wont
+#define	set_his_want_state_wont		set_my_want_state_dont
+
+
+extern FILE
+    *NetTrace;		/* Where debugging output goes */
+extern unsigned char
+    NetTraceFile[];	/* Name of file where debugging output goes */
+extern void
+    SetNetTrace P((char *));	/* Function to change where debugging goes */
+
+extern jmp_buf
+    peerdied,
+    toplevel;		/* For error conditions. */
+
+extern void
+    command P((int, char *, int)),
+    Dump P((int, unsigned char *, int)),
+    init_3270 P((void)),
+    printoption P((char *, int, int)),
+    printsub P((int, unsigned char *, int)),
+    sendnaws P((void)),
+    setconnmode P((int)),
+    setcommandmode P((void)),
+    setneturg P((void)),
+    sys_telnet_init P((void)),
+    telnet P((char *)),
+    tel_enter_binary P((int)),
+    TerminalFlushOutput P((void)),
+    TerminalNewMode P((int)),
+    TerminalRestoreState P((void)),
+    TerminalSaveState P((void)),
+    tninit P((void)),
+    upcase P((char *)),
+    willoption P((int)),
+    wontoption P((int));
+
+extern void
+    send_do P((int, int)),
+    send_dont P((int, int)),
+    send_will P((int, int)),
+    send_wont P((int, int));
+
+extern void
+    lm_will P((unsigned char *, int)),
+    lm_wont P((unsigned char *, int)),
+    lm_do P((unsigned char *, int)),
+    lm_dont P((unsigned char *, int)),
+    lm_mode P((unsigned char *, int, int));
+
+extern void
+    slc_init P((void)),
+    slcstate P((void)),
+    slc_mode_export P((void)),
+    slc_mode_import P((int)),
+    slc_import P((int)),
+    slc_export P((void)),
+    slc P((unsigned char *, int)),
+    slc_check P((void)),
+    slc_start_reply P((void)),
+    slc_add_reply P((int, int, int)),
+    slc_end_reply P((void));
+extern int
+    slc_update P((void));
+
+extern void
+    env_opt P((unsigned char *, int)),
+    env_opt_start P((void)),
+    env_opt_start_info P((void)),
+    env_opt_add P((unsigned char *)),
+    env_opt_end P((int));
+
+extern unsigned char
+    *env_default P((int, int)),
+    *env_getvalue P((unsigned char *));
+
+extern int
+    get_status P((void)),
+    dosynch P((void));
+
+extern cc_t
+    *tcval P((int));
+
+#ifndef	USE_TERMIO
+
+extern struct	tchars ntc;
+extern struct	ltchars nltc;
+extern struct	sgttyb nttyb;
+
+# define termEofChar		ntc.t_eofc
+# define termEraseChar		nttyb.sg_erase
+# define termFlushChar		nltc.t_flushc
+# define termIntChar		ntc.t_intrc
+# define termKillChar		nttyb.sg_kill
+# define termLiteralNextChar	nltc.t_lnextc
+# define termQuitChar		ntc.t_quitc
+# define termSuspChar		nltc.t_suspc
+# define termRprntChar		nltc.t_rprntc
+# define termWerasChar		nltc.t_werasc
+# define termStartChar		ntc.t_startc
+# define termStopChar		ntc.t_stopc
+# define termForw1Char		ntc.t_brkc
+extern cc_t termForw2Char;
+extern cc_t termAytChar;
+
+# define termEofCharp		(cc_t *)&ntc.t_eofc
+# define termEraseCharp		(cc_t *)&nttyb.sg_erase
+# define termFlushCharp		(cc_t *)&nltc.t_flushc
+# define termIntCharp		(cc_t *)&ntc.t_intrc
+# define termKillCharp		(cc_t *)&nttyb.sg_kill
+# define termLiteralNextCharp	(cc_t *)&nltc.t_lnextc
+# define termQuitCharp		(cc_t *)&ntc.t_quitc
+# define termSuspCharp		(cc_t *)&nltc.t_suspc
+# define termRprntCharp		(cc_t *)&nltc.t_rprntc
+# define termWerasCharp		(cc_t *)&nltc.t_werasc
+# define termStartCharp		(cc_t *)&ntc.t_startc
+# define termStopCharp		(cc_t *)&ntc.t_stopc
+# define termForw1Charp		(cc_t *)&ntc.t_brkc
+# define termForw2Charp		(cc_t *)&termForw2Char
+# define termAytCharp		(cc_t *)&termAytChar
+
+# else
+
+extern struct	termio new_tc;
+
+# define termEofChar		new_tc.c_cc[VEOF]
+# define termEraseChar		new_tc.c_cc[VERASE]
+# define termIntChar		new_tc.c_cc[VINTR]
+# define termKillChar		new_tc.c_cc[VKILL]
+# define termQuitChar		new_tc.c_cc[VQUIT]
+
+# ifndef	VSUSP
+extern cc_t termSuspChar;
+# else
+#  define termSuspChar		new_tc.c_cc[VSUSP]
+# endif
+# if	defined(VFLUSHO) && !defined(VDISCARD)
+#  define VDISCARD VFLUSHO
+# endif
+# ifndef	VDISCARD
+extern cc_t termFlushChar;
+# else
+#  define termFlushChar		new_tc.c_cc[VDISCARD]
+# endif
+# ifndef VWERASE
+extern cc_t termWerasChar;
+# else
+#  define termWerasChar		new_tc.c_cc[VWERASE]
+# endif
+# ifndef	VREPRINT
+extern cc_t termRprntChar;
+# else
+#  define termRprntChar		new_tc.c_cc[VREPRINT]
+# endif
+# ifndef	VLNEXT
+extern cc_t termLiteralNextChar;
+# else
+#  define termLiteralNextChar	new_tc.c_cc[VLNEXT]
+# endif
+# ifndef	VSTART
+extern cc_t termStartChar;
+# else
+#  define termStartChar		new_tc.c_cc[VSTART]
+# endif
+# ifndef	VSTOP
+extern cc_t termStopChar;
+# else
+#  define termStopChar		new_tc.c_cc[VSTOP]
+# endif
+# ifndef	VEOL
+extern cc_t termForw1Char;
+# else
+#  define termForw1Char		new_tc.c_cc[VEOL]
+# endif
+# ifndef	VEOL2
+extern cc_t termForw2Char;
+# else
+#  define termForw2Char		new_tc.c_cc[VEOL]
+# endif
+# ifndef	VSTATUS
+extern cc_t termAytChar;
+#else
+#  define termAytChar		new_tc.c_cc[VSTATUS]
+#endif
+
+# if !defined(CRAY) || defined(__STDC__)
+#  define termEofCharp		&termEofChar
+#  define termEraseCharp	&termEraseChar
+#  define termIntCharp		&termIntChar
+#  define termKillCharp		&termKillChar
+#  define termQuitCharp		&termQuitChar
+#  define termSuspCharp		&termSuspChar
+#  define termFlushCharp	&termFlushChar
+#  define termWerasCharp	&termWerasChar
+#  define termRprntCharp	&termRprntChar
+#  define termLiteralNextCharp	&termLiteralNextChar
+#  define termStartCharp	&termStartChar
+#  define termStopCharp		&termStopChar
+#  define termForw1Charp	&termForw1Char
+#  define termForw2Charp	&termForw2Char
+#  define termAytCharp		&termAytChar
+# else
+	/* Work around a compiler bug */
+#  define termEofCharp		0
+#  define termEraseCharp	0
+#  define termIntCharp		0
+#  define termKillCharp		0
+#  define termQuitCharp		0
+#  define termSuspCharp		0
+#  define termFlushCharp	0
+#  define termWerasCharp	0
+#  define termRprntCharp	0
+#  define termLiteralNextCharp	0
+#  define termStartCharp	0
+#  define termStopCharp		0
+#  define termForw1Charp	0
+#  define termForw2Charp	0
+#  define termAytCharp		0
+# endif
+#endif
+
+
+/* Ring buffer structures which are shared */
+
+extern Ring
+    netoring,
+    netiring,
+    ttyoring,
+    ttyiring;
+
+/* Tn3270 section */
+#if	defined(TN3270)
+
+extern int
+    HaveInput,		/* Whether an asynchronous I/O indication came in */
+    noasynchtty,	/* Don't do signals on I/O (SIGURG, SIGIO) */
+    noasynchnet,	/* Don't do signals on I/O (SIGURG, SIGIO) */
+    sigiocount,		/* Count of SIGIO receptions */
+    shell_active;	/* Subshell is active */
+
+extern char
+    *Ibackp,		/* Oldest byte of 3270 data */
+    Ibuf[],		/* 3270 buffer */
+    *Ifrontp,		/* Where next 3270 byte goes */
+    tline[],
+    *transcom;		/* Transparent command */
+
+extern int
+    settranscom P((int, char**));
+
+extern void
+    inputAvailable P((int));
+#endif	/* defined(TN3270) */
diff --git a/telnet.tproj/fdset.h b/telnet.tproj/fdset.h
new file mode 100644
index 0000000..d0f290a
--- /dev/null
+++ b/telnet.tproj/fdset.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)fdset.h	8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * The following is defined just in case someone should want to run
+ * this telnet on a 4.2 system.
+ *
+ */
+
+#ifndef	FD_SETSIZE
+
+#define	FD_SET(n, p)	((p)->fds_bits[0] |= (1<<(n)))
+#define	FD_CLR(n, p)	((p)->fds_bits[0] &= ~(1<<(n)))
+#define	FD_ISSET(n, p)	((p)->fds_bits[0] & (1<<(n)))
+#define FD_ZERO(p)	((p)->fds_bits[0] = 0)
+
+#endif
diff --git a/telnet.tproj/general.h b/telnet.tproj/general.h
new file mode 100644
index 0000000..303ae14
--- /dev/null
+++ b/telnet.tproj/general.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)general.h	8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Some general definitions.
+ */
+
+
+#define	numberof(x)	(sizeof x/sizeof x[0])
+#define	highestof(x)	(numberof(x)-1)
+
+#define	ClearElement(x)		memset((char *)&x, 0, sizeof x)
+#define	ClearArray(x)		memset((char *)x, 0, sizeof x)
diff --git a/telnet.tproj/krb4-proto.h b/telnet.tproj/krb4-proto.h
new file mode 100644
index 0000000..9f3f0b0
--- /dev/null
+++ b/telnet.tproj/krb4-proto.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#ifdef __STDC__
+# define	P(s) s
+#else
+# define P(s) ()
+#endif
+
+/* add_ticket.c */
+int add_ticket P((KTEXT , int , char *, int , char *, char *, char *, int , KTEXT ));
+
+/* cr_err_reply.c */
+void cr_err_reply P((KTEXT , char *, char *, char *, u_long , u_long , char *));
+
+/* create_auth_reply.c */
+KTEXT create_auth_reply P((char *, char *, char *, long , int , unsigned long , int , KTEXT ));
+
+/* create_ciph.c */
+int create_ciph P((KTEXT , C_Block , char *, char *, char *, unsigned long , int , KTEXT , unsigned long , C_Block ));
+
+/* create_death_packet.c */
+KTEXT krb_create_death_packet P((char *));
+
+/* create_ticket.c */
+int krb_create_ticket P((KTEXT , unsigned int , char *, char *, char *, long , char *, int , long , char *, char *, C_Block ));
+
+/* debug_decl.c */
+
+/* decomp_ticket.c */
+int decomp_ticket P((KTEXT , unsigned char *, char *, char *, char *, unsigned long *, C_Block , int *, unsigned long *, char *, char *, C_Block , Key_schedule ));
+
+/* dest_tkt.c */
+int dest_tkt P((void ));
+
+/* extract_ticket.c */
+int extract_ticket P((KTEXT , int , char *, int *, int *, char *, KTEXT ));
+
+/* fgetst.c */
+int fgetst P((FILE *, char *, int ));
+
+/* get_ad_tkt.c */
+int get_ad_tkt P((char *, char *, char *, int ));
+
+/* get_admhst.c */
+int krb_get_admhst P((char *, char *, int ));
+
+/* get_cred.c */
+int krb_get_cred P((char *, char *, char *, CREDENTIALS *));
+
+/* get_in_tkt.c */
+int krb_get_pw_in_tkt P((char *, char *, char *, char *, char *, int , char *));
+int placebo_read_password P((des_cblock *, char *, int ));
+int placebo_read_pw_string P((char *, int , char *, int ));
+
+/* get_krbhst.c */
+int krb_get_krbhst P((char *, char *, int ));
+
+/* get_krbrlm.c */
+int krb_get_lrealm P((char *, int ));
+
+/* get_phost.c */
+char *krb_get_phost P((char *));
+
+/* get_pw_tkt.c */
+int get_pw_tkt P((char *, char *, char *, char *));
+
+/* get_request.c */
+int get_request P((KTEXT , int , char **, char **));
+
+/* get_svc_in_tkt.c */
+int krb_get_svc_in_tkt P((char *, char *, char *, char *, char *, int , char *));
+
+/* get_tf_fullname.c */
+int krb_get_tf_fullname P((char *, char *, char *, char *));
+
+/* get_tf_realm.c */
+int krb_get_tf_realm P((char *, char *));
+
+/* getopt.c */
+int getopt P((int , char **, char *));
+
+/* getrealm.c */
+char *krb_realmofhost P((char *));
+
+/* getst.c */
+int getst P((int , char *, int ));
+
+/* in_tkt.c */
+int in_tkt P((char *, char *));
+
+/* k_gethostname.c */
+int k_gethostname P((char *, int ));
+
+/* klog.c */
+char *klog P((int , char *, int , int , int , int , int , int , int , int , int , int ));
+int kset_logfile P((char *));
+
+/* kname_parse.c */
+int kname_parse P((char *, char *, char *, char *));
+int k_isname P((char *));
+int k_isinst P((char *));
+int k_isrealm P((char *));
+
+/* kntoln.c */
+int krb_kntoln P((AUTH_DAT *, char *));
+
+/* krb_err_txt.c */
+
+/* krb_get_in_tkt.c */
+int krb_get_in_tkt P((char *, char *, char *, char *, char *, int , int (*key_proc )(), int (*decrypt_proc )(), char *));
+
+/* kuserok.c */
+int kuserok P((AUTH_DAT *, char *));
+
+/* log.c */
+void log P((char *, int , int , int , int , int , int , int , int , int , int ));
+int set_logfile P((char *));
+int new_log P((long , char *));
+
+/* mk_err.c */
+long krb_mk_err P((u_char *, long , char *));
+
+/* mk_priv.c */
+long krb_mk_priv P((u_char *, u_char *, u_long , Key_schedule , C_Block , struct sockaddr_in *, struct sockaddr_in *));
+
+/* mk_req.c */
+int krb_mk_req P((KTEXT , char *, char *, char *, long ));
+int krb_set_lifetime P((int ));
+
+/* mk_safe.c */
+long krb_mk_safe P((u_char *, u_char *, u_long , C_Block *, struct sockaddr_in *, struct sockaddr_in *));
+
+/* month_sname.c */
+char *month_sname P((int ));
+
+/* netread.c */
+int krb_net_read P((int , char *, int ));
+
+/* netwrite.c */
+int krb_net_write P((int , char *, int ));
+
+/* one.c */
+
+/* pkt_cipher.c */
+KTEXT pkt_cipher P((KTEXT ));
+
+/* pkt_clen.c */
+int pkt_clen P((KTEXT ));
+
+/* rd_err.c */
+int krb_rd_err P((u_char *, u_long , long *, MSG_DAT *));
+
+/* rd_priv.c */
+long krb_rd_priv P((u_char *, u_long , Key_schedule , C_Block , struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *));
+
+/* rd_req.c */
+int krb_set_key P((char *, int ));
+int krb_rd_req P((KTEXT , char *, char *, long , AUTH_DAT *, char *));
+
+/* rd_safe.c */
+long krb_rd_safe P((u_char *, u_long , C_Block *, struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *));
+
+/* read_service_key.c */
+int read_service_key P((char *, char *, char *, int , char *, char *));
+
+/* recvauth.c */
+int krb_recvauth P((long , int , KTEXT , char *, char *, struct sockaddr_in *, struct sockaddr_in *, AUTH_DAT *, char *, Key_schedule , char *));
+
+/* save_credentials.c */
+int save_credentials P((char *, char *, char *, C_Block , int , int , KTEXT , long ));
+
+/* send_to_kdc.c */
+int send_to_kdc P((KTEXT , KTEXT , char *));
+
+/* sendauth.c */
+int krb_sendauth P((long , int , KTEXT , char *, char *, char *, u_long , MSG_DAT *, CREDENTIALS *, Key_schedule , struct sockaddr_in *, struct sockaddr_in *, char *));
+int krb_sendsvc P((int , char *));
+
+/* setenv.c */
+int setenv P((char *, char *, int ));
+void unsetenv P((char *));
+char *getenv P((char *));
+char *_findenv P((char *, int *));
+
+/* stime.c */
+char *stime P((long *));
+
+/* tf_shm.c */
+int krb_shm_create P((char *));
+int krb_is_diskless P((void ));
+int krb_shm_dest P((char *));
+
+/* tf_util.c */
+int tf_init P((char *, int ));
+int tf_get_pname P((char *));
+int tf_get_pinst P((char *));
+int tf_get_cred P((CREDENTIALS *));
+int tf_close P((void ));
+int tf_save_cred P((char *, char *, char *, C_Block , int , int , KTEXT , long ));
+
+/* tkt_string.c */
+char *tkt_string P((void ));
+void krb_set_tkt_string P((char *));
+
+/* util.c */
+int ad_print P((AUTH_DAT *));
+int placebo_cblock_print P((des_cblock ));
+
+#undef P
diff --git a/telnet.tproj/main.c b/telnet.tproj/main.c
new file mode 100644
index 0000000..94cbfc8
--- /dev/null
+++ b/telnet.tproj/main.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1990, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c	8.3 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#include <sys/types.h>
+
+#include "ring.h"
+#include "externs.h"
+#include "defines.h"
+
+/* These values need to be the same as defined in libtelnet/kerberos5.c */
+/* Either define them in both places, or put in some common header file. */
+#define OPTS_FORWARD_CREDS	0x00000002
+#define OPTS_FORWARDABLE_CREDS	0x00000001
+
+#if 0
+#define FORWARD
+#endif
+
+/*
+ * Initialize variables.
+ */
+    void
+tninit()
+{
+    init_terminal();
+
+    init_network();
+
+    init_telnet();
+
+    init_sys();
+
+#if defined(TN3270)
+    init_3270();
+#endif
+}
+
+	void
+usage()
+{
+	fprintf(stderr, "Usage: %s %s%s%s%s\n",
+	    prompt,
+#ifdef	AUTHENTICATION
+	    "[-8] [-E] [-K] [-L] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]",
+	    "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] ",
+#else
+	    "[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
+	    "\n\t[-n tracefile]",
+#endif
+#if defined(TN3270) && (defined(unix) || defined(__APPLE__))
+# ifdef AUTHENTICATION
+	    "[-noasynch] [-noasynctty]\n\t[-noasyncnet] [-r] [-t transcom] ",
+# else
+	    "[-noasynch] [-noasynctty] [-noasyncnet] [-r]\n\t[-t transcom]",
+# endif
+#else
+	    "[-r] ",
+#endif
+#ifdef	ENCRYPTION
+	    "[-x] [host-name [port]]"
+#else	/* ENCRYPTION */
+	    "[host-name [port]]"
+#endif	/* ENCRYPTION */
+	);
+	exit(1);
+}
+
+/*
+ * main.  Parse arguments, invoke the protocol or command parser.
+ */
+
+
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	extern char *optarg;
+	extern int optind;
+	int ch;
+	char *user, *strrchr();
+#ifdef	FORWARD
+	extern int forward_flags;
+#endif	/* FORWARD */
+
+	tninit();		/* Clear out things */
+#if	defined(CRAY) && !defined(__STDC__)
+	_setlist_init();	/* Work around compiler bug */
+#endif
+
+	TerminalSaveState();
+
+	if (prompt = strrchr(argv[0], '/'))
+		++prompt;
+	else
+		prompt = argv[0];
+
+	user = NULL;
+
+	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
+	autologin = -1;
+
+	while ((ch = getopt(argc, argv, "8EKLS:X:acde:fFk:l:n:rt:x")) != EOF) {
+		switch(ch) {
+		case '8':
+			eight = 3;	/* binary output and input */
+			break;
+		case 'E':
+			rlogin = escape = _POSIX_VDISABLE;
+			break;
+		case 'K':
+#ifdef	AUTHENTICATION
+			autologin = 0;
+#endif
+			break;
+		case 'L':
+			eight |= 2;	/* binary output only */
+			break;
+		case 'S':
+		    {
+#ifdef	HAS_GETTOS
+			extern int tos;
+
+			if ((tos = parsetos(optarg, "tcp")) < 0)
+				fprintf(stderr, "%s%s%s%s\n",
+					prompt, ": Bad TOS argument '",
+					optarg,
+					"; will try to use default TOS");
+#else
+			fprintf(stderr,
+			   "%s: Warning: -S ignored, no parsetos() support.\n",
+								prompt);
+#endif
+		    }
+			break;
+		case 'X':
+#ifdef	AUTHENTICATION
+			auth_disable_name(optarg);
+#endif
+			break;
+		case 'a':
+			autologin = 1;
+			break;
+		case 'c':
+			skiprc = 1;
+			break;
+		case 'd':
+			debug = 1;
+			break;
+		case 'e':
+			set_escape_char(optarg);
+			break;
+		case 'f':
+#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
+			if (forward_flags & OPTS_FORWARD_CREDS) {
+			    fprintf(stderr,
+				    "%s: Only one of -f and -F allowed.\n",
+				    prompt);
+			    usage();
+			}
+			forward_flags |= OPTS_FORWARD_CREDS;
+#else
+			fprintf(stderr,
+			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
+				prompt);
+#endif
+			break;
+		case 'F':
+#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
+			if (forward_flags & OPTS_FORWARD_CREDS) {
+			    fprintf(stderr,
+				    "%s: Only one of -f and -F allowed.\n",
+				    prompt);
+			    usage();
+			}
+			forward_flags |= OPTS_FORWARD_CREDS;
+			forward_flags |= OPTS_FORWARDABLE_CREDS;
+#else
+			fprintf(stderr,
+			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
+				prompt);
+#endif
+			break;
+		case 'k':
+#if defined(AUTHENTICATION) && defined(KRB4)
+		    {
+			extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
+			dest_realm = dst_realm_buf;
+			(void)strncpy(dest_realm, optarg, dst_realm_sz);
+		    }
+#else
+			fprintf(stderr,
+			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
+								prompt);
+#endif
+			break;
+		case 'l':
+			autologin = 1;
+			user = optarg;
+			break;
+		case 'n':
+#if defined(TN3270) && (defined(unix) || defined(__APPLE__))
+			/* distinguish between "-n oasynch" and "-noasynch" */
+			if (argv[optind - 1][0] == '-' && argv[optind - 1][1]
+			    == 'n' && argv[optind - 1][2] == 'o') {
+				if (!strcmp(optarg, "oasynch")) {
+					noasynchtty = 1;
+					noasynchnet = 1;
+				} else if (!strcmp(optarg, "oasynchtty"))
+					noasynchtty = 1;
+				else if (!strcmp(optarg, "oasynchnet"))
+					noasynchnet = 1;
+			} else
+#endif	/* defined(TN3270) && (defined(unix) || defined(__APPLE__)) */
+				SetNetTrace(optarg);
+			break;
+		case 'r':
+			rlogin = '~';
+			break;
+		case 't':
+#if defined(TN3270) && (defined(unix) || defined(__APPLE__))
+			transcom = tline;
+			(void)strcpy(transcom, optarg);
+#else
+			fprintf(stderr,
+			   "%s: Warning: -t ignored, no TN3270 support.\n",
+								prompt);
+#endif
+			break;
+		case 'x':
+#ifdef	ENCRYPTION
+			encrypt_auto(1);
+			decrypt_auto(1);
+#else	/* ENCRYPTION */
+			fprintf(stderr,
+			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
+								prompt);
+#endif	/* ENCRYPTION */
+			break;
+		case '?':
+		default:
+			usage();
+			/* NOTREACHED */
+		}
+	}
+	if (autologin == -1)
+		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc) {
+		char *args[7], **argp = args;
+
+		if (argc > 2)
+			usage();
+		*argp++ = prompt;
+		if (user) {
+			*argp++ = "-l";
+			*argp++ = user;
+		}
+		*argp++ = argv[0];		/* host */
+		if (argc > 1)
+			*argp++ = argv[1];	/* port */
+		*argp = 0;
+
+		if (setjmp(toplevel) != 0)
+			Exit(0);
+		if (tn(argp - args, args) == 1)
+			return (0);
+		else
+			return (1);
+	}
+	(void)setjmp(toplevel);
+	for (;;) {
+#ifdef TN3270
+		if (shell_active)
+			shell_continue();
+		else
+#endif
+			command(1, 0, 0);
+	}
+}
diff --git a/telnet.tproj/network.c b/telnet.tproj/network.c
new file mode 100644
index 0000000..27cc7bd
--- /dev/null
+++ b/telnet.tproj/network.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)network.c	8.2 (Berkeley) 12/15/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <errno.h>
+
+#include <arpa/telnet.h>
+
+#include "ring.h"
+
+#include "defines.h"
+#include "externs.h"
+#include "fdset.h"
+
+Ring		netoring, netiring;
+unsigned char	netobuf[2*BUFSIZ], netibuf[BUFSIZ];
+
+/*
+ * Initialize internal network data structures.
+ */
+
+    void
+init_network()
+{
+    if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
+	exit(1);
+    }
+    if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
+	exit(1);
+    }
+    NetTrace = stdout;
+}
+
+
+/*
+ * Check to see if any out-of-band data exists on a socket (for
+ * Telnet "synch" processing).
+ */
+
+    int
+stilloob()
+{
+    static struct timeval timeout = { 0 };
+    fd_set	excepts;
+    int value;
+
+    do {
+	FD_ZERO(&excepts);
+	FD_SET(net, &excepts);
+	value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
+    } while ((value == -1) && (errno == EINTR));
+
+    if (value < 0) {
+	perror("select");
+	(void) quit();
+	/* NOTREACHED */
+    }
+    if (FD_ISSET(net, &excepts)) {
+	return 1;
+    } else {
+	return 0;
+    }
+}
+
+
+/*
+ *  setneturg()
+ *
+ *	Sets "neturg" to the current location.
+ */
+
+    void
+setneturg()
+{
+    ring_mark(&netoring);
+}
+
+
+/*
+ *  netflush
+ *		Send as much data as possible to the network,
+ *	handling requests for urgent data.
+ *
+ *		The return value indicates whether we did any
+ *	useful work.
+ */
+
+
+    int
+netflush()
+{
+    register int n, n1;
+
+#ifdef	ENCRYPTION
+    if (encrypt_output)
+	ring_encrypt(&netoring, encrypt_output);
+#endif	/* ENCRYPTION */
+    if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
+	if (!ring_at_mark(&netoring)) {
+	    n = send(net, (char *)netoring.consume, n, 0); /* normal write */
+	} else {
+	    /*
+	     * In 4.2 (and 4.3) systems, there is some question about
+	     * what byte in a sendOOB operation is the "OOB" data.
+	     * To make ourselves compatible, we only send ONE byte
+	     * out of band, the one WE THINK should be OOB (though
+	     * we really have more the TCP philosophy of urgent data
+	     * rather than the Unix philosophy of OOB data).
+	     */
+	    n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */
+	}
+    }
+    if (n < 0) {
+	if (errno != ENOBUFS && errno != EWOULDBLOCK) {
+	    setcommandmode();
+	    perror(hostname);
+	    (void)NetClose(net);
+	    ring_clear_mark(&netoring);
+	    longjmp(peerdied, -1);
+	    /*NOTREACHED*/
+	}
+	n = 0;
+    }
+    if (netdata && n) {
+	Dump('>', netoring.consume, n);
+    }
+    if (n) {
+	ring_consumed(&netoring, n);
+	/*
+	 * If we sent all, and more to send, then recurse to pick
+	 * up the other half.
+	 */
+	if ((n1 == n) && ring_full_consecutive(&netoring)) {
+	    (void) netflush();
+	}
+	return 1;
+    } else {
+	return 0;
+    }
+}
diff --git a/telnet.tproj/ring.c b/telnet.tproj/ring.c
new file mode 100644
index 0000000..6506ae1
--- /dev/null
+++ b/telnet.tproj/ring.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ring.c	8.2 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+/*
+ * This defines a structure for a ring buffer.
+ *
+ * The circular buffer has two parts:
+ *(((
+ *	full:	[consume, supply)
+ *	empty:	[supply, consume)
+ *]]]
+ *
+ */
+
+#include	<stdio.h>
+#include	<errno.h>
+
+#ifdef	size_t
+#undef	size_t
+#endif
+
+#include	<sys/types.h>
+#ifndef	FILIO_H
+#include	<sys/ioctl.h>
+#endif
+#include	<sys/socket.h>
+
+#include	"ring.h"
+#include	"general.h"
+
+/* Internal macros */
+
+#if	!defined(MIN)
+#define	MIN(a,b)	(((a)<(b))? (a):(b))
+#endif	/* !defined(MIN) */
+
+#define	ring_subtract(d,a,b)	(((a)-(b) >= 0)? \
+					(a)-(b): (((a)-(b))+(d)->size))
+
+#define	ring_increment(d,a,c)	(((a)+(c) < (d)->top)? \
+					(a)+(c) : (((a)+(c))-(d)->size))
+
+#define	ring_decrement(d,a,c)	(((a)-(c) >= (d)->bottom)? \
+					(a)-(c) : (((a)-(c))-(d)->size))
+
+
+/*
+ * The following is a clock, used to determine full, empty, etc.
+ *
+ * There is some trickiness here.  Since the ring buffers are initialized
+ * to ZERO on allocation, we need to make sure, when interpreting the
+ * clock, that when the times are EQUAL, then the buffer is FULL.
+ */
+static u_long ring_clock = 0;
+
+
+#define	ring_empty(d) (((d)->consume == (d)->supply) && \
+				((d)->consumetime >= (d)->supplytime))
+#define	ring_full(d) (((d)->supply == (d)->consume) && \
+				((d)->supplytime > (d)->consumetime))
+
+
+
+
+
+/* Buffer state transition routines */
+
+    ring_init(ring, buffer, count)
+Ring *ring;
+    unsigned char *buffer;
+    int count;
+{
+    memset((char *)ring, 0, sizeof *ring);
+
+    ring->size = count;
+
+    ring->supply = ring->consume = ring->bottom = buffer;
+
+    ring->top = ring->bottom+ring->size;
+
+#ifdef	ENCRYPTION
+    ring->clearto = 0;
+#endif	/* ENCRYPTION */
+
+    return 1;
+}
+
+/* Mark routines */
+
+/*
+ * Mark the most recently supplied byte.
+ */
+
+    void
+ring_mark(ring)
+    Ring *ring;
+{
+    ring->mark = ring_decrement(ring, ring->supply, 1);
+}
+
+/*
+ * Is the ring pointing to the mark?
+ */
+
+    int
+ring_at_mark(ring)
+    Ring *ring;
+{
+    if (ring->mark == ring->consume) {
+	return 1;
+    } else {
+	return 0;
+    }
+}
+
+/*
+ * Clear any mark set on the ring.
+ */
+
+    void
+ring_clear_mark(ring)
+    Ring *ring;
+{
+    ring->mark = 0;
+}
+
+/*
+ * Add characters from current segment to ring buffer.
+ */
+    void
+ring_supplied(ring, count)
+    Ring *ring;
+    int count;
+{
+    ring->supply = ring_increment(ring, ring->supply, count);
+    ring->supplytime = ++ring_clock;
+}
+
+/*
+ * We have just consumed "c" bytes.
+ */
+    void
+ring_consumed(ring, count)
+    Ring *ring;
+    int count;
+{
+    if (count == 0)	/* don't update anything */
+	return;
+
+    if (ring->mark &&
+		(ring_subtract(ring, ring->mark, ring->consume) < count)) {
+	ring->mark = 0;
+    }
+#ifdef	ENCRYPTION
+    if (ring->consume < ring->clearto &&
+		ring->clearto <= ring->consume + count)
+	ring->clearto = 0;
+    else if (ring->consume + count > ring->top &&
+		ring->bottom <= ring->clearto &&
+		ring->bottom + ((ring->consume + count) - ring->top))
+	ring->clearto = 0;
+#endif	/* ENCRYPTION */
+    ring->consume = ring_increment(ring, ring->consume, count);
+    ring->consumetime = ++ring_clock;
+    /*
+     * Try to encourage "ring_empty_consecutive()" to be large.
+     */
+    if (ring_empty(ring)) {
+	ring->consume = ring->supply = ring->bottom;
+    }
+}
+
+
+
+/* Buffer state query routines */
+
+
+/* Number of bytes that may be supplied */
+    int
+ring_empty_count(ring)
+    Ring *ring;
+{
+    if (ring_empty(ring)) {	/* if empty */
+	    return ring->size;
+    } else {
+	return ring_subtract(ring, ring->consume, ring->supply);
+    }
+}
+
+/* number of CONSECUTIVE bytes that may be supplied */
+    int
+ring_empty_consecutive(ring)
+    Ring *ring;
+{
+    if ((ring->consume < ring->supply) || ring_empty(ring)) {
+			    /*
+			     * if consume is "below" supply, or empty, then
+			     * return distance to the top
+			     */
+	return ring_subtract(ring, ring->top, ring->supply);
+    } else {
+				    /*
+				     * else, return what we may.
+				     */
+	return ring_subtract(ring, ring->consume, ring->supply);
+    }
+}
+
+/* Return the number of bytes that are available for consuming
+ * (but don't give more than enough to get to cross over set mark)
+ */
+
+    int
+ring_full_count(ring)
+    Ring *ring;
+{
+    if ((ring->mark == 0) || (ring->mark == ring->consume)) {
+	if (ring_full(ring)) {
+	    return ring->size;	/* nothing consumed, but full */
+	} else {
+	    return ring_subtract(ring, ring->supply, ring->consume);
+	}
+    } else {
+	return ring_subtract(ring, ring->mark, ring->consume);
+    }
+}
+
+/*
+ * Return the number of CONSECUTIVE bytes available for consuming.
+ * However, don't return more than enough to cross over set mark.
+ */
+    int
+ring_full_consecutive(ring)
+    Ring *ring;
+{
+    if ((ring->mark == 0) || (ring->mark == ring->consume)) {
+	if ((ring->supply < ring->consume) || ring_full(ring)) {
+	    return ring_subtract(ring, ring->top, ring->consume);
+	} else {
+	    return ring_subtract(ring, ring->supply, ring->consume);
+	}
+    } else {
+	if (ring->mark < ring->consume) {
+	    return ring_subtract(ring, ring->top, ring->consume);
+	} else {	/* Else, distance to mark */
+	    return ring_subtract(ring, ring->mark, ring->consume);
+	}
+    }
+}
+
+/*
+ * Move data into the "supply" portion of of the ring buffer.
+ */
+    void
+ring_supply_data(ring, buffer, count)
+    Ring *ring;
+    unsigned char *buffer;
+    int count;
+{
+    int i;
+
+    while (count) {
+	i = MIN(count, ring_empty_consecutive(ring));
+	memmove(ring->supply, buffer, i);
+	ring_supplied(ring, i);
+	count -= i;
+	buffer += i;
+    }
+}
+
+#ifdef notdef
+
+/*
+ * Move data from the "consume" portion of the ring buffer
+ */
+    void
+ring_consume_data(ring, buffer, count)
+    Ring *ring;
+    unsigned char *buffer;
+    int count;
+{
+    int i;
+
+    while (count) {
+	i = MIN(count, ring_full_consecutive(ring));
+	memmove(buffer, ring->consume, i);
+	ring_consumed(ring, i);
+	count -= i;
+	buffer += i;
+    }
+}
+#endif
+
+#ifdef	ENCRYPTION
+    void
+ring_encrypt(ring, encryptor)
+    Ring *ring;
+    void (*encryptor)();
+{
+    unsigned char *s, *c;
+
+    if (ring_empty(ring) || ring->clearto == ring->supply)
+	return;
+
+    if (!(c = ring->clearto))
+	c = ring->consume;
+
+    s = ring->supply;
+
+    if (s <= c) {
+	(*encryptor)(c, ring->top - c);
+	(*encryptor)(ring->bottom, s - ring->bottom);
+    } else
+	(*encryptor)(c, s - c);
+
+    ring->clearto = ring->supply;
+}
+
+    void
+ring_clearto(ring)
+    Ring *ring;
+{
+    if (!ring_empty(ring))
+	ring->clearto = ring->supply;
+    else
+	ring->clearto = 0;
+}
+#endif	/* ENCRYPTION */
diff --git a/telnet.tproj/ring.h b/telnet.tproj/ring.h
new file mode 100644
index 0000000..a9ef843
--- /dev/null
+++ b/telnet.tproj/ring.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ring.h	8.1 (Berkeley) 6/6/93
+ */
+
+#if defined(P)
+# undef P
+#endif
+
+#if defined(__STDC__) || defined(LINT_ARGS)
+# define	P(x)	x
+#else
+# define	P(x)	()
+#endif
+
+/*
+ * This defines a structure for a ring buffer.
+ *
+ * The circular buffer has two parts:
+ *(((
+ *	full:	[consume, supply)
+ *	empty:	[supply, consume)
+ *]]]
+ *
+ */
+typedef struct {
+    unsigned char	*consume,	/* where data comes out of */
+			*supply,	/* where data comes in to */
+			*bottom,	/* lowest address in buffer */
+			*top,		/* highest address+1 in buffer */
+			*mark;		/* marker (user defined) */
+#ifdef	ENCRYPTION
+    unsigned char	*clearto;	/* Data to this point is clear text */
+    unsigned char	*encryyptedto;	/* Data is encrypted to here */
+#endif	/* ENCRYPTION */
+    int		size;		/* size in bytes of buffer */
+    u_long	consumetime,	/* help us keep straight full, empty, etc. */
+		supplytime;
+} Ring;
+
+/* Here are some functions and macros to deal with the ring buffer */
+
+/* Initialization routine */
+extern int
+	ring_init P((Ring *ring, unsigned char *buffer, int count));
+
+/* Data movement routines */
+extern void
+	ring_supply_data P((Ring *ring, unsigned char *buffer, int count));
+#ifdef notdef
+extern void
+	ring_consume_data P((Ring *ring, unsigned char *buffer, int count));
+#endif
+
+/* Buffer state transition routines */
+extern void
+	ring_supplied P((Ring *ring, int count)),
+	ring_consumed P((Ring *ring, int count));
+
+/* Buffer state query routines */
+extern int
+	ring_empty_count P((Ring *ring)),
+	ring_empty_consecutive P((Ring *ring)),
+	ring_full_count P((Ring *ring)),
+	ring_full_consecutive P((Ring *ring));
+
+#ifdef	ENCRYPTION
+extern void
+	ring_encrypt P((Ring *ring, void (*func)())),
+	ring_clearto P((Ring *ring));
+#endif	/* ENCRYPTION */
+
+extern void
+    ring_clear_mark(),
+    ring_mark();
diff --git a/telnet.tproj/sys_bsd.c b/telnet.tproj/sys_bsd.c
new file mode 100644
index 0000000..8455d4d
--- /dev/null
+++ b/telnet.tproj/sys_bsd.c
@@ -0,0 +1,1243 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)sys_bsd.c	8.4 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+/*
+ * The following routines try to encapsulate what is system dependent
+ * (at least between 4.x and dos) which is used in telnet.c.
+ */
+
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <errno.h>
+#include <arpa/telnet.h>
+
+#include "ring.h"
+
+#include "fdset.h"
+
+#include "defines.h"
+#include "externs.h"
+#include "types.h"
+
+#if	defined(CRAY) || (defined(USE_TERMIO) && !defined(SYSV_TERMIO))
+#define	SIG_FUNC_RET	void
+#else
+#define	SIG_FUNC_RET	int
+#endif
+
+#ifdef	SIGINFO
+extern SIG_FUNC_RET ayt_status();
+#endif
+
+int
+	tout,			/* Output file descriptor */
+	tin,			/* Input file descriptor */
+	net;
+
+#ifndef	USE_TERMIO
+struct	tchars otc = { 0 }, ntc = { 0 };
+struct	ltchars oltc = { 0 }, nltc = { 0 };
+struct	sgttyb ottyb = { 0 }, nttyb = { 0 };
+int	olmode = 0;
+# define cfgetispeed(ptr)	(ptr)->sg_ispeed
+# define cfgetospeed(ptr)	(ptr)->sg_ospeed
+# define old_tc ottyb
+
+#else	/* USE_TERMIO */
+struct	termio old_tc = { 0 };
+extern struct termio new_tc;
+
+# ifndef	TCSANOW
+#  ifdef TCSETS
+#   define	TCSANOW		TCSETS
+#   define	TCSADRAIN	TCSETSW
+#   define	tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
+#  else
+#   ifdef TCSETA
+#    define	TCSANOW		TCSETA
+#    define	TCSADRAIN	TCSETAW
+#    define	tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)
+#   else
+#    define	TCSANOW		TIOCSETA
+#    define	TCSADRAIN	TIOCSETAW
+#    define	tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)
+#   endif
+#  endif
+#  define	tcsetattr(f, a, t) ioctl(f, a, (char *)t)
+#  define	cfgetospeed(ptr)	((ptr)->c_cflag&CBAUD)
+#  ifdef CIBAUD
+#   define	cfgetispeed(ptr)	(((ptr)->c_cflag&CIBAUD) >> IBSHIFT)
+#  else
+#   define	cfgetispeed(ptr)	cfgetospeed(ptr)
+#  endif
+# endif /* TCSANOW */
+# ifdef	sysV88
+# define TIOCFLUSH TC_PX_DRAIN
+# endif
+#endif	/* USE_TERMIO */
+
+static fd_set ibits, obits, xbits;
+
+
+    void
+init_sys()
+{
+    tout = fileno(stdout);
+    tin = fileno(stdin);
+    FD_ZERO(&ibits);
+    FD_ZERO(&obits);
+    FD_ZERO(&xbits);
+
+    errno = 0;
+}
+
+
+    int
+TerminalWrite(buf, n)
+    char *buf;
+    int  n;
+{
+    return write(tout, buf, n);
+}
+
+    int
+TerminalRead(buf, n)
+    char *buf;
+    int  n;
+{
+    return read(tin, buf, n);
+}
+
+/*
+ *
+ */
+
+    int
+TerminalAutoFlush()
+{
+#if	defined(LNOFLSH)
+    int flush;
+
+    ioctl(0, TIOCLGET, (char *)&flush);
+    return !(flush&LNOFLSH);	/* if LNOFLSH, no autoflush */
+#else	/* LNOFLSH */
+    return 1;
+#endif	/* LNOFLSH */
+}
+
+#ifdef	KLUDGELINEMODE
+extern int kludgelinemode;
+#endif
+/*
+ * TerminalSpecialChars()
+ *
+ * Look at an input character to see if it is a special character
+ * and decide what to do.
+ *
+ * Output:
+ *
+ *	0	Don't add this character.
+ *	1	Do add this character
+ */
+
+extern void xmitAO(), xmitEL(), xmitEC(), intp(), sendbrk();
+
+    int
+TerminalSpecialChars(c)
+    int	c;
+{
+    if (c == termIntChar) {
+	intp();
+	return 0;
+    } else if (c == termQuitChar) {
+#ifdef	KLUDGELINEMODE
+	if (kludgelinemode)
+	    sendbrk();
+	else
+#endif
+	    sendabort();
+	return 0;
+    } else if (c == termEofChar) {
+	if (my_want_state_is_will(TELOPT_LINEMODE)) {
+	    sendeof();
+	    return 0;
+	}
+	return 1;
+    } else if (c == termSuspChar) {
+	sendsusp();
+	return(0);
+    } else if (c == termFlushChar) {
+	xmitAO();		/* Transmit Abort Output */
+	return 0;
+    } else if (!MODE_LOCAL_CHARS(globalmode)) {
+	if (c == termKillChar) {
+	    xmitEL();
+	    return 0;
+	} else if (c == termEraseChar) {
+	    xmitEC();		/* Transmit Erase Character */
+	    return 0;
+	}
+    }
+    return 1;
+}
+
+
+/*
+ * Flush output to the terminal
+ */
+
+    void
+TerminalFlushOutput()
+{
+#ifdef	TIOCFLUSH
+    (void) ioctl(fileno(stdout), TIOCFLUSH, (char *) 0);
+#else
+    (void) ioctl(fileno(stdout), TCFLSH, (char *) 0);
+#endif
+}
+
+    void
+TerminalSaveState()
+{
+#ifndef	USE_TERMIO
+    ioctl(0, TIOCGETP, (char *)&ottyb);
+    ioctl(0, TIOCGETC, (char *)&otc);
+    ioctl(0, TIOCGLTC, (char *)&oltc);
+    ioctl(0, TIOCLGET, (char *)&olmode);
+
+    ntc = otc;
+    nltc = oltc;
+    nttyb = ottyb;
+
+#else	/* USE_TERMIO */
+    tcgetattr(0, &old_tc);
+
+    new_tc = old_tc;
+
+#ifndef	VDISCARD
+    termFlushChar = CONTROL('O');
+#endif
+#ifndef	VWERASE
+    termWerasChar = CONTROL('W');
+#endif
+#ifndef	VREPRINT
+    termRprntChar = CONTROL('R');
+#endif
+#ifndef	VLNEXT
+    termLiteralNextChar = CONTROL('V');
+#endif
+#ifndef	VSTART
+    termStartChar = CONTROL('Q');
+#endif
+#ifndef	VSTOP
+    termStopChar = CONTROL('S');
+#endif
+#ifndef	VSTATUS
+    termAytChar = CONTROL('T');
+#endif
+#endif	/* USE_TERMIO */
+}
+
+    cc_t *
+tcval(func)
+    register int func;
+{
+    switch(func) {
+    case SLC_IP:	return(&termIntChar);
+    case SLC_ABORT:	return(&termQuitChar);
+    case SLC_EOF:	return(&termEofChar);
+    case SLC_EC:	return(&termEraseChar);
+    case SLC_EL:	return(&termKillChar);
+    case SLC_XON:	return(&termStartChar);
+    case SLC_XOFF:	return(&termStopChar);
+    case SLC_FORW1:	return(&termForw1Char);
+#ifdef	USE_TERMIO
+    case SLC_FORW2:	return(&termForw2Char);
+# ifdef	VDISCARD
+    case SLC_AO:	return(&termFlushChar);
+# endif
+# ifdef	VSUSP
+    case SLC_SUSP:	return(&termSuspChar);
+# endif
+# ifdef	VWERASE
+    case SLC_EW:	return(&termWerasChar);
+# endif
+# ifdef	VREPRINT
+    case SLC_RP:	return(&termRprntChar);
+# endif
+# ifdef	VLNEXT
+    case SLC_LNEXT:	return(&termLiteralNextChar);
+# endif
+# ifdef	VSTATUS
+    case SLC_AYT:	return(&termAytChar);
+# endif
+#endif
+
+    case SLC_SYNCH:
+    case SLC_BRK:
+    case SLC_EOR:
+    default:
+	return((cc_t *)0);
+    }
+}
+
+    void
+TerminalDefaultChars()
+{
+#ifndef	USE_TERMIO
+    ntc = otc;
+    nltc = oltc;
+    nttyb.sg_kill = ottyb.sg_kill;
+    nttyb.sg_erase = ottyb.sg_erase;
+#else	/* USE_TERMIO */
+    memmove(new_tc.c_cc, old_tc.c_cc, sizeof(old_tc.c_cc));
+# ifndef	VDISCARD
+    termFlushChar = CONTROL('O');
+# endif
+# ifndef	VWERASE
+    termWerasChar = CONTROL('W');
+# endif
+# ifndef	VREPRINT
+    termRprntChar = CONTROL('R');
+# endif
+# ifndef	VLNEXT
+    termLiteralNextChar = CONTROL('V');
+# endif
+# ifndef	VSTART
+    termStartChar = CONTROL('Q');
+# endif
+# ifndef	VSTOP
+    termStopChar = CONTROL('S');
+# endif
+# ifndef	VSTATUS
+    termAytChar = CONTROL('T');
+# endif
+#endif	/* USE_TERMIO */
+}
+
+#ifdef notdef
+void
+TerminalRestoreState()
+{
+}
+#endif
+
+/*
+ * TerminalNewMode - set up terminal to a specific mode.
+ *	MODE_ECHO: do local terminal echo
+ *	MODE_FLOW: do local flow control
+ *	MODE_TRAPSIG: do local mapping to TELNET IAC sequences
+ *	MODE_EDIT: do local line editing
+ *
+ *	Command mode:
+ *		MODE_ECHO|MODE_EDIT|MODE_FLOW|MODE_TRAPSIG
+ *		local echo
+ *		local editing
+ *		local xon/xoff
+ *		local signal mapping
+ *
+ *	Linemode:
+ *		local/no editing
+ *	Both Linemode and Single Character mode:
+ *		local/remote echo
+ *		local/no xon/xoff
+ *		local/no signal mapping
+ */
+
+
+    void
+TerminalNewMode(f)
+    register int f;
+{
+    static int prevmode = 0;
+#ifndef	USE_TERMIO
+    struct tchars tc;
+    struct ltchars ltc;
+    struct sgttyb sb;
+    int lmode;
+#else	/* USE_TERMIO */
+    struct termio tmp_tc;
+#endif	/* USE_TERMIO */
+    int onoff;
+    int old;
+    cc_t esc;
+
+    globalmode = f&~MODE_FORCE;
+    if (prevmode == f)
+	return;
+
+    /*
+     * Write any outstanding data before switching modes
+     * ttyflush() returns 0 only when there is no more data
+     * left to write out, it returns -1 if it couldn't do
+     * anything at all, otherwise it returns 1 + the number
+     * of characters left to write.
+#ifndef	USE_TERMIO
+     * We would really like ask the kernel to wait for the output
+     * to drain, like we can do with the TCSADRAIN, but we don't have
+     * that option.  The only ioctl that waits for the output to
+     * drain, TIOCSETP, also flushes the input queue, which is NOT
+     * what we want (TIOCSETP is like TCSADFLUSH).
+#endif
+     */
+    old = ttyflush(SYNCHing|flushout);
+    if (old < 0 || old > 1) {
+#ifdef	USE_TERMIO
+	tcgetattr(tin, &tmp_tc);
+#endif	/* USE_TERMIO */
+	do {
+	    /*
+	     * Wait for data to drain, then flush again.
+	     */
+#ifdef	USE_TERMIO
+	    tcsetattr(tin, TCSADRAIN, &tmp_tc);
+#endif	/* USE_TERMIO */
+	    old = ttyflush(SYNCHing|flushout);
+	} while (old < 0 || old > 1);
+    }
+
+    old = prevmode;
+    prevmode = f&~MODE_FORCE;
+#ifndef	USE_TERMIO
+    sb = nttyb;
+    tc = ntc;
+    ltc = nltc;
+    lmode = olmode;
+#else
+    tmp_tc = new_tc;
+#endif
+
+    if (f&MODE_ECHO) {
+#ifndef	USE_TERMIO
+	sb.sg_flags |= ECHO;
+#else
+	tmp_tc.c_lflag |= ECHO;
+	tmp_tc.c_oflag |= ONLCR;
+	if (crlf)
+		tmp_tc.c_iflag |= ICRNL;
+#endif
+    } else {
+#ifndef	USE_TERMIO
+	sb.sg_flags &= ~ECHO;
+#else
+	tmp_tc.c_lflag &= ~ECHO;
+	tmp_tc.c_oflag &= ~ONLCR;
+# ifdef notdef
+	if (crlf)
+		tmp_tc.c_iflag &= ~ICRNL;
+# endif
+#endif
+    }
+
+    if ((f&MODE_FLOW) == 0) {
+#ifndef	USE_TERMIO
+	tc.t_startc = _POSIX_VDISABLE;
+	tc.t_stopc = _POSIX_VDISABLE;
+#else
+	tmp_tc.c_iflag &= ~(IXOFF|IXON);	/* Leave the IXANY bit alone */
+    } else {
+	if (restartany < 0) {
+		tmp_tc.c_iflag |= IXOFF|IXON;	/* Leave the IXANY bit alone */
+	} else if (restartany > 0) {
+		tmp_tc.c_iflag |= IXOFF|IXON|IXANY;
+	} else {
+		tmp_tc.c_iflag |= IXOFF|IXON;
+		tmp_tc.c_iflag &= ~IXANY;
+	}
+#endif
+    }
+
+    if ((f&MODE_TRAPSIG) == 0) {
+#ifndef	USE_TERMIO
+	tc.t_intrc = _POSIX_VDISABLE;
+	tc.t_quitc = _POSIX_VDISABLE;
+	tc.t_eofc = _POSIX_VDISABLE;
+	ltc.t_suspc = _POSIX_VDISABLE;
+	ltc.t_dsuspc = _POSIX_VDISABLE;
+#else
+	tmp_tc.c_lflag &= ~ISIG;
+#endif
+	localchars = 0;
+    } else {
+#ifdef	USE_TERMIO
+	tmp_tc.c_lflag |= ISIG;
+#endif
+	localchars = 1;
+    }
+
+    if (f&MODE_EDIT) {
+#ifndef	USE_TERMIO
+	sb.sg_flags &= ~CBREAK;
+	sb.sg_flags |= CRMOD;
+#else
+	tmp_tc.c_lflag |= ICANON;
+#endif
+    } else {
+#ifndef	USE_TERMIO
+	sb.sg_flags |= CBREAK;
+	if (f&MODE_ECHO)
+	    sb.sg_flags |= CRMOD;
+	else
+	    sb.sg_flags &= ~CRMOD;
+#else
+	tmp_tc.c_lflag &= ~ICANON;
+	tmp_tc.c_iflag &= ~ICRNL;
+	tmp_tc.c_cc[VMIN] = 1;
+	tmp_tc.c_cc[VTIME] = 0;
+#endif
+    }
+
+    if ((f&(MODE_EDIT|MODE_TRAPSIG)) == 0) {
+#ifndef	USE_TERMIO
+	ltc.t_lnextc = _POSIX_VDISABLE;
+#else
+# ifdef VLNEXT
+	tmp_tc.c_cc[VLNEXT] = (cc_t)(_POSIX_VDISABLE);
+# endif
+#endif
+    }
+
+    if (f&MODE_SOFT_TAB) {
+#ifndef USE_TERMIO
+	sb.sg_flags |= XTABS;
+#else
+# ifdef	OXTABS
+	tmp_tc.c_oflag |= OXTABS;
+# endif
+# ifdef	TABDLY
+	tmp_tc.c_oflag &= ~TABDLY;
+	tmp_tc.c_oflag |= TAB3;
+# endif
+#endif
+    } else {
+#ifndef USE_TERMIO
+	sb.sg_flags &= ~XTABS;
+#else
+# ifdef	OXTABS
+	tmp_tc.c_oflag &= ~OXTABS;
+# endif
+# ifdef	TABDLY
+	tmp_tc.c_oflag &= ~TABDLY;
+# endif
+#endif
+    }
+
+    if (f&MODE_LIT_ECHO) {
+#ifndef USE_TERMIO
+	lmode &= ~LCTLECH;
+#else
+# ifdef	ECHOCTL
+	tmp_tc.c_lflag &= ~ECHOCTL;
+# endif
+#endif
+    } else {
+#ifndef USE_TERMIO
+	lmode |= LCTLECH;
+#else
+# ifdef	ECHOCTL
+	tmp_tc.c_lflag |= ECHOCTL;
+# endif
+#endif
+    }
+
+    if (f == -1) {
+	onoff = 0;
+    } else {
+#ifndef	USE_TERMIO
+	if (f & MODE_OUTBIN)
+		lmode |= LLITOUT;
+	else
+		lmode &= ~LLITOUT;
+
+	if (f & MODE_INBIN)
+		lmode |= LPASS8;
+	else
+		lmode &= ~LPASS8;
+#else
+	if (f & MODE_INBIN)
+		tmp_tc.c_iflag &= ~ISTRIP;
+	else
+		tmp_tc.c_iflag |= ISTRIP;
+	if (f & MODE_OUTBIN) {
+		tmp_tc.c_cflag &= ~(CSIZE|PARENB);
+		tmp_tc.c_cflag |= CS8;
+		tmp_tc.c_oflag &= ~OPOST;
+	} else {
+		tmp_tc.c_cflag &= ~(CSIZE|PARENB);
+		tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);
+		tmp_tc.c_oflag |= OPOST;
+	}
+#endif
+	onoff = 1;
+    }
+
+    if (f != -1) {
+#ifdef	SIGTSTP
+	SIG_FUNC_RET susp();
+#endif	/* SIGTSTP */
+#ifdef	SIGINFO
+	SIG_FUNC_RET ayt();
+#endif
+
+#ifdef	SIGTSTP
+	(void) signal(SIGTSTP, susp);
+#endif	/* SIGTSTP */
+#ifdef	SIGINFO
+	(void) signal(SIGINFO, ayt);
+#endif
+#if	defined(USE_TERMIO) && defined(NOKERNINFO)
+	tmp_tc.c_lflag |= NOKERNINFO;
+#endif
+	/*
+	 * We don't want to process ^Y here.  It's just another
+	 * character that we'll pass on to the back end.  It has
+	 * to process it because it will be processed when the
+	 * user attempts to read it, not when we send it.
+	 */
+#ifndef	USE_TERMIO
+	ltc.t_dsuspc = _POSIX_VDISABLE;
+#else
+# ifdef	VDSUSP
+	tmp_tc.c_cc[VDSUSP] = (cc_t)(_POSIX_VDISABLE);
+# endif
+#endif
+#ifdef	USE_TERMIO
+	/*
+	 * If the VEOL character is already set, then use VEOL2,
+	 * otherwise use VEOL.
+	 */
+	esc = (rlogin != _POSIX_VDISABLE) ? rlogin : escape;
+	if ((tmp_tc.c_cc[VEOL] != esc)
+# ifdef	VEOL2
+	    && (tmp_tc.c_cc[VEOL2] != esc)
+# endif
+	    ) {
+		if (tmp_tc.c_cc[VEOL] == (cc_t)(_POSIX_VDISABLE))
+		    tmp_tc.c_cc[VEOL] = esc;
+# ifdef	VEOL2
+		else if (tmp_tc.c_cc[VEOL2] == (cc_t)(_POSIX_VDISABLE))
+		    tmp_tc.c_cc[VEOL2] = esc;
+# endif
+	}
+#else
+	if (tc.t_brkc == (cc_t)(_POSIX_VDISABLE))
+		tc.t_brkc = esc;
+#endif
+    } else {
+#ifdef	SIGINFO
+	SIG_FUNC_RET ayt_status();
+
+	(void) signal(SIGINFO, ayt_status);
+#endif
+#ifdef	SIGTSTP
+	(void) signal(SIGTSTP, SIG_DFL);
+# ifndef SOLARIS
+	(void) sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));
+# else	SOLARIS
+	(void) sigrelse(SIGTSTP);
+# endif	SOLARIS
+#endif	/* SIGTSTP */
+#ifndef USE_TERMIO
+	ltc = oltc;
+	tc = otc;
+	sb = ottyb;
+	lmode = olmode;
+#else
+	tmp_tc = old_tc;
+#endif
+    }
+#ifndef USE_TERMIO
+    ioctl(tin, TIOCLSET, (char *)&lmode);
+    ioctl(tin, TIOCSLTC, (char *)&ltc);
+    ioctl(tin, TIOCSETC, (char *)&tc);
+    ioctl(tin, TIOCSETN, (char *)&sb);
+#else
+    if (tcsetattr(tin, TCSADRAIN, &tmp_tc) < 0)
+	tcsetattr(tin, TCSANOW, &tmp_tc);
+#endif
+
+#if	(!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR))
+# if	!defined(sysV88)
+    ioctl(tin, FIONBIO, (char *)&onoff);
+    ioctl(tout, FIONBIO, (char *)&onoff);
+# endif
+#endif	/* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */
+#if	defined(TN3270)
+    if (noasynchtty == 0) {
+	ioctl(tin, FIOASYNC, (char *)&onoff);
+    }
+#endif	/* defined(TN3270) */
+
+}
+
+/*
+ * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD).
+ */
+#if B4800 != 4800
+#define	DECODE_BAUD
+#endif
+
+#ifdef	DECODE_BAUD
+#ifndef	B7200
+#define B7200   B4800
+#endif
+
+#ifndef	B14400
+#define B14400  B9600
+#endif
+
+#ifndef	B19200
+# define B19200 B14400
+#endif
+
+#ifndef	B28800
+#define B28800  B19200
+#endif
+
+#ifndef	B38400
+# define B38400 B28800
+#endif
+
+#ifndef B57600
+#define B57600  B38400
+#endif
+
+#ifndef B76800
+#define B76800  B57600
+#endif
+
+#ifndef B115200
+#define B115200 B76800
+#endif
+
+#ifndef B230400
+#define B230400 B115200
+#endif
+
+
+/*
+ * This code assumes that the values B0, B50, B75...
+ * are in ascending order.  They do not have to be
+ * contiguous.
+ */
+struct termspeeds {
+	long speed;
+	long value;
+} termspeeds[] = {
+	{ 0,      B0 },      { 50,    B50 },    { 75,     B75 },
+	{ 110,    B110 },    { 134,   B134 },   { 150,    B150 },
+	{ 200,    B200 },    { 300,   B300 },   { 600,    B600 },
+	{ 1200,   B1200 },   { 1800,  B1800 },  { 2400,   B2400 },
+	{ 4800,   B4800 },   { 7200,  B7200 },  { 9600,   B9600 },
+	{ 14400,  B14400 },  { 19200, B19200 }, { 28800,  B28800 },
+	{ 38400,  B38400 },  { 57600, B57600 }, { 115200, B115200 },
+	{ 230400, B230400 }, { -1,    B230400 }
+};
+#endif	/* DECODE_BAUD */
+
+    void
+TerminalSpeeds(ispeed, ospeed)
+    long *ispeed;
+    long *ospeed;
+{
+#ifdef	DECODE_BAUD
+    register struct termspeeds *tp;
+#endif	/* DECODE_BAUD */
+    register long in, out;
+
+    out = cfgetospeed(&old_tc);
+    in = cfgetispeed(&old_tc);
+    if (in == 0)
+	in = out;
+
+#ifdef	DECODE_BAUD
+    tp = termspeeds;
+    while ((tp->speed != -1) && (tp->value < in))
+	tp++;
+    *ispeed = tp->speed;
+
+    tp = termspeeds;
+    while ((tp->speed != -1) && (tp->value < out))
+	tp++;
+    *ospeed = tp->speed;
+#else	/* DECODE_BAUD */
+	*ispeed = in;
+	*ospeed = out;
+#endif	/* DECODE_BAUD */
+}
+
+    int
+TerminalWindowSize(rows, cols)
+    long *rows, *cols;
+{
+#ifdef	TIOCGWINSZ
+    struct winsize ws;
+
+    if (ioctl(fileno(stdin), TIOCGWINSZ, (char *)&ws) >= 0) {
+	*rows = ws.ws_row;
+	*cols = ws.ws_col;
+	return 1;
+    }
+#endif	/* TIOCGWINSZ */
+    return 0;
+}
+
+    int
+NetClose(fd)
+    int	fd;
+{
+    return close(fd);
+}
+
+
+    void
+NetNonblockingIO(fd, onoff)
+    int fd;
+    int onoff;
+{
+    ioctl(fd, FIONBIO, (char *)&onoff);
+}
+
+#if	defined(TN3270)
+    void
+NetSigIO(fd, onoff)
+    int fd;
+    int onoff;
+{
+    ioctl(fd, FIOASYNC, (char *)&onoff);	/* hear about input */
+}
+
+    void
+NetSetPgrp(fd)
+    int fd;
+{
+    int myPid;
+
+    myPid = getpid();
+    fcntl(fd, F_SETOWN, myPid);
+}
+#endif	/*defined(TN3270)*/
+
+/*
+ * Various signal handling routines.
+ */
+
+    /* ARGSUSED */
+    SIG_FUNC_RET
+deadpeer(sig)
+    int sig;
+{
+	setcommandmode();
+	longjmp(peerdied, -1);
+}
+
+    /* ARGSUSED */
+    SIG_FUNC_RET
+intr(sig)
+    int sig;
+{
+    if (localchars) {
+	intp();
+	return;
+    }
+    setcommandmode();
+    longjmp(toplevel, -1);
+}
+
+    /* ARGSUSED */
+    SIG_FUNC_RET
+intr2(sig)
+    int sig;
+{
+    if (localchars) {
+#ifdef	KLUDGELINEMODE
+	if (kludgelinemode)
+	    sendbrk();
+	else
+#endif
+	    sendabort();
+	return;
+    }
+}
+
+#ifdef	SIGTSTP
+    /* ARGSUSED */
+    SIG_FUNC_RET
+susp(sig)
+    int sig;
+{
+    if ((rlogin != _POSIX_VDISABLE) && rlogin_susp())
+	return;
+    if (localchars)
+	sendsusp();
+}
+#endif
+
+#ifdef	SIGWINCH
+    /* ARGSUSED */
+    SIG_FUNC_RET
+sendwin(sig)
+    int sig;
+{
+    if (connected) {
+	sendnaws();
+    }
+}
+#endif
+
+#ifdef	SIGINFO
+    /* ARGSUSED */
+    SIG_FUNC_RET
+ayt(sig)
+    int sig;
+{
+    if (connected)
+	sendayt();
+    else
+	ayt_status();
+}
+#endif
+
+
+    void
+sys_telnet_init()
+{
+    (void) signal(SIGINT, intr);
+    (void) signal(SIGQUIT, intr2);
+    (void) signal(SIGPIPE, deadpeer);
+#ifdef	SIGWINCH
+    (void) signal(SIGWINCH, sendwin);
+#endif
+#ifdef	SIGTSTP
+    (void) signal(SIGTSTP, susp);
+#endif
+#ifdef	SIGINFO
+    (void) signal(SIGINFO, ayt);
+#endif
+
+    setconnmode(0);
+
+    NetNonblockingIO(net, 1);
+
+#if	defined(TN3270)
+    if (noasynchnet == 0) {			/* DBX can't handle! */
+	NetSigIO(net, 1);
+	NetSetPgrp(net);
+    }
+#endif	/* defined(TN3270) */
+
+#if	defined(SO_OOBINLINE)
+    if (SetSockOpt(net, SOL_SOCKET, SO_OOBINLINE, 1) == -1) {
+	perror("SetSockOpt");
+    }
+#endif	/* defined(SO_OOBINLINE) */
+}
+
+/*
+ * Process rings -
+ *
+ *	This routine tries to fill up/empty our various rings.
+ *
+ *	The parameter specifies whether this is a poll operation,
+ *	or a block-until-something-happens operation.
+ *
+ *	The return value is 1 if something happened, 0 if not.
+ */
+
+    int
+process_rings(netin, netout, netex, ttyin, ttyout, poll)
+    int poll;		/* If 0, then block until something to do */
+{
+    register int c;
+		/* One wants to be a bit careful about setting returnValue
+		 * to one, since a one implies we did some useful work,
+		 * and therefore probably won't be called to block next
+		 * time (TN3270 mode only).
+		 */
+    int returnValue = 0;
+    static struct timeval TimeValue = { 0 };
+
+    if (netout) {
+	FD_SET(net, &obits);
+    }
+    if (ttyout) {
+	FD_SET(tout, &obits);
+    }
+#if	defined(TN3270)
+    if (ttyin) {
+	FD_SET(tin, &ibits);
+    }
+#else	/* defined(TN3270) */
+    if (ttyin) {
+	FD_SET(tin, &ibits);
+    }
+#endif	/* defined(TN3270) */
+#if	defined(TN3270)
+    if (netin) {
+	FD_SET(net, &ibits);
+    }
+#   else /* !defined(TN3270) */
+    if (netin) {
+	FD_SET(net, &ibits);
+    }
+#   endif /* !defined(TN3270) */
+    if (netex) {
+	FD_SET(net, &xbits);
+    }
+    if ((c = select(16, &ibits, &obits, &xbits,
+			(poll == 0)? (struct timeval *)0 : &TimeValue)) < 0) {
+	if (c == -1) {
+		    /*
+		     * we can get EINTR if we are in line mode,
+		     * and the user does an escape (TSTP), or
+		     * some other signal generator.
+		     */
+	    if (errno == EINTR) {
+		return 0;
+	    }
+#	    if defined(TN3270)
+		    /*
+		     * we can get EBADF if we were in transparent
+		     * mode, and the transcom process died.
+		    */
+	    if (errno == EBADF) {
+			/*
+			 * zero the bits (even though kernel does it)
+			 * to make sure we are selecting on the right
+			 * ones.
+			*/
+		FD_ZERO(&ibits);
+		FD_ZERO(&obits);
+		FD_ZERO(&xbits);
+		return 0;
+	    }
+#	    endif /* defined(TN3270) */
+		    /* I don't like this, does it ever happen? */
+	    printf("sleep(5) from telnet, after select\r\n");
+	    sleep(5);
+	}
+	return 0;
+    }
+
+    /*
+     * Any urgent data?
+     */
+    if (FD_ISSET(net, &xbits)) {
+	FD_CLR(net, &xbits);
+	SYNCHing = 1;
+	(void) ttyflush(1);	/* flush already enqueued data */
+    }
+
+    /*
+     * Something to read from the network...
+     */
+    if (FD_ISSET(net, &ibits)) {
+	int canread;
+
+	FD_CLR(net, &ibits);
+	canread = ring_empty_consecutive(&netiring);
+#if	!defined(SO_OOBINLINE)
+	    /*
+	     * In 4.2 (and some early 4.3) systems, the
+	     * OOB indication and data handling in the kernel
+	     * is such that if two separate TCP Urgent requests
+	     * come in, one byte of TCP data will be overlaid.
+	     * This is fatal for Telnet, but we try to live
+	     * with it.
+	     *
+	     * In addition, in 4.2 (and...), a special protocol
+	     * is needed to pick up the TCP Urgent data in
+	     * the correct sequence.
+	     *
+	     * What we do is:  if we think we are in urgent
+	     * mode, we look to see if we are "at the mark".
+	     * If we are, we do an OOB receive.  If we run
+	     * this twice, we will do the OOB receive twice,
+	     * but the second will fail, since the second
+	     * time we were "at the mark", but there wasn't
+	     * any data there (the kernel doesn't reset
+	     * "at the mark" until we do a normal read).
+	     * Once we've read the OOB data, we go ahead
+	     * and do normal reads.
+	     *
+	     * There is also another problem, which is that
+	     * since the OOB byte we read doesn't put us
+	     * out of OOB state, and since that byte is most
+	     * likely the TELNET DM (data mark), we would
+	     * stay in the TELNET SYNCH (SYNCHing) state.
+	     * So, clocks to the rescue.  If we've "just"
+	     * received a DM, then we test for the
+	     * presence of OOB data when the receive OOB
+	     * fails (and AFTER we did the normal mode read
+	     * to clear "at the mark").
+	     */
+	if (SYNCHing) {
+	    int atmark;
+	    static int bogus_oob = 0, first = 1;
+
+	    ioctl(net, SIOCATMARK, (char *)&atmark);
+	    if (atmark) {
+		c = recv(net, netiring.supply, canread, MSG_OOB);
+		if ((c == -1) && (errno == EINVAL)) {
+		    c = recv(net, netiring.supply, canread, 0);
+		    if (clocks.didnetreceive < clocks.gotDM) {
+			SYNCHing = stilloob(net);
+		    }
+		} else if (first && c > 0) {
+		    /*
+		     * Bogosity check.  Systems based on 4.2BSD
+		     * do not return an error if you do a second
+		     * recv(MSG_OOB).  So, we do one.  If it
+		     * succeeds and returns exactly the same
+		     * data, then assume that we are running
+		     * on a broken system and set the bogus_oob
+		     * flag.  (If the data was different, then
+		     * we probably got some valid new data, so
+		     * increment the count...)
+		     */
+		    int i;
+		    i = recv(net, netiring.supply + c, canread - c, MSG_OOB);
+		    if (i == c &&
+			 memcmp(netiring.supply, netiring.supply + c, i) == 0) {
+			bogus_oob = 1;
+			first = 0;
+		    } else if (i < 0) {
+			bogus_oob = 0;
+			first = 0;
+		    } else
+			c += i;
+		}
+		if (bogus_oob && c > 0) {
+		    int i;
+		    /*
+		     * Bogosity.  We have to do the read
+		     * to clear the atmark to get out of
+		     * an infinate loop.
+		     */
+		    i = read(net, netiring.supply + c, canread - c);
+		    if (i > 0)
+			c += i;
+		}
+	    } else {
+		c = recv(net, netiring.supply, canread, 0);
+	    }
+	} else {
+	    c = recv(net, netiring.supply, canread, 0);
+	}
+	settimer(didnetreceive);
+#else	/* !defined(SO_OOBINLINE) */
+	c = recv(net, (char *)netiring.supply, canread, 0);
+#endif	/* !defined(SO_OOBINLINE) */
+	if (c < 0 && errno == EWOULDBLOCK) {
+	    c = 0;
+	} else if (c <= 0) {
+	    return -1;
+	}
+	if (netdata) {
+	    Dump('<', netiring.supply, c);
+	}
+	if (c)
+	    ring_supplied(&netiring, c);
+	returnValue = 1;
+    }
+
+    /*
+     * Something to read from the tty...
+     */
+    if (FD_ISSET(tin, &ibits)) {
+	FD_CLR(tin, &ibits);
+	c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring));
+	if (c < 0 && errno == EIO)
+	    c = 0;
+	if (c < 0 && errno == EWOULDBLOCK) {
+	    c = 0;
+	} else {
+	    /* EOF detection for line mode!!!! */
+	    if ((c == 0) && MODE_LOCAL_CHARS(globalmode) && isatty(tin)) {
+			/* must be an EOF... */
+		*ttyiring.supply = termEofChar;
+		c = 1;
+	    }
+	    if (c <= 0) {
+		return -1;
+	    }
+	    if (termdata) {
+		Dump('<', ttyiring.supply, c);
+	    }
+	    ring_supplied(&ttyiring, c);
+	}
+	returnValue = 1;		/* did something useful */
+    }
+
+    if (FD_ISSET(net, &obits)) {
+	FD_CLR(net, &obits);
+	returnValue |= netflush();
+    }
+    if (FD_ISSET(tout, &obits)) {
+	FD_CLR(tout, &obits);
+	returnValue |= (ttyflush(SYNCHing|flushout) > 0);
+    }
+
+    return returnValue;
+}
diff --git a/telnet.tproj/telnet.1 b/telnet.tproj/telnet.1
new file mode 100644
index 0000000..b996fea
--- /dev/null
+++ b/telnet.tproj/telnet.1
@@ -0,0 +1,1366 @@
+.\" Copyright (c) 1983, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)telnet.1	8.6 (Berkeley) 6/1/94
+.\"
+.Dd June 1, 1994
+.Dt TELNET 1
+.Os BSD 4.2
+.Sh NAME
+.Nm telnet
+.Nd user interface to the 
+.Tn TELNET
+protocol
+.Sh SYNOPSIS
+.Nm telnet
+.Op Fl 8EFKLacdfrx
+.Op Fl S Ar tos
+.Op Fl X Ar authtype
+.Op Fl e Ar escapechar
+.Op Fl k Ar realm
+.Op Fl l Ar user
+.Op Fl n Ar tracefile
+.Oo
+.Ar host
+.Op port
+.Oc
+.Sh DESCRIPTION
+The
+.Nm telnet
+command
+is used to communicate with another host using the 
+.Tn TELNET
+protocol.
+If
+.Nm telnet
+is invoked without the
+.Ar host
+argument, it enters command mode,
+indicated by its prompt
+.Pq Nm telnet\&> .
+In this mode, it accepts and executes the commands listed below.
+If it is invoked with arguments, it performs an
+.Ic open
+command with those arguments.
+.Pp
+Options:
+.Bl -tag -width indent
+.It Fl 8
+Specifies an 8-bit data path.  This causes an attempt to
+negotiate the
+.Dv TELNET BINARY
+option on both input and output.
+.It Fl E
+Stops any character from being recognized as an escape character.
+.It Fl F
+If Kerberos V5 authentication is being used, the
+.Fl F
+option allows the local credentials to be forwarded
+to the remote system, including any credentials that
+have already been forwarded into the local environment.
+.It Fl K
+Specifies no automatic login to the remote system.
+.It Fl L
+Specifies an 8-bit data path on output.  This causes the
+BINARY option to be negotiated on output.
+.It Fl S Ar tos
+Sets the IP type-of-service (TOS) option for the telnet
+connection to the value
+.Ar tos,
+which can be a numeric TOS value
+or, on systems that support it, a symbolic
+TOS name found in the /etc/iptos file.
+.It Fl X Ar atype 
+Disables the
+.Ar atype
+type of authentication.
+.It Fl a
+Attempt automatic login.
+Currently, this sends the user name via the
+.Ev USER
+variable
+of the
+.Ev ENVIRON
+option if supported by the remote system.
+The name used is that of the current user as returned by
+.Xr getlogin 2
+if it agrees with the current user ID,
+otherwise it is the name associated with the user ID.
+.It Fl c
+Disables the reading of the user's
+.Pa \&.telnetrc
+file.  (See the
+.Ic toggle skiprc
+command on this man page.)
+.It Fl d
+Sets the initial value of the
+.Ic debug
+toggle to
+.Dv TRUE
+.It Fl e Ar escape char 
+Sets the initial
+.Nm
+.Nm telnet
+escape character to
+.Ar escape char.
+If
+.Ar escape char
+is omitted, then
+there will be no escape character.
+.It Fl f
+If Kerberos V5 authentication is being used, the
+.Fl f
+option allows the local credentials to be forwarded to the remote system.
+.ne 1i
+.It Fl k Ar realm
+If Kerberos authentication is being used, the
+.Fl k
+option requests that telnet obtain tickets for the remote host in
+realm realm instead of the remote host's realm, as determined
+by
+.Xr krb_realmofhost 3 .
+.It Fl l Ar user 
+When connecting to the remote system, if the remote system
+understands the
+.Ev ENVIRON
+option, then
+.Ar user
+will be sent to the remote system as the value for the variable USER.
+This option implies the
+.Fl a
+option.
+This option may also be used with the
+.Ic open
+command.
+.It Fl n Ar tracefile 
+Opens
+.Ar tracefile
+for recording trace information.
+See the
+.Ic set tracefile
+command below.
+.It Fl r
+Specifies a user interface similar to
+.Xr rlogin 1 .
+In this
+mode, the escape character is set to the tilde (~) character,
+unless modified by the -e option.
+.It Fl x
+Turns on encryption of the data stream if possible.  This
+option is not available outside of the United States and
+Canada.
+.It Ar host
+Indicates the official name, an alias, or the Internet address
+of a remote host.
+.It Ar port
+Indicates a port number (address of an application).  If a number is
+not specified, the default
+.Nm telnet
+port is used.
+.El
+.Pp
+When in rlogin mode, a line of the form ~.  disconnects from the
+remote host; ~ is the telnet escape character.
+Similarly, the line ~^Z suspends the telnet session.
+The line ~^] escapes to the normal telnet escape prompt.
+.Pp
+Once a connection has been opened,
+.Nm telnet
+will attempt to enable the
+.Dv TELNET LINEMODE
+option.
+If this fails, then
+.Nm telnet
+will revert to one of two input modes:
+either \*(Lqcharacter at a time\*(Rq
+or \*(Lqold line by line\*(Rq
+depending on what the remote system supports.
+.Pp
+When 
+.Dv LINEMODE
+is enabled, character processing is done on the
+local system, under the control of the remote system.  When input
+editing or character echoing is to be disabled, the remote system
+will relay that information.  The remote system will also relay
+changes to any special characters that happen on the remote
+system, so that they can take effect on the local system.
+.Pp
+In \*(Lqcharacter at a time\*(Rq mode, most
+text typed is immediately sent to the remote host for processing.
+.Pp
+In \*(Lqold line by line\*(Rq mode, all text is echoed locally,
+and (normally) only completed lines are sent to the remote host.
+The \*(Lqlocal echo character\*(Rq (initially \*(Lq^E\*(Rq) may be used
+to turn off and on the local echo
+(this would mostly be used to enter passwords
+without the password being echoed).
+.Pp
+If the 
+.Dv LINEMODE
+option is enabled, or if the
+.Ic localchars
+toggle is
+.Dv TRUE
+(the default for \*(Lqold line by line\*(Lq; see below),
+the user's
+.Ic quit  ,
+.Ic intr ,
+and
+.Ic flush
+characters are trapped locally, and sent as
+.Tn TELNET
+protocol sequences to the remote side.
+If 
+.Dv LINEMODE
+has ever been enabled, then the user's
+.Ic susp
+and
+.Ic eof
+are also sent as
+.Tn TELNET
+protocol sequences,
+and
+.Ic quit
+is sent as a 
+.Dv TELNET ABORT
+instead of 
+.Dv BREAK
+There are options (see
+.Ic toggle
+.Ic autoflush
+and
+.Ic toggle
+.Ic autosynch
+below)
+which cause this action to flush subsequent output to the terminal
+(until the remote host acknowledges the
+.Tn TELNET
+sequence) and flush previous terminal input
+(in the case of
+.Ic quit
+and
+.Ic intr  ) .
+.Pp
+While connected to a remote host,
+.Nm telnet
+command mode may be entered by typing the
+.Nm telnet
+\*(Lqescape character\*(Rq (initially \*(Lq^]\*(Rq).
+When in command mode, the normal terminal editing conventions are available.
+.Pp
+The following
+.Nm telnet
+commands are available.
+Only enough of each command to uniquely identify it need be typed
+(this is also true for arguments to the
+.Ic mode  ,
+.Ic set ,
+.Ic toggle  ,
+.Ic unset ,
+.Ic slc  ,
+.Ic environ ,
+and
+.Ic display
+commands).
+.Pp
+.Bl -tag -width "mode type"
+.It Ic auth Ar argument ... 
+The auth command manipulates the information sent through the
+.Dv TELNET AUTHENTICATE
+option.  Valid arguments for the
+auth command are as follows:
+.Bl -tag -width "disable type"
+.It Ic disable Ar type
+Disables the specified type of authentication.  To
+obtain a list of available types, use the
+.Ic auth disable \&?
+command.
+.It Ic enable Ar type
+Enables the specified type of authentication.  To
+obtain a list of available types, use the
+.Ic auth enable \&?
+command.
+.It Ic status
+Lists the current status of the various types of
+authentication.
+.El
+.It Ic close
+Close a
+.Tn TELNET
+session and return to command mode.
+.It Ic display Ar argument ... 
+Displays all, or some, of the
+.Ic set
+and
+.Ic toggle
+values (see below).
+.It Ic encrypt Ar argument ...
+The encrypt command manipulates the information sent through the
+.Dv TELNET ENCRYPT
+option.
+.Pp
+Note:  Because of export controls, the
+.Dv TELNET ENCRYPT
+option is not supported outside of the United States and Canada.
+.Pp
+Valid arguments for the encrypt command are as follows:
+.Bl -tag -width Ar
+.It Ic disable Ar type Ic [input|output]
+Disables the specified type of encryption.  If you
+omit the input and output, both input and output
+are disabled.  To obtain a list of available
+types, use the
+.Ic encrypt disable \&?
+command.
+.It Ic enable Ar type Ic [input|output]
+Enables the specified type of encryption.  If you
+omit input and output, both input and output are
+enabled.  To obtain a list of available types, use the
+.Ic encrypt enable \&?
+command.
+.It Ic input
+This is the same as the
+.Ic encrypt start input
+command.
+.It Ic -input
+This is the same as the
+.Ic encrypt stop input
+command.
+.It Ic output
+This is the same as the
+.Ic encrypt start output
+command.
+.It Ic -output
+This is the same as the
+.Ic encrypt stop output
+command.
+.It Ic start Ic [input|output]
+Attempts to start encryption.  If you omit
+.Ic input
+and
+.Ic output,
+both input and output are enabled.  To
+obtain a list of available types, use the
+.Ic encrypt enable \&?
+command.
+.It Ic status
+Lists the current status of encryption.
+.It Ic stop Ic [input|output]
+Stops encryption.  If you omit input and output,
+encryption is on both input and output.
+.It Ic type Ar type
+Sets the default type of encryption to be used
+with later
+.Ic encrypt start
+or
+.Ic encrypt stop
+commands.
+.El
+.It Ic environ Ar arguments... 
+The
+.Ic environ
+command is used to manipulate the
+the variables that my be sent through the
+.Dv TELNET ENVIRON
+option.
+The initial set of variables is taken from the users
+environment, with only the
+.Ev DISPLAY
+and
+.Ev PRINTER
+variables being exported by default.
+The
+.Ev USER
+variable is also exported if the
+.Fl a
+or
+.Fl l
+options are used.
+.br
+Valid arguments for the
+.Ic environ
+command are:
+.Bl -tag -width Fl
+.It Ic define Ar variable value 
+Define the variable
+.Ar variable
+to have a value of
+.Ar value.
+Any variables defined by this command are automatically exported.
+The
+.Ar value
+may be enclosed in single or double quotes so
+that tabs and spaces may be included.
+.It Ic undefine Ar variable 
+Remove
+.Ar variable
+from the list of environment variables.
+.It Ic export Ar variable 
+Mark the variable
+.Ar variable
+to be exported to the remote side.
+.It Ic unexport Ar variable 
+Mark the variable
+.Ar variable
+to not be exported unless
+explicitly asked for by the remote side.
+.It Ic list
+List the current set of environment variables.
+Those marked with a
+.Cm *
+will be sent automatically,
+other variables will only be sent if explicitly requested.
+.It Ic \&?
+Prints out help information for the
+.Ic environ
+command.
+.El
+.It Ic logout
+Sends the
+.Dv TELNET LOGOUT
+option to the remote side.
+This command is similar to a
+.Ic close
+command; however, if the remote side does not support the
+.Dv LOGOUT
+option, nothing happens.
+If, however, the remote side does support the
+.Dv LOGOUT
+option, this command should cause the remote side to close the
+.Tn TELNET
+connection.
+If the remote side also supports the concept of
+suspending a user's session for later reattachment,
+the logout argument indicates that you
+should terminate the session immediately.
+.It Ic mode Ar type 
+.Ar Type
+is one of several options, depending on the state of the
+.Tn TELNET
+session.
+The remote host is asked for permission to go into the requested mode.
+If the remote host is capable of entering that mode, the requested
+mode will be entered.
+.Bl -tag -width Ar
+.It Ic character
+Disable the
+.Dv TELNET LINEMODE
+option, or, if the remote side does not understand the
+.Dv LINEMODE
+option, then enter \*(Lqcharacter at a time\*(Lq mode.
+.It Ic line
+Enable the
+.Dv TELNET LINEMODE
+option, or, if the remote side does not understand the
+.Dv LINEMODE
+option, then attempt to enter \*(Lqold-line-by-line\*(Lq mode.
+.It Ic isig Pq Ic \-isig 
+Attempt to enable (disable) the 
+.Dv TRAPSIG
+mode of the 
+.Dv LINEMODE
+option.
+This requires that the 
+.Dv LINEMODE
+option be enabled.
+.It Ic edit Pq Ic \-edit 
+Attempt to enable (disable) the 
+.Dv EDIT
+mode of the 
+.Dv LINEMODE
+option.
+This requires that the 
+.Dv LINEMODE
+option be enabled.
+.It Ic softtabs Pq Ic \-softtabs 
+Attempt to enable (disable) the 
+.Dv SOFT_TAB
+mode of the 
+.Dv LINEMODE
+option.
+This requires that the 
+.Dv LINEMODE
+option be enabled.
+.ne 1i
+.It Ic litecho Pq Ic \-litecho 
+Attempt to enable (disable) the 
+.Dv LIT_ECHO
+mode of the 
+.Dv LINEMODE
+option.
+This requires that the 
+.Dv LINEMODE
+option be enabled.
+.It Ic \&?
+Prints out help information for the
+.Ic mode
+command.
+.El
+.It Xo
+.Ic open Ar host
+.Oo Op Fl l
+.Ar user
+.Oc Ns Oo Fl
+.Ar port Oc
+.Xc
+Open a connection to the named host.
+If no port number
+is specified,
+.Nm telnet
+will attempt to contact a
+.Tn TELNET
+server at the default port.
+The host specification may be either a host name (see
+.Xr hosts  5  )
+or an Internet address specified in the \*(Lqdot notation\*(Rq (see
+.Xr inet 3 ) .
+The
+.Op Fl l
+option may be used to specify the user name
+to be passed to the remote system via the
+.Ev ENVIRON
+option.
+When connecting to a non-standard port,
+.Nm telnet
+omits any automatic initiation of
+.Tn TELNET
+options.  When the port number is preceded by a minus sign,
+the initial option negotiation is done.
+After establishing a connection, the file
+.Pa \&.telnetrc
+in the
+users home directory is opened.  Lines beginning with a # are
+comment lines.  Blank lines are ignored.  Lines that begin
+without white space are the start of a machine entry.  The
+first thing on the line is the name of the machine that is
+being connected to.  The rest of the line, and successive
+lines that begin with white space are assumed to be
+.Nm telnet
+commands and are processed as if they had been typed
+in manually to the
+.Nm telnet
+command prompt.
+.It Ic quit
+Close any open
+.Tn TELNET
+session and exit
+.Nm telnet  .
+An end of file (in command mode) will also close a session and exit.
+.It Ic send Ar arguments 
+Sends one or more special character sequences to the remote host.
+The following are the arguments which may be specified
+(more than one argument may be specified at a time):
+.Pp
+.Bl -tag -width escape
+.It Ic abort
+Sends the
+.Dv TELNET ABORT
+(Abort
+processes)
+sequence.
+.It Ic ao
+Sends the
+.Dv TELNET AO
+(Abort Output) sequence, which should cause the remote system to flush
+all output
+.Em from
+the remote system
+.Em to
+the user's terminal.
+.It Ic ayt
+Sends the
+.Dv TELNET AYT
+(Are You There)
+sequence, to which the remote system may or may not choose to respond.
+.It Ic brk
+Sends the
+.Dv TELNET BRK
+(Break) sequence, which may have significance to the remote
+system.
+.It Ic ec
+Sends the
+.Dv TELNET EC
+(Erase Character)
+sequence, which should cause the remote system to erase the last character
+entered.
+.It Ic el
+Sends the
+.Dv TELNET EL
+(Erase Line)
+sequence, which should cause the remote system to erase the line currently
+being entered.
+.It Ic eof
+Sends the
+.Dv TELNET EOF
+(End Of File)
+sequence.
+.It Ic eor
+Sends the
+.Dv TELNET EOR
+(End of Record)
+sequence.
+.It Ic escape
+Sends the current
+.Nm telnet
+escape character (initially \*(Lq^\*(Rq).
+.It Ic ga
+Sends the
+.Dv TELNET GA
+(Go Ahead)
+sequence, which likely has no significance to the remote system.
+.It Ic getstatus
+If the remote side supports the
+.Dv TELNET STATUS
+command,
+.Ic getstatus
+will send the subnegotiation to request that the server send
+its current option status.
+.ne 1i
+.It Ic ip
+Sends the
+.Dv TELNET IP
+(Interrupt Process) sequence, which should cause the remote
+system to abort the currently running process.
+.It Ic nop
+Sends the
+.Dv TELNET NOP
+(No OPeration)
+sequence.
+.It Ic susp
+Sends the
+.Dv TELNET SUSP
+(SUSPend process)
+sequence.
+.It Ic synch
+Sends the
+.Dv TELNET SYNCH
+sequence.
+This sequence causes the remote system to discard all previously typed
+(but not yet read) input.
+This sequence is sent as
+.Tn TCP
+urgent
+data (and may not work if the remote system is a
+.Bx 4.2
+system -- if
+it doesn't work, a lower case \*(Lqr\*(Rq may be echoed on the terminal).
+.It Ic do Ar cmd
+.It Ic dont Ar cmd
+.It Ic will Ar cmd
+.It Ic wont Ar cmd
+Sends the
+.Dv TELNET DO
+.Ar cmd
+sequence.
+.Ar Cmd
+can be either a decimal number between 0 and 255,
+or a symbolic name for a specific
+.Dv TELNET
+command.
+.Ar Cmd
+can also be either
+.Ic help
+or
+.Ic \&?
+to print out help information, including
+a list of known symbolic names.
+.It Ic \&?
+Prints out help information for the
+.Ic send
+command.
+.El
+.It Ic set Ar argument value 
+.It Ic unset Ar argument value 
+The
+.Ic set
+command will set any one of a number of
+.Nm telnet
+variables to a specific value or to
+.Dv TRUE .
+The special value
+.Ic off
+turns off the function associated with
+the variable, this is equivalent to using the
+.Ic unset
+command.
+The
+.Ic unset
+command will disable or set to
+.Dv FALSE
+any of the specified functions.
+The values of variables may be interrogated with the
+.Ic display
+command.
+The variables which may be set or unset, but not toggled, are
+listed here.  In addition, any of the variables for the
+.Ic toggle
+command may be explicitly set or unset using
+the
+.Ic set
+and
+.Ic unset
+commands.
+.Bl -tag -width escape
+.It Ic ayt
+If
+.Tn TELNET
+is in localchars mode, or
+.Dv LINEMODE
+is enabled, and the status character is typed, a
+.Dv TELNET AYT
+sequence (see
+.Ic send ayt
+preceding) is sent to the
+remote host.  The initial value for the "Are You There"
+character is the terminal's status character.
+.It Ic echo
+This is the value (initially \*(Lq^E\*(Rq) which, when in
+\*(Lqline by line\*(Rq mode, toggles between doing local echoing
+of entered characters (for normal processing), and suppressing
+echoing of entered characters (for entering, say, a password).
+.It Ic eof
+If
+.Nm telnet
+is operating in
+.Dv LINEMODE
+or \*(Lqold line by line\*(Rq mode, entering this character
+as the first character on a line will cause this character to be
+sent to the remote system.
+The initial value of the eof character is taken to be the terminal's
+.Ic eof
+character.
+.It Ic erase
+If
+.Nm telnet
+is in
+.Ic localchars
+mode (see
+.Ic toggle
+.Ic localchars
+below),
+.Sy and
+if
+.Nm telnet
+is operating in \*(Lqcharacter at a time\*(Rq mode, then when this
+character is typed, a
+.Dv TELNET EC
+sequence (see
+.Ic send
+.Ic ec
+above)
+is sent to the remote system.
+The initial value for the erase character is taken to be
+the terminal's
+.Ic erase
+character.
+.It Ic escape
+This is the
+.Nm telnet
+escape character (initially \*(Lq^[\*(Rq) which causes entry
+into
+.Nm telnet
+command mode (when connected to a remote system).
+.It Ic flushoutput
+If
+.Nm telnet
+is in
+.Ic localchars
+mode (see
+.Ic toggle
+.Ic localchars
+below)
+and the
+.Ic flushoutput
+character is typed, a
+.Dv TELNET AO
+sequence (see
+.Ic send
+.Ic ao
+above)
+is sent to the remote host.
+The initial value for the flush character is taken to be
+the terminal's
+.Ic flush
+character.
+.It Ic forw1
+.It Ic forw2
+If
+.Tn TELNET
+is operating in
+.Dv LINEMODE ,
+these are the
+characters that, when typed, cause partial lines to be
+forwarded to the remote system.  The initial value for
+the forwarding characters are taken from the terminal's
+eol and eol2 characters.
+.It Ic interrupt
+If
+.Nm telnet
+is in
+.Ic localchars
+mode (see
+.Ic toggle
+.Ic localchars
+below)
+and the
+.Ic interrupt
+character is typed, a
+.Dv TELNET IP
+sequence (see
+.Ic send
+.Ic ip
+above)
+is sent to the remote host.
+The initial value for the interrupt character is taken to be
+the terminal's
+.Ic intr
+character.
+.It Ic kill
+If
+.Nm telnet
+is in
+.Ic localchars
+mode (see
+.Ic toggle
+.Ic localchars
+below),
+.Ic and
+if
+.Nm telnet
+is operating in \*(Lqcharacter at a time\*(Rq mode, then when this
+character is typed, a
+.Dv TELNET EL
+sequence (see
+.Ic send
+.Ic el
+above)
+is sent to the remote system.
+The initial value for the kill character is taken to be
+the terminal's
+.Ic kill
+character.
+.It Ic lnext
+If
+.Nm telnet
+is operating in
+.Dv LINEMODE
+or \*(Lqold line by line\*(Lq mode, then this character is taken to
+be the terminal's
+.Ic lnext
+character.
+The initial value for the lnext character is taken to be
+the terminal's
+.Ic lnext
+character.
+.It Ic quit
+If
+.Nm telnet
+is in
+.Ic localchars
+mode (see
+.Ic toggle
+.Ic localchars
+below)
+and the
+.Ic quit
+character is typed, a
+.Dv TELNET BRK
+sequence (see
+.Ic send
+.Ic brk
+above)
+is sent to the remote host.
+The initial value for the quit character is taken to be
+the terminal's
+.Ic quit
+character.
+.It Ic reprint
+If
+.Nm telnet
+is operating in
+.Dv LINEMODE
+or \*(Lqold line by line\*(Lq mode, then this character is taken to
+be the terminal's
+.Ic reprint
+character.
+The initial value for the reprint character is taken to be
+the terminal's
+.Ic reprint
+character.
+.It Ic rlogin
+This is the rlogin escape character.
+If set, the normal
+.Tn TELNET
+escape character is ignored unless it is
+preceded by this character at the beginning of a line.
+This character, at the beginning of a line followed by
+a "."  closes the connection; when followed by a ^Z it
+suspends the telnet command.  The initial state is to
+disable the rlogin escape character.
+.It Ic start
+If the
+.Dv TELNET TOGGLE-FLOW-CONTROL
+option has been enabled,
+then this character is taken to
+be the terminal's
+.Ic start
+character.
+The initial value for the kill character is taken to be
+the terminal's
+.Ic start
+character.
+.It Ic stop
+If the
+.Dv TELNET TOGGLE-FLOW-CONTROL
+option has been enabled,
+then this character is taken to
+be the terminal's
+.Ic stop
+character.
+The initial value for the kill character is taken to be
+the terminal's
+.Ic stop
+character.
+.It Ic susp
+If
+.Nm telnet
+is in
+.Ic localchars
+mode, or
+.Dv LINEMODE
+is enabled, and the
+.Ic suspend
+character is typed, a
+.Dv TELNET SUSP
+sequence (see
+.Ic send
+.Ic susp
+above)
+is sent to the remote host.
+The initial value for the suspend character is taken to be
+the terminal's
+.Ic suspend
+character.
+.ne 1i
+.It Ic tracefile
+This is the file to which the output, caused by
+.Ic netdata
+or
+.Ic option
+tracing being
+.Dv TRUE ,
+will be written.  If it is set to
+.Dq Fl ,
+then tracing information will be written to standard output (the default).
+.It Ic worderase
+If
+.Nm telnet
+is operating in
+.Dv LINEMODE
+or \*(Lqold line by line\*(Lq mode, then this character is taken to
+be the terminal's
+.Ic worderase
+character.
+The initial value for the worderase character is taken to be
+the terminal's
+.Ic worderase
+character.
+.It Ic \&?
+Displays the legal
+.Ic set
+.Pq Ic unset
+commands.
+.El
+.It Ic slc Ar state 
+The
+.Ic slc
+command (Set Local Characters) is used to set
+or change the state of the the special
+characters when the 
+.Dv TELNET LINEMODE
+option has
+been enabled.  Special characters are characters that get
+mapped to 
+.Tn TELNET
+commands sequences (like
+.Ic ip
+or
+.Ic quit  )
+or line editing characters (like
+.Ic erase
+and
+.Ic kill  ) .
+By default, the local special characters are exported.
+.Bl -tag -width Fl
+.It Ic check
+Verify the current settings for the current special characters.
+The remote side is requested to send all the current special
+character settings, and if there are any discrepancies with
+the local side, the local side will switch to the remote value.
+.It Ic export
+Switch to the local defaults for the special characters.  The
+local default characters are those of the local terminal at
+the time when
+.Nm telnet
+was started.
+.It Ic import
+Switch to the remote defaults for the special characters.
+The remote default characters are those of the remote system
+at the time when the 
+.Tn TELNET
+connection was established.
+.It Ic \&?
+Prints out help information for the
+.Ic slc
+command.
+.El
+.It Ic status
+Show the current status of
+.Nm telnet  .
+This includes the peer one is connected to, as well
+as the current mode.
+.It Ic toggle Ar arguments ... 
+Toggle (between
+.Dv TRUE
+and
+.Dv FALSE )
+various flags that control how
+.Nm telnet
+responds to events.
+These flags may be set explicitly to
+.Dv TRUE
+or
+.Dv FALSE
+using the
+.Ic set
+and
+.Ic unset
+commands listed above.
+More than one argument may be specified.
+The state of these flags may be interrogated with the
+.Ic display
+command.
+Valid arguments are:
+.Bl -tag -width Ar
+.It Ic authdebug
+Turns on debugging information for the authentication code.
+.It Ic autoflush
+If
+.Ic autoflush
+and
+.Ic localchars
+are both
+.Dv TRUE ,
+then when the
+.Ic ao  ,
+or
+.Ic quit
+characters are recognized (and transformed into
+.Tn TELNET
+sequences; see
+.Ic set
+above for details),
+.Nm telnet
+refuses to display any data on the user's terminal
+until the remote system acknowledges (via a
+.Dv TELNET TIMING MARK
+option)
+that it has processed those
+.Tn TELNET
+sequences.
+The initial value for this toggle is
+.Dv TRUE
+if the terminal user had not
+done an "stty noflsh", otherwise
+.Dv FALSE
+(see
+.Xr stty  1  ) .
+.It Ic autodecrypt
+When the
+.Dv TELNET ENCRYPT
+option is negotiated, by
+default the actual encryption (decryption) of the data
+stream does not start automatically.  The autoencrypt
+(autodecrypt) command states that encryption of the
+output (input) stream should be enabled as soon as
+possible.
+.sp
+.Pp
+Note:  Because of export controls, the
+.Dv TELNET ENCRYPT
+option is not supported outside the United States and Canada.
+.It Ic autologin
+If the remote side supports the
+.Dv TELNET AUTHENTICATION
+option
+.Tn TELNET
+attempts to use it to perform automatic authentication.  If the
+.Dv AUTHENTICATION
+option is not supported, the user's login
+name are propagated through the
+.Dv TELNET ENVIRON
+option.
+This command is the same as specifying
+.Ar a
+option on the
+.Ic open
+command.
+.It Ic autosynch
+If
+.Ic autosynch
+and
+.Ic localchars
+are both
+.Dv TRUE ,
+then when either the
+.Ic intr
+or
+.Ic quit
+characters is typed (see
+.Ic set
+above for descriptions of the
+.Ic intr
+and
+.Ic quit
+characters), the resulting
+.Tn TELNET
+sequence sent is followed by the
+.Dv TELNET SYNCH
+sequence.
+This procedure
+.Ic should
+cause the remote system to begin throwing away all previously
+typed input until both of the
+.Tn TELNET
+sequences have been read and acted upon.
+The initial value of this toggle is
+.Dv FALSE .
+.It Ic binary
+Enable or disable the
+.Dv TELNET BINARY
+option on both input and output.
+.It Ic inbinary
+Enable or disable the
+.Dv TELNET BINARY
+option on input.
+.It Ic outbinary
+Enable or disable the
+.Dv TELNET BINARY
+option on output.
+.It Ic crlf
+If this is
+.Dv TRUE ,
+then carriage returns will be sent as
+.Li <CR><LF> .
+If this is
+.Dv FALSE ,
+then carriage returns will be send as
+.Li <CR><NUL> .
+The initial value for this toggle is
+.Dv FALSE .
+.It Ic crmod
+Toggle carriage return mode.
+When this mode is enabled, most carriage return characters received from
+the remote host will be mapped into a carriage return followed by
+a line feed.
+This mode does not affect those characters typed by the user, only
+those received from the remote host.
+This mode is not very useful unless the remote host
+only sends carriage return, but never line feed.
+The initial value for this toggle is
+.Dv FALSE .
+.It Ic debug
+Toggles socket level debugging (useful only to the
+.Ic super user  ) .
+The initial value for this toggle is
+.Dv FALSE .
+.It Ic encdebug
+Turns on debugging information for the encryption code.
+.It Ic localchars
+If this is
+.Dv TRUE ,
+then the
+.Ic flush  ,
+.Ic interrupt ,
+.Ic quit  ,
+.Ic erase ,
+and
+.Ic kill
+characters (see
+.Ic set
+above) are recognized locally, and transformed into (hopefully) appropriate
+.Tn TELNET
+control sequences
+(respectively
+.Ic ao  ,
+.Ic ip ,
+.Ic brk  ,
+.Ic ec ,
+and
+.Ic el  ;
+see
+.Ic send
+above).
+The initial value for this toggle is
+.Dv TRUE
+in \*(Lqold line by line\*(Rq mode,
+and
+.Dv FALSE
+in \*(Lqcharacter at a time\*(Rq mode.
+When the
+.Dv LINEMODE
+option is enabled, the value of
+.Ic localchars
+is ignored, and assumed to always be
+.Dv TRUE .
+If
+.Dv LINEMODE
+has ever been enabled, then
+.Ic quit
+is sent as
+.Ic abort  ,
+and
+.Ic eof and
+.B suspend
+are sent as
+.Ic eof and
+.Ic susp ,
+see
+.Ic send
+above).
+.It Ic netdata
+Toggles the display of all network data (in hexadecimal format).
+The initial value for this toggle is
+.Dv FALSE .
+.It Ic options
+Toggles the display of some internal
+.Nm telnet
+protocol processing (having to do with
+.Tn TELNET
+options).
+The initial value for this toggle is
+.Dv FALSE .
+.ne 1i
+.It Ic prettydump
+When the
+.Ic netdata
+toggle is enabled, if
+.Ic prettydump
+is enabled the output from the
+.Ic netdata
+command will be formatted in a more user readable format.
+Spaces are put between each character in the output, and the
+beginning of any
+.Tn TELNET
+escape sequence is preceded by a '*' to aid in locating them.
+.It Ic skiprc
+When the skiprc toggle is
+.Dv TRUE ,
+.Tn TELNET
+skips the reading of the
+.Pa \&.telnetrc
+file in the users home
+directory when connections are opened.  The initial
+value for this toggle is
+.Dv FALSE.
+.It Ic termdata
+Toggles the display of all terminal data (in hexadecimal format).
+The initial value for this toggle is
+.Dv FALSE .
+.It Ic verbose_encrypt
+When the
+.Ic verbose_encrypt
+toggle is
+.Dv TRUE ,
+.Tn TELNET
+prints out a message each time encryption is enabled or
+disabled.  The initial value for this toggle is
+.Dv FALSE.
+Note:  Because of export controls, data encryption
+is not supported outside of the United States and Canada.
+.It Ic \&?
+Displays the legal
+.Ic toggle
+commands.
+.El
+.It Ic z
+Suspend
+.Nm telnet  .
+This command only works when the user is using the
+.Xr csh  1  .
+.It Ic \&! Op Ar command 
+Execute a single command in a subshell on the local
+system.  If
+.Ic command
+is omitted, then an interactive
+subshell is invoked.
+.It Ic \&? Op Ar command 
+Get help.  With no arguments,
+.Nm telnet
+prints a help summary.
+If a command is specified,
+.Nm telnet
+will print the help information for just that command.
+.El
+.Sh ENVIRONMENT
+.Nm Telnet
+uses at least the
+.Ev HOME ,
+.Ev SHELL ,
+.Ev DISPLAY ,
+and
+.Ev TERM
+environment variables.
+Other environment variables may be propagated
+to the other side via the
+.Dv TELNET ENVIRON
+option.
+.Sh FILES
+.Bl -tag -width ~/.telnetrc -compact
+.It Pa ~/.telnetrc
+user customized telnet startup values
+.El
+.Sh HISTORY
+The
+.Nm Telnet
+command appeared in
+.Bx 4.2 .
+.Sh NOTES
+.Pp
+On some remote systems, echo has to be turned off manually when in
+\*(Lqold line by line\*(Rq mode.
+.Pp
+In \*(Lqold line by line\*(Rq mode or 
+.Dv LINEMODE
+the terminal's
+.Ic eof
+character is only recognized (and sent to the remote system)
+when it is the first character on a line.
diff --git a/telnet.tproj/telnet.c b/telnet.tproj/telnet.c
new file mode 100644
index 0000000..e1a974f
--- /dev/null
+++ b/telnet.tproj/telnet.c
@@ -0,0 +1,2673 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)telnet.c	8.4 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#include <sys/types.h>
+
+#if	defined(unix) || defined(__APPLE__)
+#include <signal.h>
+/* By the way, we need to include curses.h before telnet.h since,
+ * among other things, telnet.h #defines 'DO', which is a variable
+ * declared in curses.h.
+ */
+#endif	/* defined(unix) || defined(__APPLE__) */
+
+#include <arpa/telnet.h>
+
+#include <ctype.h>
+
+#include "ring.h"
+
+#include "defines.h"
+#include "externs.h"
+#include "types.h"
+#include "general.h"
+
+
+#define	strip(x) ((my_want_state_is_wont(TELOPT_BINARY)) ? ((x)&0x7f) : (x))
+
+static unsigned char	subbuffer[SUBBUFSIZE],
+			*subpointer, *subend;	 /* buffer for sub-options */
+#define	SB_CLEAR()	subpointer = subbuffer;
+#define	SB_TERM()	{ subend = subpointer; SB_CLEAR(); }
+#define	SB_ACCUM(c)	if (subpointer < (subbuffer+sizeof subbuffer)) { \
+				*subpointer++ = (c); \
+			}
+
+#define	SB_GET()	((*subpointer++)&0xff)
+#define	SB_PEEK()	((*subpointer)&0xff)
+#define	SB_EOF()	(subpointer >= subend)
+#define	SB_LEN()	(subend - subpointer)
+
+char	options[256];		/* The combined options */
+char	do_dont_resp[256];
+char	will_wont_resp[256];
+
+int
+	eight = 0,
+	autologin = 0,	/* Autologin anyone? */
+	skiprc = 0,
+	connected,
+	showoptions,
+	In3270,		/* Are we in 3270 mode? */
+	ISend,		/* trying to send network data in */
+	debug = 0,
+	crmod,
+	netdata,	/* Print out network data flow */
+	crlf,		/* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */
+#if	defined(TN3270)
+	noasynchtty = 0,/* User specified "-noasynch" on command line */
+	noasynchnet = 0,/* User specified "-noasynch" on command line */
+	askedSGA = 0,	/* We have talked about suppress go ahead */
+#endif	/* defined(TN3270) */
+	telnetport,
+	SYNCHing,	/* we are in TELNET SYNCH mode */
+	flushout,	/* flush output */
+	autoflush = 0,	/* flush output when interrupting? */
+	autosynch,	/* send interrupt characters with SYNCH? */
+	localflow,	/* we handle flow control locally */
+	restartany,	/* if flow control enabled, restart on any character */
+	localchars,	/* we recognize interrupt/quit */
+	donelclchars,	/* the user has set "localchars" */
+	donebinarytoggle,	/* the user has put us in binary */
+	dontlecho,	/* do we suppress local echoing right now? */
+	globalmode;
+
+char *prompt = 0;
+
+cc_t escape;
+cc_t rlogin;
+#ifdef	KLUDGELINEMODE
+cc_t echoc;
+#endif
+
+/*
+ * Telnet receiver states for fsm
+ */
+#define	TS_DATA		0
+#define	TS_IAC		1
+#define	TS_WILL		2
+#define	TS_WONT		3
+#define	TS_DO		4
+#define	TS_DONT		5
+#define	TS_CR		6
+#define	TS_SB		7		/* sub-option collection */
+#define	TS_SE		8		/* looking for sub-option end */
+
+static int	telrcv_state;
+#ifdef	OLD_ENVIRON
+unsigned char telopt_environ = TELOPT_NEW_ENVIRON;
+#else
+# define telopt_environ TELOPT_NEW_ENVIRON
+#endif
+
+jmp_buf	toplevel = { 0 };
+jmp_buf	peerdied;
+
+int	flushline;
+int	linemode;
+
+#ifdef	KLUDGELINEMODE
+int	kludgelinemode = 1;
+#endif
+
+/*
+ * The following are some clocks used to decide how to interpret
+ * the relationship between various variables.
+ */
+
+Clocks clocks;
+
+#ifdef	notdef
+Modelist modelist[] = {
+	{ "telnet command mode", COMMAND_LINE },
+	{ "character-at-a-time mode", 0 },
+	{ "character-at-a-time mode (local echo)", LOCAL_ECHO|LOCAL_CHARS },
+	{ "line-by-line mode (remote echo)", LINE | LOCAL_CHARS },
+	{ "line-by-line mode", LINE | LOCAL_ECHO | LOCAL_CHARS },
+	{ "line-by-line mode (local echoing suppressed)", LINE | LOCAL_CHARS },
+	{ "3270 mode", 0 },
+};
+#endif
+
+
+/*
+ * Initialize telnet environment.
+ */
+
+    void
+init_telnet()
+{
+    env_init();
+
+    SB_CLEAR();
+    ClearArray(options);
+
+    connected = In3270 = ISend = localflow = donebinarytoggle = 0;
+#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
+    auth_encrypt_connect(connected);
+#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION)  */
+    restartany = -1;
+
+    SYNCHing = 0;
+
+    /* Don't change NetTrace */
+
+    escape = CONTROL(']');
+    rlogin = _POSIX_VDISABLE;
+#ifdef	KLUDGELINEMODE
+    echoc = CONTROL('E');
+#endif
+
+    flushline = 1;
+    telrcv_state = TS_DATA;
+}
+
+
+#ifdef	notdef
+#include <varargs.h>
+
+    /*VARARGS*/
+    static void
+printring(va_alist)
+    va_dcl
+{
+    va_list ap;
+    char buffer[100];		/* where things go */
+    char *ptr;
+    char *format;
+    char *string;
+    Ring *ring;
+    int i;
+
+    va_start(ap);
+
+    ring = va_arg(ap, Ring *);
+    format = va_arg(ap, char *);
+    ptr = buffer;
+
+    while ((i = *format++) != 0) {
+	if (i == '%') {
+	    i = *format++;
+	    switch (i) {
+	    case 'c':
+		*ptr++ = va_arg(ap, int);
+		break;
+	    case 's':
+		string = va_arg(ap, char *);
+		ring_supply_data(ring, buffer, ptr-buffer);
+		ring_supply_data(ring, string, strlen(string));
+		ptr = buffer;
+		break;
+	    case 0:
+		ExitString("printring: trailing %%.\n", 1);
+		/*NOTREACHED*/
+	    default:
+		ExitString("printring: unknown format character.\n", 1);
+		/*NOTREACHED*/
+	    }
+	} else {
+	    *ptr++ = i;
+	}
+    }
+    ring_supply_data(ring, buffer, ptr-buffer);
+}
+#endif
+
+/*
+ * These routines are in charge of sending option negotiations
+ * to the other side.
+ *
+ * The basic idea is that we send the negotiation if either side
+ * is in disagreement as to what the current state should be.
+ */
+
+    void
+send_do(c, init)
+    register int c, init;
+{
+    if (init) {
+	if (((do_dont_resp[c] == 0) && my_state_is_do(c)) ||
+				my_want_state_is_do(c))
+	    return;
+	set_my_want_state_do(c);
+	do_dont_resp[c]++;
+    }
+    NET2ADD(IAC, DO);
+    NETADD(c);
+    printoption("SENT", DO, c);
+}
+
+    void
+send_dont(c, init)
+    register int c, init;
+{
+    if (init) {
+	if (((do_dont_resp[c] == 0) && my_state_is_dont(c)) ||
+				my_want_state_is_dont(c))
+	    return;
+	set_my_want_state_dont(c);
+	do_dont_resp[c]++;
+    }
+    NET2ADD(IAC, DONT);
+    NETADD(c);
+    printoption("SENT", DONT, c);
+}
+
+    void
+send_will(c, init)
+    register int c, init;
+{
+    if (init) {
+	if (((will_wont_resp[c] == 0) && my_state_is_will(c)) ||
+				my_want_state_is_will(c))
+	    return;
+	set_my_want_state_will(c);
+	will_wont_resp[c]++;
+    }
+    NET2ADD(IAC, WILL);
+    NETADD(c);
+    printoption("SENT", WILL, c);
+}
+
+    void
+send_wont(c, init)
+    register int c, init;
+{
+    if (init) {
+	if (((will_wont_resp[c] == 0) && my_state_is_wont(c)) ||
+				my_want_state_is_wont(c))
+	    return;
+	set_my_want_state_wont(c);
+	will_wont_resp[c]++;
+    }
+    NET2ADD(IAC, WONT);
+    NETADD(c);
+    printoption("SENT", WONT, c);
+}
+
+
+	void
+willoption(option)
+	int option;
+{
+	int new_state_ok = 0;
+
+	if (do_dont_resp[option]) {
+	    --do_dont_resp[option];
+	    if (do_dont_resp[option] && my_state_is_do(option))
+		--do_dont_resp[option];
+	}
+
+	if ((do_dont_resp[option] == 0) && my_want_state_is_dont(option)) {
+
+	    switch (option) {
+
+	    case TELOPT_ECHO:
+#	    if defined(TN3270)
+		/*
+		 * The following is a pain in the rear-end.
+		 * Various IBM servers (some versions of Wiscnet,
+		 * possibly Fibronics/Spartacus, and who knows who
+		 * else) will NOT allow us to send "DO SGA" too early
+		 * in the setup proceedings.  On the other hand,
+		 * 4.2 servers (telnetd) won't set SGA correctly.
+		 * So, we are stuck.  Empirically (but, based on
+		 * a VERY small sample), the IBM servers don't send
+		 * out anything about ECHO, so we postpone our sending
+		 * "DO SGA" until we see "WILL ECHO" (which 4.2 servers
+		 * DO send).
+		  */
+		{
+		    if (askedSGA == 0) {
+			askedSGA = 1;
+			if (my_want_state_is_dont(TELOPT_SGA))
+			    send_do(TELOPT_SGA, 1);
+		    }
+		}
+		    /* Fall through */
+	    case TELOPT_EOR:
+#endif	    /* defined(TN3270) */
+	    case TELOPT_BINARY:
+	    case TELOPT_SGA:
+		settimer(modenegotiated);
+		/* FALL THROUGH */
+	    case TELOPT_STATUS:
+#if	defined(AUTHENTICATION)
+	    case TELOPT_AUTHENTICATION:
+#endif
+#ifdef	ENCRYPTION
+	    case TELOPT_ENCRYPT:
+#endif /* ENCRYPTION */
+		new_state_ok = 1;
+		break;
+
+	    case TELOPT_TM:
+		if (flushout)
+		    flushout = 0;
+		/*
+		 * Special case for TM.  If we get back a WILL,
+		 * pretend we got back a WONT.
+		 */
+		set_my_want_state_dont(option);
+		set_my_state_dont(option);
+		return;			/* Never reply to TM will's/wont's */
+
+	    case TELOPT_LINEMODE:
+	    default:
+		break;
+	    }
+
+	    if (new_state_ok) {
+		set_my_want_state_do(option);
+		send_do(option, 0);
+		setconnmode(0);		/* possibly set new tty mode */
+	    } else {
+		do_dont_resp[option]++;
+		send_dont(option, 0);
+	    }
+	}
+	set_my_state_do(option);
+#ifdef	ENCRYPTION
+	if (option == TELOPT_ENCRYPT)
+		encrypt_send_support();
+#endif	/* ENCRYPTION */
+}
+
+	void
+wontoption(option)
+	int option;
+{
+	if (do_dont_resp[option]) {
+	    --do_dont_resp[option];
+	    if (do_dont_resp[option] && my_state_is_dont(option))
+		--do_dont_resp[option];
+	}
+
+	if ((do_dont_resp[option] == 0) && my_want_state_is_do(option)) {
+
+	    switch (option) {
+
+#ifdef	KLUDGELINEMODE
+	    case TELOPT_SGA:
+		if (!kludgelinemode)
+		    break;
+		/* FALL THROUGH */
+#endif
+	    case TELOPT_ECHO:
+		settimer(modenegotiated);
+		break;
+
+	    case TELOPT_TM:
+		if (flushout)
+		    flushout = 0;
+		set_my_want_state_dont(option);
+		set_my_state_dont(option);
+		return;		/* Never reply to TM will's/wont's */
+
+	    default:
+		break;
+	    }
+	    set_my_want_state_dont(option);
+	    if (my_state_is_do(option))
+		send_dont(option, 0);
+	    setconnmode(0);			/* Set new tty mode */
+	} else if (option == TELOPT_TM) {
+	    /*
+	     * Special case for TM.
+	     */
+	    if (flushout)
+		flushout = 0;
+	    set_my_want_state_dont(option);
+	}
+	set_my_state_dont(option);
+}
+
+	static void
+dooption(option)
+	int option;
+{
+	int new_state_ok = 0;
+
+	if (will_wont_resp[option]) {
+	    --will_wont_resp[option];
+	    if (will_wont_resp[option] && my_state_is_will(option))
+		--will_wont_resp[option];
+	}
+
+	if (will_wont_resp[option] == 0) {
+	  if (my_want_state_is_wont(option)) {
+
+	    switch (option) {
+
+	    case TELOPT_TM:
+		/*
+		 * Special case for TM.  We send a WILL, but pretend
+		 * we sent WONT.
+		 */
+		send_will(option, 0);
+		set_my_want_state_wont(TELOPT_TM);
+		set_my_state_wont(TELOPT_TM);
+		return;
+
+#	if defined(TN3270)
+	    case TELOPT_EOR:		/* end of record */
+#	endif	/* defined(TN3270) */
+	    case TELOPT_BINARY:		/* binary mode */
+	    case TELOPT_NAWS:		/* window size */
+	    case TELOPT_TSPEED:		/* terminal speed */
+	    case TELOPT_LFLOW:		/* local flow control */
+	    case TELOPT_TTYPE:		/* terminal type option */
+	    case TELOPT_SGA:		/* no big deal */
+#ifdef	ENCRYPTION
+	    case TELOPT_ENCRYPT:	/* encryption variable option */
+#endif	/* ENCRYPTION */
+		new_state_ok = 1;
+		break;
+
+	    case TELOPT_NEW_ENVIRON:	/* New environment variable option */
+#ifdef	OLD_ENVIRON
+		if (my_state_is_will(TELOPT_OLD_ENVIRON))
+			send_wont(TELOPT_OLD_ENVIRON, 1); /* turn off the old */
+		goto env_common;
+	    case TELOPT_OLD_ENVIRON:	/* Old environment variable option */
+		if (my_state_is_will(TELOPT_NEW_ENVIRON))
+			break;		/* Don't enable if new one is in use! */
+	    env_common:
+		telopt_environ = option;
+#endif
+		new_state_ok = 1;
+		break;
+
+#if	defined(AUTHENTICATION)
+	    case TELOPT_AUTHENTICATION:
+		if (autologin)
+			new_state_ok = 1;
+		break;
+#endif
+
+	    case TELOPT_XDISPLOC:	/* X Display location */
+		if (env_getvalue((unsigned char *)"DISPLAY"))
+		    new_state_ok = 1;
+		break;
+
+	    case TELOPT_LINEMODE:
+#ifdef	KLUDGELINEMODE
+		kludgelinemode = 0;
+		send_do(TELOPT_SGA, 1);
+#endif
+		set_my_want_state_will(TELOPT_LINEMODE);
+		send_will(option, 0);
+		set_my_state_will(TELOPT_LINEMODE);
+		slc_init();
+		return;
+
+	    case TELOPT_ECHO:		/* We're never going to echo... */
+	    default:
+		break;
+	    }
+
+	    if (new_state_ok) {
+		set_my_want_state_will(option);
+		send_will(option, 0);
+		setconnmode(0);			/* Set new tty mode */
+	    } else {
+		will_wont_resp[option]++;
+		send_wont(option, 0);
+	    }
+	  } else {
+	    /*
+	     * Handle options that need more things done after the
+	     * other side has acknowledged the option.
+	     */
+	    switch (option) {
+	    case TELOPT_LINEMODE:
+#ifdef	KLUDGELINEMODE
+		kludgelinemode = 0;
+		send_do(TELOPT_SGA, 1);
+#endif
+		set_my_state_will(option);
+		slc_init();
+		send_do(TELOPT_SGA, 0);
+		return;
+	    }
+	  }
+	}
+	set_my_state_will(option);
+}
+
+	static void
+dontoption(option)
+	int option;
+{
+
+	if (will_wont_resp[option]) {
+	    --will_wont_resp[option];
+	    if (will_wont_resp[option] && my_state_is_wont(option))
+		--will_wont_resp[option];
+	}
+
+	if ((will_wont_resp[option] == 0) && my_want_state_is_will(option)) {
+	    switch (option) {
+	    case TELOPT_LINEMODE:
+		linemode = 0;	/* put us back to the default state */
+		break;
+#ifdef	OLD_ENVIRON
+	    case TELOPT_NEW_ENVIRON:
+		/*
+		 * The new environ option wasn't recognized, try
+		 * the old one.
+		 */
+		send_will(TELOPT_OLD_ENVIRON, 1);
+		telopt_environ = TELOPT_OLD_ENVIRON;
+		break;
+#endif
+	    }
+	    /* we always accept a DONT */
+	    set_my_want_state_wont(option);
+	    if (my_state_is_will(option))
+		send_wont(option, 0);
+	    setconnmode(0);			/* Set new tty mode */
+	}
+	set_my_state_wont(option);
+}
+
+/*
+ * Given a buffer returned by tgetent(), this routine will turn
+ * the pipe seperated list of names in the buffer into an array
+ * of pointers to null terminated names.  We toss out any bad,
+ * duplicate, or verbose names (names with spaces).
+ */
+
+static char *name_unknown = "UNKNOWN";
+static char *unknown[] = { 0, 0 };
+
+	char **
+mklist(buf, name)
+	char *buf, *name;
+{
+	register int n;
+	register char c, *cp, **argvp, *cp2, **argv, **avt;
+
+	if (name) {
+		if ((int)strlen(name) > 40) {
+			name = 0;
+			unknown[0] = name_unknown;
+		} else {
+			unknown[0] = name;
+			upcase(name);
+		}
+	} else
+		unknown[0] = name_unknown;
+	/*
+	 * Count up the number of names.
+	 */
+	for (n = 1, cp = buf; *cp && *cp != ':'; cp++) {
+		if (*cp == '|')
+			n++;
+	}
+	/*
+	 * Allocate an array to put the name pointers into
+	 */
+	argv = (char **)malloc((n+3)*sizeof(char *));
+	if (argv == 0)
+		return(unknown);
+
+	/*
+	 * Fill up the array of pointers to names.
+	 */
+	*argv = 0;
+	argvp = argv+1;
+	n = 0;
+	for (cp = cp2 = buf; (c = *cp);  cp++) {
+		if (c == '|' || c == ':') {
+			*cp++ = '\0';
+			/*
+			 * Skip entries that have spaces or are over 40
+			 * characters long.  If this is our environment
+			 * name, then put it up front.  Otherwise, as
+			 * long as this is not a duplicate name (case
+			 * insensitive) add it to the list.
+			 */
+			if (n || (cp - cp2 > 41))
+				;
+			else if (name && (strncasecmp(name, cp2, cp-cp2) == 0))
+				*argv = cp2;
+			else if (is_unique(cp2, argv+1, argvp))
+				*argvp++ = cp2;
+			if (c == ':')
+				break;
+			/*
+			 * Skip multiple delimiters. Reset cp2 to
+			 * the beginning of the next name. Reset n,
+			 * the flag for names with spaces.
+			 */
+			while ((c = *cp) == '|')
+				cp++;
+			cp2 = cp;
+			n = 0;
+		}
+		/*
+		 * Skip entries with spaces or non-ascii values.
+		 * Convert lower case letters to upper case.
+		 */
+		if ((c == ' ') || !isascii(c))
+			n = 1;
+		else if (islower(c))
+			*cp = toupper(c);
+	}
+
+	/*
+	 * Check for an old V6 2 character name.  If the second
+	 * name points to the beginning of the buffer, and is
+	 * only 2 characters long, move it to the end of the array.
+	 */
+	if ((argv[1] == buf) && (strlen(argv[1]) == 2)) {
+		--argvp;
+		for (avt = &argv[1]; avt < argvp; avt++)
+			*avt = *(avt+1);
+		*argvp++ = buf;
+	}
+
+	/*
+	 * Duplicate last name, for TTYPE option, and null
+	 * terminate the array.  If we didn't find a match on
+	 * our terminal name, put that name at the beginning.
+	 */
+	cp = *(argvp-1);
+	*argvp++ = cp;
+	*argvp = 0;
+
+	if (*argv == 0) {
+		if (name)
+			*argv = name;
+		else {
+			--argvp;
+			for (avt = argv; avt < argvp; avt++)
+				*avt = *(avt+1);
+		}
+	}
+	if (*argv)
+		return(argv);
+	else
+		return(unknown);
+}
+
+	int
+is_unique(name, as, ae)
+	register char *name, **as, **ae;
+{
+	register char **ap;
+	register int n;
+
+	n = strlen(name) + 1;
+	for (ap = as; ap < ae; ap++)
+		if (strncasecmp(*ap, name, n) == 0)
+			return(0);
+	return (1);
+}
+
+#ifdef	TERMCAP
+char termbuf[1024];
+
+	/*ARGSUSED*/
+	int
+setupterm(tname, fd, errp)
+	char *tname;
+	int fd, *errp;
+{
+	if (tgetent(termbuf, tname) == 1) {
+		termbuf[1023] = '\0';
+		if (errp)
+			*errp = 1;
+		return(0);
+	}
+	if (errp)
+		*errp = 0;
+	return(-1);
+}
+#else
+#define	termbuf	ttytype
+extern char ttytype[];
+#endif
+
+int resettermname = 1;
+
+	char *
+gettermname()
+{
+	char *tname;
+	static char **tnamep = 0;
+	static char **next;
+	int err;
+
+	if (resettermname) {
+		resettermname = 0;
+		if (tnamep && tnamep != unknown)
+			free(tnamep);
+		if ((tname = (char *)env_getvalue((unsigned char *)"TERM")) &&
+				(setupterm(tname, 1, &err) == 0)) {
+			tnamep = mklist(termbuf, tname);
+		} else {
+			if (tname && ((int)strlen(tname) <= 40)) {
+				unknown[0] = tname;
+				upcase(tname);
+			} else
+				unknown[0] = name_unknown;
+			tnamep = unknown;
+		}
+		next = tnamep;
+	}
+	if (*next == 0)
+		next = tnamep;
+	return(*next++);
+}
+/*
+ * suboption()
+ *
+ *	Look at the sub-option buffer, and try to be helpful to the other
+ * side.
+ *
+ *	Currently we recognize:
+ *
+ *		Terminal type, send request.
+ *		Terminal speed (send request).
+ *		Local flow control (is request).
+ *		Linemode
+ */
+
+    static void
+suboption()
+{
+    unsigned char subchar;
+
+    printsub('<', subbuffer, SB_LEN()+2);
+    switch (subchar = SB_GET()) {
+    case TELOPT_TTYPE:
+	if (my_want_state_is_wont(TELOPT_TTYPE))
+	    return;
+	if (SB_EOF() || SB_GET() != TELQUAL_SEND) {
+	    return;
+	} else {
+	    char *name;
+	    unsigned char temp[50];
+	    int len;
+
+#if	defined(TN3270)
+	    if (tn3270_ttype()) {
+		return;
+	    }
+#endif	/* defined(TN3270) */
+	    name = gettermname();
+	    len = strlen(name) + 4 + 2;
+	    if (len < NETROOM()) {
+		sprintf((char *)temp, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE,
+				TELQUAL_IS, name, IAC, SE);
+		ring_supply_data(&netoring, temp, len);
+		printsub('>', &temp[2], len-2);
+	    } else {
+		ExitString("No room in buffer for terminal type.\n", 1);
+		/*NOTREACHED*/
+	    }
+	}
+	break;
+    case TELOPT_TSPEED:
+	if (my_want_state_is_wont(TELOPT_TSPEED))
+	    return;
+	if (SB_EOF())
+	    return;
+	if (SB_GET() == TELQUAL_SEND) {
+	    long ospeed, ispeed;
+	    unsigned char temp[50];
+	    int len;
+
+	    TerminalSpeeds(&ispeed, &ospeed);
+
+	    sprintf((char *)temp, "%c%c%c%c%d,%d%c%c", IAC, SB, TELOPT_TSPEED,
+		    TELQUAL_IS, ospeed, ispeed, IAC, SE);
+	    len = strlen((char *)temp+4) + 4;	/* temp[3] is 0 ... */
+
+	    if (len < NETROOM()) {
+		ring_supply_data(&netoring, temp, len);
+		printsub('>', temp+2, len - 2);
+	    }
+/*@*/	    else printf("lm_will: not enough room in buffer\n");
+	}
+	break;
+    case TELOPT_LFLOW:
+	if (my_want_state_is_wont(TELOPT_LFLOW))
+	    return;
+	if (SB_EOF())
+	    return;
+	switch(SB_GET()) {
+	case LFLOW_RESTART_ANY:
+	    restartany = 1;
+	    break;
+	case LFLOW_RESTART_XON:
+	    restartany = 0;
+	    break;
+	case LFLOW_ON:
+	    localflow = 1;
+	    break;
+	case LFLOW_OFF:
+	    localflow = 0;
+	    break;
+	default:
+	    return;
+	}
+	setcommandmode();
+	setconnmode(0);
+	break;
+
+    case TELOPT_LINEMODE:
+	if (my_want_state_is_wont(TELOPT_LINEMODE))
+	    return;
+	if (SB_EOF())
+	    return;
+	switch (SB_GET()) {
+	case WILL:
+	    lm_will(subpointer, SB_LEN());
+	    break;
+	case WONT:
+	    lm_wont(subpointer, SB_LEN());
+	    break;
+	case DO:
+	    lm_do(subpointer, SB_LEN());
+	    break;
+	case DONT:
+	    lm_dont(subpointer, SB_LEN());
+	    break;
+	case LM_SLC:
+	    slc(subpointer, SB_LEN());
+	    break;
+	case LM_MODE:
+	    lm_mode(subpointer, SB_LEN(), 0);
+	    break;
+	default:
+	    break;
+	}
+	break;
+
+#ifdef	OLD_ENVIRON
+    case TELOPT_OLD_ENVIRON:
+#endif
+    case TELOPT_NEW_ENVIRON:
+	if (SB_EOF())
+	    return;
+	switch(SB_PEEK()) {
+	case TELQUAL_IS:
+	case TELQUAL_INFO:
+	    if (my_want_state_is_dont(subchar))
+		return;
+	    break;
+	case TELQUAL_SEND:
+	    if (my_want_state_is_wont(subchar)) {
+		return;
+	    }
+	    break;
+	default:
+	    return;
+	}
+	env_opt(subpointer, SB_LEN());
+	break;
+
+    case TELOPT_XDISPLOC:
+	if (my_want_state_is_wont(TELOPT_XDISPLOC))
+	    return;
+	if (SB_EOF())
+	    return;
+	if (SB_GET() == TELQUAL_SEND) {
+	    unsigned char temp[50], *dp;
+	    int len;
+
+	    if ((dp = env_getvalue((unsigned char *)"DISPLAY")) == NULL) {
+		/*
+		 * Something happened, we no longer have a DISPLAY
+		 * variable.  So, turn off the option.
+		 */
+		send_wont(TELOPT_XDISPLOC, 1);
+		break;
+	    }
+	    sprintf((char *)temp, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC,
+		    TELQUAL_IS, dp, IAC, SE);
+	    len = strlen((char *)temp+4) + 4;	/* temp[3] is 0 ... */
+
+	    if (len < NETROOM()) {
+		ring_supply_data(&netoring, temp, len);
+		printsub('>', temp+2, len - 2);
+	    }
+/*@*/	    else printf("lm_will: not enough room in buffer\n");
+	}
+	break;
+
+#if	defined(AUTHENTICATION)
+	case TELOPT_AUTHENTICATION: {
+		if (!autologin)
+			break;
+		if (SB_EOF())
+			return;
+		switch(SB_GET()) {
+		case TELQUAL_IS:
+			if (my_want_state_is_dont(TELOPT_AUTHENTICATION))
+				return;
+			auth_is(subpointer, SB_LEN());
+			break;
+		case TELQUAL_SEND:
+			if (my_want_state_is_wont(TELOPT_AUTHENTICATION))
+				return;
+			auth_send(subpointer, SB_LEN());
+			break;
+		case TELQUAL_REPLY:
+			if (my_want_state_is_wont(TELOPT_AUTHENTICATION))
+				return;
+			auth_reply(subpointer, SB_LEN());
+			break;
+		case TELQUAL_NAME:
+			if (my_want_state_is_dont(TELOPT_AUTHENTICATION))
+				return;
+			auth_name(subpointer, SB_LEN());
+			break;
+		}
+	}
+	break;
+#endif
+#ifdef	ENCRYPTION
+	case TELOPT_ENCRYPT:
+		if (SB_EOF())
+			return;
+		switch(SB_GET()) {
+		case ENCRYPT_START:
+			if (my_want_state_is_dont(TELOPT_ENCRYPT))
+				return;
+			encrypt_start(subpointer, SB_LEN());
+			break;
+		case ENCRYPT_END:
+			if (my_want_state_is_dont(TELOPT_ENCRYPT))
+				return;
+			encrypt_end();
+			break;
+		case ENCRYPT_SUPPORT:
+			if (my_want_state_is_wont(TELOPT_ENCRYPT))
+				return;
+			encrypt_support(subpointer, SB_LEN());
+			break;
+		case ENCRYPT_REQSTART:
+			if (my_want_state_is_wont(TELOPT_ENCRYPT))
+				return;
+			encrypt_request_start(subpointer, SB_LEN());
+			break;
+		case ENCRYPT_REQEND:
+			if (my_want_state_is_wont(TELOPT_ENCRYPT))
+				return;
+			/*
+			 * We can always send an REQEND so that we cannot
+			 * get stuck encrypting.  We should only get this
+			 * if we have been able to get in the correct mode
+			 * anyhow.
+			 */
+			encrypt_request_end();
+			break;
+		case ENCRYPT_IS:
+			if (my_want_state_is_dont(TELOPT_ENCRYPT))
+				return;
+			encrypt_is(subpointer, SB_LEN());
+			break;
+		case ENCRYPT_REPLY:
+			if (my_want_state_is_wont(TELOPT_ENCRYPT))
+				return;
+			encrypt_reply(subpointer, SB_LEN());
+			break;
+		case ENCRYPT_ENC_KEYID:
+			if (my_want_state_is_dont(TELOPT_ENCRYPT))
+				return;
+			encrypt_enc_keyid(subpointer, SB_LEN());
+			break;
+		case ENCRYPT_DEC_KEYID:
+			if (my_want_state_is_wont(TELOPT_ENCRYPT))
+				return;
+			encrypt_dec_keyid(subpointer, SB_LEN());
+			break;
+		default:
+			break;
+		}
+		break;
+#endif	/* ENCRYPTION */
+    default:
+	break;
+    }
+}
+
+static unsigned char str_lm[] = { IAC, SB, TELOPT_LINEMODE, 0, 0, IAC, SE };
+
+    void
+lm_will(cmd, len)
+    unsigned char *cmd;
+    int len;
+{
+    if (len < 1) {
+/*@*/	printf("lm_will: no command!!!\n");	/* Should not happen... */
+	return;
+    }
+    switch(cmd[0]) {
+    case LM_FORWARDMASK:	/* We shouldn't ever get this... */
+    default:
+	str_lm[3] = DONT;
+	str_lm[4] = cmd[0];
+	if (NETROOM() > sizeof(str_lm)) {
+	    ring_supply_data(&netoring, str_lm, sizeof(str_lm));
+	    printsub('>', &str_lm[2], sizeof(str_lm)-2);
+	}
+/*@*/	else printf("lm_will: not enough room in buffer\n");
+	break;
+    }
+}
+
+    void
+lm_wont(cmd, len)
+    unsigned char *cmd;
+    int len;
+{
+    if (len < 1) {
+/*@*/	printf("lm_wont: no command!!!\n");	/* Should not happen... */
+	return;
+    }
+    switch(cmd[0]) {
+    case LM_FORWARDMASK:	/* We shouldn't ever get this... */
+    default:
+	/* We are always DONT, so don't respond */
+	return;
+    }
+}
+
+    void
+lm_do(cmd, len)
+    unsigned char *cmd;
+    int len;
+{
+    if (len < 1) {
+/*@*/	printf("lm_do: no command!!!\n");	/* Should not happen... */
+	return;
+    }
+    switch(cmd[0]) {
+    case LM_FORWARDMASK:
+    default:
+	str_lm[3] = WONT;
+	str_lm[4] = cmd[0];
+	if (NETROOM() > sizeof(str_lm)) {
+	    ring_supply_data(&netoring, str_lm, sizeof(str_lm));
+	    printsub('>', &str_lm[2], sizeof(str_lm)-2);
+	}
+/*@*/	else printf("lm_do: not enough room in buffer\n");
+	break;
+    }
+}
+
+    void
+lm_dont(cmd, len)
+    unsigned char *cmd;
+    int len;
+{
+    if (len < 1) {
+/*@*/	printf("lm_dont: no command!!!\n");	/* Should not happen... */
+	return;
+    }
+    switch(cmd[0]) {
+    case LM_FORWARDMASK:
+    default:
+	/* we are always WONT, so don't respond */
+	break;
+    }
+}
+
+static unsigned char str_lm_mode[] = {
+	IAC, SB, TELOPT_LINEMODE, LM_MODE, 0, IAC, SE
+};
+
+	void
+lm_mode(cmd, len, init)
+	unsigned char *cmd;
+	int len, init;
+{
+	if (len != 1)
+		return;
+	if ((linemode&MODE_MASK&~MODE_ACK) == *cmd)
+		return;
+	if (*cmd&MODE_ACK)
+		return;
+	linemode = *cmd&(MODE_MASK&~MODE_ACK);
+	str_lm_mode[4] = linemode;
+	if (!init)
+	    str_lm_mode[4] |= MODE_ACK;
+	if (NETROOM() > sizeof(str_lm_mode)) {
+	    ring_supply_data(&netoring, str_lm_mode, sizeof(str_lm_mode));
+	    printsub('>', &str_lm_mode[2], sizeof(str_lm_mode)-2);
+	}
+/*@*/	else printf("lm_mode: not enough room in buffer\n");
+	setconnmode(0);	/* set changed mode */
+}
+
+
+
+/*
+ * slc()
+ * Handle special character suboption of LINEMODE.
+ */
+
+struct spc {
+	cc_t val;
+	cc_t *valp;
+	char flags;	/* Current flags & level */
+	char mylevel;	/* Maximum level & flags */
+} spc_data[NSLC+1];
+
+#define SLC_IMPORT	0
+#define	SLC_EXPORT	1
+#define SLC_RVALUE	2
+static int slc_mode = SLC_EXPORT;
+
+	void
+slc_init()
+{
+	register struct spc *spcp;
+
+	localchars = 1;
+	for (spcp = spc_data; spcp < &spc_data[NSLC+1]; spcp++) {
+		spcp->val = 0;
+		spcp->valp = 0;
+		spcp->flags = spcp->mylevel = SLC_NOSUPPORT;
+	}
+
+#define	initfunc(func, flags) { \
+					spcp = &spc_data[func]; \
+					if (spcp->valp = tcval(func)) { \
+					    spcp->val = *spcp->valp; \
+					    spcp->mylevel = SLC_VARIABLE|flags; \
+					} else { \
+					    spcp->val = 0; \
+					    spcp->mylevel = SLC_DEFAULT; \
+					} \
+				    }
+
+	initfunc(SLC_SYNCH, 0);
+	/* No BRK */
+	initfunc(SLC_AO, 0);
+	initfunc(SLC_AYT, 0);
+	/* No EOR */
+	initfunc(SLC_ABORT, SLC_FLUSHIN|SLC_FLUSHOUT);
+	initfunc(SLC_EOF, 0);
+#ifndef	SYSV_TERMIO
+	initfunc(SLC_SUSP, SLC_FLUSHIN);
+#endif
+	initfunc(SLC_EC, 0);
+	initfunc(SLC_EL, 0);
+#ifndef	SYSV_TERMIO
+	initfunc(SLC_EW, 0);
+	initfunc(SLC_RP, 0);
+	initfunc(SLC_LNEXT, 0);
+#endif
+	initfunc(SLC_XON, 0);
+	initfunc(SLC_XOFF, 0);
+#ifdef	SYSV_TERMIO
+	spc_data[SLC_XON].mylevel = SLC_CANTCHANGE;
+	spc_data[SLC_XOFF].mylevel = SLC_CANTCHANGE;
+#endif
+	initfunc(SLC_FORW1, 0);
+#ifdef	USE_TERMIO
+	initfunc(SLC_FORW2, 0);
+	/* No FORW2 */
+#endif
+
+	initfunc(SLC_IP, SLC_FLUSHIN|SLC_FLUSHOUT);
+#undef	initfunc
+
+	if (slc_mode == SLC_EXPORT)
+		slc_export();
+	else
+		slc_import(1);
+
+}
+
+    void
+slcstate()
+{
+    printf("Special characters are %s values\n",
+		slc_mode == SLC_IMPORT ? "remote default" :
+		slc_mode == SLC_EXPORT ? "local" :
+					 "remote");
+}
+
+    void
+slc_mode_export()
+{
+    slc_mode = SLC_EXPORT;
+    if (my_state_is_will(TELOPT_LINEMODE))
+	slc_export();
+}
+
+    void
+slc_mode_import(def)
+    int def;
+{
+    slc_mode = def ? SLC_IMPORT : SLC_RVALUE;
+    if (my_state_is_will(TELOPT_LINEMODE))
+	slc_import(def);
+}
+
+unsigned char slc_import_val[] = {
+	IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_VARIABLE, 0, IAC, SE
+};
+unsigned char slc_import_def[] = {
+	IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_DEFAULT, 0, IAC, SE
+};
+
+    void
+slc_import(def)
+    int def;
+{
+    if (NETROOM() > sizeof(slc_import_val)) {
+	if (def) {
+	    ring_supply_data(&netoring, slc_import_def, sizeof(slc_import_def));
+	    printsub('>', &slc_import_def[2], sizeof(slc_import_def)-2);
+	} else {
+	    ring_supply_data(&netoring, slc_import_val, sizeof(slc_import_val));
+	    printsub('>', &slc_import_val[2], sizeof(slc_import_val)-2);
+	}
+    }
+/*@*/ else printf("slc_import: not enough room\n");
+}
+
+    void
+slc_export()
+{
+    register struct spc *spcp;
+
+    TerminalDefaultChars();
+
+    slc_start_reply();
+    for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {
+	if (spcp->mylevel != SLC_NOSUPPORT) {
+	    if (spcp->val == (cc_t)(_POSIX_VDISABLE))
+		spcp->flags = SLC_NOSUPPORT;
+	    else
+		spcp->flags = spcp->mylevel;
+	    if (spcp->valp)
+		spcp->val = *spcp->valp;
+	    slc_add_reply(spcp - spc_data, spcp->flags, spcp->val);
+	}
+    }
+    slc_end_reply();
+    (void)slc_update();
+    setconnmode(1);	/* Make sure the character values are set */
+}
+
+	void
+slc(cp, len)
+	register unsigned char *cp;
+	int len;
+{
+	register struct spc *spcp;
+	register int func,level;
+
+	slc_start_reply();
+
+	for (; len >= 3; len -=3, cp +=3) {
+
+		func = cp[SLC_FUNC];
+
+		if (func == 0) {
+			/*
+			 * Client side: always ignore 0 function.
+			 */
+			continue;
+		}
+		if (func > NSLC) {
+			if ((cp[SLC_FLAGS] & SLC_LEVELBITS) != SLC_NOSUPPORT)
+				slc_add_reply(func, SLC_NOSUPPORT, 0);
+			continue;
+		}
+
+		spcp = &spc_data[func];
+
+		level = cp[SLC_FLAGS]&(SLC_LEVELBITS|SLC_ACK);
+
+		if ((cp[SLC_VALUE] == (unsigned char)spcp->val) &&
+		    ((level&SLC_LEVELBITS) == (spcp->flags&SLC_LEVELBITS))) {
+			continue;
+		}
+
+		if (level == (SLC_DEFAULT|SLC_ACK)) {
+			/*
+			 * This is an error condition, the SLC_ACK
+			 * bit should never be set for the SLC_DEFAULT
+			 * level.  Our best guess to recover is to
+			 * ignore the SLC_ACK bit.
+			 */
+			cp[SLC_FLAGS] &= ~SLC_ACK;
+		}
+
+		if (level == ((spcp->flags&SLC_LEVELBITS)|SLC_ACK)) {
+			spcp->val = (cc_t)cp[SLC_VALUE];
+			spcp->flags = cp[SLC_FLAGS];	/* include SLC_ACK */
+			continue;
+		}
+
+		level &= ~SLC_ACK;
+
+		if (level <= (spcp->mylevel&SLC_LEVELBITS)) {
+			spcp->flags = cp[SLC_FLAGS]|SLC_ACK;
+			spcp->val = (cc_t)cp[SLC_VALUE];
+		}
+		if (level == SLC_DEFAULT) {
+			if ((spcp->mylevel&SLC_LEVELBITS) != SLC_DEFAULT)
+				spcp->flags = spcp->mylevel;
+			else
+				spcp->flags = SLC_NOSUPPORT;
+		}
+		slc_add_reply(func, spcp->flags, spcp->val);
+	}
+	slc_end_reply();
+	if (slc_update())
+		setconnmode(1);	/* set the  new character values */
+}
+
+    void
+slc_check()
+{
+    register struct spc *spcp;
+
+    slc_start_reply();
+    for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {
+	if (spcp->valp && spcp->val != *spcp->valp) {
+	    spcp->val = *spcp->valp;
+	    if (spcp->val == (cc_t)(_POSIX_VDISABLE))
+		spcp->flags = SLC_NOSUPPORT;
+	    else
+		spcp->flags = spcp->mylevel;
+	    slc_add_reply(spcp - spc_data, spcp->flags, spcp->val);
+	}
+    }
+    slc_end_reply();
+    setconnmode(1);
+}
+
+
+unsigned char slc_reply[128];
+unsigned char *slc_replyp;
+
+	void
+slc_start_reply()
+{
+	slc_replyp = slc_reply;
+	*slc_replyp++ = IAC;
+	*slc_replyp++ = SB;
+	*slc_replyp++ = TELOPT_LINEMODE;
+	*slc_replyp++ = LM_SLC;
+}
+
+	void
+slc_add_reply(func, flags, value)
+	unsigned char func;
+	unsigned char flags;
+	cc_t value;
+{
+	if ((*slc_replyp++ = func) == IAC)
+		*slc_replyp++ = IAC;
+	if ((*slc_replyp++ = flags) == IAC)
+		*slc_replyp++ = IAC;
+	if ((*slc_replyp++ = (unsigned char)value) == IAC)
+		*slc_replyp++ = IAC;
+}
+
+    void
+slc_end_reply()
+{
+    register int len;
+
+    *slc_replyp++ = IAC;
+    *slc_replyp++ = SE;
+    len = slc_replyp - slc_reply;
+    if (len <= 6)
+	return;
+    if (NETROOM() > len) {
+	ring_supply_data(&netoring, slc_reply, slc_replyp - slc_reply);
+	printsub('>', &slc_reply[2], slc_replyp - slc_reply - 2);
+    }
+/*@*/else printf("slc_end_reply: not enough room\n");
+}
+
+	int
+slc_update()
+{
+	register struct spc *spcp;
+	int need_update = 0;
+
+	for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {
+		if (!(spcp->flags&SLC_ACK))
+			continue;
+		spcp->flags &= ~SLC_ACK;
+		if (spcp->valp && (*spcp->valp != spcp->val)) {
+			*spcp->valp = spcp->val;
+			need_update = 1;
+		}
+	}
+	return(need_update);
+}
+
+#ifdef	OLD_ENVIRON
+# ifdef	ENV_HACK
+/*
+ * Earlier version of telnet/telnetd from the BSD code had
+ * the definitions of VALUE and VAR reversed.  To ensure
+ * maximum interoperability, we assume that the server is
+ * an older BSD server, until proven otherwise.  The newer
+ * BSD servers should be able to handle either definition,
+ * so it is better to use the wrong values if we don't
+ * know what type of server it is.
+ */
+int env_auto = 1;
+int old_env_var = OLD_ENV_VAR;
+int old_env_value = OLD_ENV_VALUE;
+# else
+#  define old_env_var OLD_ENV_VAR
+#  define old_env_value OLD_ENV_VALUE
+# endif
+#endif
+
+	void
+env_opt(buf, len)
+	register unsigned char *buf;
+	register int len;
+{
+	register unsigned char *ep = 0, *epc = 0;
+	register int i;
+
+	switch(buf[0]&0xff) {
+	case TELQUAL_SEND:
+		env_opt_start();
+		if (len == 1) {
+			env_opt_add(NULL);
+		} else for (i = 1; i < len; i++) {
+			switch (buf[i]&0xff) {
+#ifdef	OLD_ENVIRON
+			case OLD_ENV_VAR:
+# ifdef	ENV_HACK
+				if (telopt_environ == TELOPT_OLD_ENVIRON
+				    && env_auto) {
+					/* Server has the same definitions */
+					old_env_var = OLD_ENV_VAR;
+					old_env_value = OLD_ENV_VALUE;
+				}
+				/* FALL THROUGH */
+# endif
+			case OLD_ENV_VALUE:
+				/*
+				 * Although OLD_ENV_VALUE is not legal, we will
+				 * still recognize it, just in case it is an
+				 * old server that has VAR & VALUE mixed up...
+				 */
+				/* FALL THROUGH */
+#else
+			case NEW_ENV_VAR:
+#endif
+			case ENV_USERVAR:
+				if (ep) {
+					*epc = 0;
+					env_opt_add(ep);
+				}
+				ep = epc = &buf[i+1];
+				break;
+			case ENV_ESC:
+				i++;
+				/*FALL THROUGH*/
+			default:
+				if (epc)
+					*epc++ = buf[i];
+				break;
+			}
+		}
+		if (ep) {
+			*epc = 0;
+			env_opt_add(ep);
+		}
+		env_opt_end(1);
+		break;
+
+	case TELQUAL_IS:
+	case TELQUAL_INFO:
+		/* Ignore for now.  We shouldn't get it anyway. */
+		break;
+
+	default:
+		break;
+	}
+}
+
+#define	OPT_REPLY_SIZE	256
+unsigned char *opt_reply;
+unsigned char *opt_replyp;
+unsigned char *opt_replyend;
+
+	void
+env_opt_start()
+{
+	if (opt_reply)
+		opt_reply = (unsigned char *)realloc(opt_reply, OPT_REPLY_SIZE);
+	else
+		opt_reply = (unsigned char *)malloc(OPT_REPLY_SIZE);
+	if (opt_reply == NULL) {
+/*@*/		printf("env_opt_start: malloc()/realloc() failed!!!\n");
+		opt_reply = opt_replyp = opt_replyend = NULL;
+		return;
+	}
+	opt_replyp = opt_reply;
+	opt_replyend = opt_reply + OPT_REPLY_SIZE;
+	*opt_replyp++ = IAC;
+	*opt_replyp++ = SB;
+	*opt_replyp++ = telopt_environ;
+	*opt_replyp++ = TELQUAL_IS;
+}
+
+	void
+env_opt_start_info()
+{
+	env_opt_start();
+	if (opt_replyp)
+	    opt_replyp[-1] = TELQUAL_INFO;
+}
+
+	void
+env_opt_add(ep)
+	register unsigned char *ep;
+{
+	register unsigned char *vp, c;
+
+	if (opt_reply == NULL)		/*XXX*/
+		return;			/*XXX*/
+
+	if (ep == NULL || *ep == '\0') {
+		/* Send user defined variables first. */
+		env_default(1, 0);
+		while (ep = env_default(0, 0))
+			env_opt_add(ep);
+
+		/* Now add the list of well know variables.  */
+		env_default(1, 1);
+		while (ep = env_default(0, 1))
+			env_opt_add(ep);
+		return;
+	}
+	vp = env_getvalue(ep);
+	if (opt_replyp + (vp ? strlen((char *)vp) : 0) +
+				strlen((char *)ep) + 6 > opt_replyend)
+	{
+		register int len;
+		opt_replyend += OPT_REPLY_SIZE;
+		len = opt_replyend - opt_reply;
+		opt_reply = (unsigned char *)realloc(opt_reply, len);
+		if (opt_reply == NULL) {
+/*@*/			printf("env_opt_add: realloc() failed!!!\n");
+			opt_reply = opt_replyp = opt_replyend = NULL;
+			return;
+		}
+		opt_replyp = opt_reply + len - (opt_replyend - opt_replyp);
+		opt_replyend = opt_reply + len;
+	}
+	if (opt_welldefined(ep))
+#ifdef	OLD_ENVIRON
+		if (telopt_environ == TELOPT_OLD_ENVIRON)
+			*opt_replyp++ = old_env_var;
+		else
+#endif
+			*opt_replyp++ = NEW_ENV_VAR;
+	else
+		*opt_replyp++ = ENV_USERVAR;
+	for (;;) {
+		while (c = *ep++) {
+			switch(c&0xff) {
+			case IAC:
+				*opt_replyp++ = IAC;
+				break;
+			case NEW_ENV_VAR:
+			case NEW_ENV_VALUE:
+			case ENV_ESC:
+			case ENV_USERVAR:
+				*opt_replyp++ = ENV_ESC;
+				break;
+			}
+			*opt_replyp++ = c;
+		}
+		if (ep = vp) {
+#ifdef	OLD_ENVIRON
+			if (telopt_environ == TELOPT_OLD_ENVIRON)
+				*opt_replyp++ = old_env_value;
+			else
+#endif
+				*opt_replyp++ = NEW_ENV_VALUE;
+			vp = NULL;
+		} else
+			break;
+	}
+}
+
+	int
+opt_welldefined(ep)
+	char *ep;
+{
+	if ((strcmp(ep, "USER") == 0) ||
+	    (strcmp(ep, "DISPLAY") == 0) ||
+	    (strcmp(ep, "PRINTER") == 0) ||
+	    (strcmp(ep, "SYSTEMTYPE") == 0) ||
+	    (strcmp(ep, "JOB") == 0) ||
+	    (strcmp(ep, "ACCT") == 0))
+		return(1);
+	return(0);
+}
+	void
+env_opt_end(emptyok)
+	register int emptyok;
+{
+	register int len;
+
+	len = opt_replyp - opt_reply + 2;
+	if (emptyok || len > 6) {
+		*opt_replyp++ = IAC;
+		*opt_replyp++ = SE;
+		if (NETROOM() > len) {
+			ring_supply_data(&netoring, opt_reply, len);
+			printsub('>', &opt_reply[2], len - 2);
+		}
+/*@*/		else printf("slc_end_reply: not enough room\n");
+	}
+	if (opt_reply) {
+		free(opt_reply);
+		opt_reply = opt_replyp = opt_replyend = NULL;
+	}
+}
+
+
+
+    int
+telrcv()
+{
+    register int c;
+    register int scc;
+    register unsigned char *sbp;
+    int count;
+    int returnValue = 0;
+
+    scc = 0;
+    count = 0;
+    while (TTYROOM() > 2) {
+	if (scc == 0) {
+	    if (count) {
+		ring_consumed(&netiring, count);
+		returnValue = 1;
+		count = 0;
+	    }
+	    sbp = netiring.consume;
+	    scc = ring_full_consecutive(&netiring);
+	    if (scc == 0) {
+		/* No more data coming in */
+		break;
+	    }
+	}
+
+	c = *sbp++ & 0xff, scc--; count++;
+#ifdef	ENCRYPTION
+	if (decrypt_input)
+		c = (*decrypt_input)(c);
+#endif	/* ENCRYPTION */
+
+	switch (telrcv_state) {
+
+	case TS_CR:
+	    telrcv_state = TS_DATA;
+	    if (c == '\0') {
+		break;	/* Ignore \0 after CR */
+	    }
+	    else if ((c == '\n') && my_want_state_is_dont(TELOPT_ECHO) && !crmod) {
+		TTYADD(c);
+		break;
+	    }
+	    /* Else, fall through */
+
+	case TS_DATA:
+	    if (c == IAC) {
+		telrcv_state = TS_IAC;
+		break;
+	    }
+#	    if defined(TN3270)
+	    if (In3270) {
+		*Ifrontp++ = c;
+		while (scc > 0) {
+		    c = *sbp++ & 0377, scc--; count++;
+#ifdef	ENCRYPTION
+		    if (decrypt_input)
+			c = (*decrypt_input)(c);
+#endif	/* ENCRYPTION */
+		    if (c == IAC) {
+			telrcv_state = TS_IAC;
+			break;
+		    }
+		    *Ifrontp++ = c;
+		}
+	    } else
+#	    endif /* defined(TN3270) */
+		    /*
+		     * The 'crmod' hack (see following) is needed
+		     * since we can't * set CRMOD on output only.
+		     * Machines like MULTICS like to send \r without
+		     * \n; since we must turn off CRMOD to get proper
+		     * input, the mapping is done here (sigh).
+		     */
+	    if ((c == '\r') && my_want_state_is_dont(TELOPT_BINARY)) {
+		if (scc > 0) {
+		    c = *sbp&0xff;
+#ifdef	ENCRYPTION
+		    if (decrypt_input)
+			c = (*decrypt_input)(c);
+#endif	/* ENCRYPTION */
+		    if (c == 0) {
+			sbp++, scc--; count++;
+			/* a "true" CR */
+			TTYADD('\r');
+		    } else if (my_want_state_is_dont(TELOPT_ECHO) &&
+					(c == '\n')) {
+			sbp++, scc--; count++;
+			TTYADD('\n');
+		    } else {
+#ifdef	ENCRYPTION
+			if (decrypt_input)
+			    (*decrypt_input)(-1);
+#endif	/* ENCRYPTION */
+
+			TTYADD('\r');
+			if (crmod) {
+				TTYADD('\n');
+			}
+		    }
+		} else {
+		    telrcv_state = TS_CR;
+		    TTYADD('\r');
+		    if (crmod) {
+			    TTYADD('\n');
+		    }
+		}
+	    } else {
+		TTYADD(c);
+	    }
+	    continue;
+
+	case TS_IAC:
+process_iac:
+	    switch (c) {
+
+	    case WILL:
+		telrcv_state = TS_WILL;
+		continue;
+
+	    case WONT:
+		telrcv_state = TS_WONT;
+		continue;
+
+	    case DO:
+		telrcv_state = TS_DO;
+		continue;
+
+	    case DONT:
+		telrcv_state = TS_DONT;
+		continue;
+
+	    case DM:
+		    /*
+		     * We may have missed an urgent notification,
+		     * so make sure we flush whatever is in the
+		     * buffer currently.
+		     */
+		printoption("RCVD", IAC, DM);
+		SYNCHing = 1;
+		(void) ttyflush(1);
+		SYNCHing = stilloob();
+		settimer(gotDM);
+		break;
+
+	    case SB:
+		SB_CLEAR();
+		telrcv_state = TS_SB;
+		continue;
+
+#	    if defined(TN3270)
+	    case EOR:
+		if (In3270) {
+		    if (Ibackp == Ifrontp) {
+			Ibackp = Ifrontp = Ibuf;
+			ISend = 0;	/* should have been! */
+		    } else {
+			Ibackp += DataFromNetwork(Ibackp, Ifrontp-Ibackp, 1);
+			ISend = 1;
+		    }
+		}
+		printoption("RCVD", IAC, EOR);
+		break;
+#	    endif /* defined(TN3270) */
+
+	    case IAC:
+#	    if !defined(TN3270)
+		TTYADD(IAC);
+#	    else /* !defined(TN3270) */
+		if (In3270) {
+		    *Ifrontp++ = IAC;
+		} else {
+		    TTYADD(IAC);
+		}
+#	    endif /* !defined(TN3270) */
+		break;
+
+	    case NOP:
+	    case GA:
+	    default:
+		printoption("RCVD", IAC, c);
+		break;
+	    }
+	    telrcv_state = TS_DATA;
+	    continue;
+
+	case TS_WILL:
+	    printoption("RCVD", WILL, c);
+	    willoption(c);
+	    SetIn3270();
+	    telrcv_state = TS_DATA;
+	    continue;
+
+	case TS_WONT:
+	    printoption("RCVD", WONT, c);
+	    wontoption(c);
+	    SetIn3270();
+	    telrcv_state = TS_DATA;
+	    continue;
+
+	case TS_DO:
+	    printoption("RCVD", DO, c);
+	    dooption(c);
+	    SetIn3270();
+	    if (c == TELOPT_NAWS) {
+		sendnaws();
+	    } else if (c == TELOPT_LFLOW) {
+		localflow = 1;
+		setcommandmode();
+		setconnmode(0);
+	    }
+	    telrcv_state = TS_DATA;
+	    continue;
+
+	case TS_DONT:
+	    printoption("RCVD", DONT, c);
+	    dontoption(c);
+	    flushline = 1;
+	    setconnmode(0);	/* set new tty mode (maybe) */
+	    SetIn3270();
+	    telrcv_state = TS_DATA;
+	    continue;
+
+	case TS_SB:
+	    if (c == IAC) {
+		telrcv_state = TS_SE;
+	    } else {
+		SB_ACCUM(c);
+	    }
+	    continue;
+
+	case TS_SE:
+	    if (c != SE) {
+		if (c != IAC) {
+		    /*
+		     * This is an error.  We only expect to get
+		     * "IAC IAC" or "IAC SE".  Several things may
+		     * have happend.  An IAC was not doubled, the
+		     * IAC SE was left off, or another option got
+		     * inserted into the suboption are all possibilities.
+		     * If we assume that the IAC was not doubled,
+		     * and really the IAC SE was left off, we could
+		     * get into an infinate loop here.  So, instead,
+		     * we terminate the suboption, and process the
+		     * partial suboption if we can.
+		     */
+		    SB_ACCUM(IAC);
+		    SB_ACCUM(c);
+		    subpointer -= 2;
+		    SB_TERM();
+
+		    printoption("In SUBOPTION processing, RCVD", IAC, c);
+		    suboption();	/* handle sub-option */
+		    SetIn3270();
+		    telrcv_state = TS_IAC;
+		    goto process_iac;
+		}
+		SB_ACCUM(c);
+		telrcv_state = TS_SB;
+	    } else {
+		SB_ACCUM(IAC);
+		SB_ACCUM(SE);
+		subpointer -= 2;
+		SB_TERM();
+		suboption();	/* handle sub-option */
+		SetIn3270();
+		telrcv_state = TS_DATA;
+	    }
+	}
+    }
+    if (count)
+	ring_consumed(&netiring, count);
+    return returnValue||count;
+}
+
+static int bol = 1, local = 0;
+
+    int
+rlogin_susp()
+{
+    if (local) {
+	local = 0;
+	bol = 1;
+	command(0, "z\n", 2);
+	return(1);
+    }
+    return(0);
+}
+
+    static int
+telsnd()
+{
+    int tcc;
+    int count;
+    int returnValue = 0;
+    unsigned char *tbp;
+
+    tcc = 0;
+    count = 0;
+    while (NETROOM() > 2) {
+	register int sc;
+	register int c;
+
+	if (tcc == 0) {
+	    if (count) {
+		ring_consumed(&ttyiring, count);
+		returnValue = 1;
+		count = 0;
+	    }
+	    tbp = ttyiring.consume;
+	    tcc = ring_full_consecutive(&ttyiring);
+	    if (tcc == 0) {
+		break;
+	    }
+	}
+	c = *tbp++ & 0xff, sc = strip(c), tcc--; count++;
+	if (rlogin != _POSIX_VDISABLE) {
+		if (bol) {
+			bol = 0;
+			if (sc == rlogin) {
+				local = 1;
+				continue;
+			}
+		} else if (local) {
+			local = 0;
+			if (sc == '.' || c == termEofChar) {
+				bol = 1;
+				command(0, "close\n", 6);
+				continue;
+			}
+			if (sc == termSuspChar) {
+				bol = 1;
+				command(0, "z\n", 2);
+				continue;
+			}
+			if (sc == escape) {
+				command(0, (char *)tbp, tcc);
+				bol = 1;
+				count += tcc;
+				tcc = 0;
+				flushline = 1;
+				break;
+			}
+			if (sc != rlogin) {
+				++tcc;
+				--tbp;
+				--count;
+				c = sc = rlogin;
+			}
+		}
+		if ((sc == '\n') || (sc == '\r'))
+			bol = 1;
+	} else if (sc == escape) {
+	    /*
+	     * Double escape is a pass through of a single escape character.
+	     */
+	    if (tcc && strip(*tbp) == escape) {
+		tbp++;
+		tcc--;
+		count++;
+		bol = 0;
+	    } else {
+		command(0, (char *)tbp, tcc);
+		bol = 1;
+		count += tcc;
+		tcc = 0;
+		flushline = 1;
+		break;
+	    }
+	} else
+	    bol = 0;
+#ifdef	KLUDGELINEMODE
+	if (kludgelinemode && (globalmode&MODE_EDIT) && (sc == echoc)) {
+	    if (tcc > 0 && strip(*tbp) == echoc) {
+		tcc--; tbp++; count++;
+	    } else {
+		dontlecho = !dontlecho;
+		settimer(echotoggle);
+		setconnmode(0);
+		flushline = 1;
+		break;
+	    }
+	}
+#endif
+	if (MODE_LOCAL_CHARS(globalmode)) {
+	    if (TerminalSpecialChars(sc) == 0) {
+		bol = 1;
+		break;
+	    }
+	}
+	if (my_want_state_is_wont(TELOPT_BINARY)) {
+	    switch (c) {
+	    case '\n':
+		    /*
+		     * If we are in CRMOD mode (\r ==> \n)
+		     * on our local machine, then probably
+		     * a newline (unix) is CRLF (TELNET).
+		     */
+		if (MODE_LOCAL_CHARS(globalmode)) {
+		    NETADD('\r');
+		}
+		NETADD('\n');
+		bol = flushline = 1;
+		break;
+	    case '\r':
+		if (!crlf) {
+		    NET2ADD('\r', '\0');
+		} else {
+		    NET2ADD('\r', '\n');
+		}
+		bol = flushline = 1;
+		break;
+	    case IAC:
+		NET2ADD(IAC, IAC);
+		break;
+	    default:
+		NETADD(c);
+		break;
+	    }
+	} else if (c == IAC) {
+	    NET2ADD(IAC, IAC);
+	} else {
+	    NETADD(c);
+	}
+    }
+    if (count)
+	ring_consumed(&ttyiring, count);
+    return returnValue||count;		/* Non-zero if we did anything */
+}
+
+/*
+ * Scheduler()
+ *
+ * Try to do something.
+ *
+ * If we do something useful, return 1; else return 0.
+ *
+ */
+
+
+    int
+Scheduler(block)
+    int	block;			/* should we block in the select ? */
+{
+		/* One wants to be a bit careful about setting returnValue
+		 * to one, since a one implies we did some useful work,
+		 * and therefore probably won't be called to block next
+		 * time (TN3270 mode only).
+		 */
+    int returnValue;
+    int netin, netout, netex, ttyin, ttyout;
+
+    /* Decide which rings should be processed */
+
+    netout = ring_full_count(&netoring) &&
+	    (flushline ||
+		(my_want_state_is_wont(TELOPT_LINEMODE)
+#ifdef	KLUDGELINEMODE
+			&& (!kludgelinemode || my_want_state_is_do(TELOPT_SGA))
+#endif
+		) ||
+			my_want_state_is_will(TELOPT_BINARY));
+    ttyout = ring_full_count(&ttyoring);
+
+#if	defined(TN3270)
+    ttyin = ring_empty_count(&ttyiring) && (shell_active == 0);
+#else	/* defined(TN3270) */
+    ttyin = ring_empty_count(&ttyiring);
+#endif	/* defined(TN3270) */
+
+#if	defined(TN3270)
+    netin = ring_empty_count(&netiring);
+#   else /* !defined(TN3270) */
+    netin = !ISend && ring_empty_count(&netiring);
+#   endif /* !defined(TN3270) */
+
+    netex = !SYNCHing;
+
+    /* If we have seen a signal recently, reset things */
+#   if defined(TN3270) && (defined(unix) || defined(__APPLE__))
+    if (HaveInput) {
+	HaveInput = 0;
+	(void) signal(SIGIO, inputAvailable);
+    }
+#endif	/* defined(TN3270) && (defined(unix) || defined(__APPLE__)) */
+
+    /* Call to system code to process rings */
+
+    returnValue = process_rings(netin, netout, netex, ttyin, ttyout, !block);
+
+    /* Now, look at the input rings, looking for work to do. */
+
+    if (ring_full_count(&ttyiring)) {
+#   if defined(TN3270)
+	if (In3270) {
+	    int c;
+
+	    c = DataFromTerminal(ttyiring.consume,
+					ring_full_consecutive(&ttyiring));
+	    if (c) {
+		returnValue = 1;
+		ring_consumed(&ttyiring, c);
+	    }
+	} else {
+#   endif /* defined(TN3270) */
+	    returnValue |= telsnd();
+#   if defined(TN3270)
+	}
+#   endif /* defined(TN3270) */
+    }
+
+    if (ring_full_count(&netiring)) {
+#	if !defined(TN3270)
+	returnValue |= telrcv();
+#	else /* !defined(TN3270) */
+	returnValue = Push3270();
+#	endif /* !defined(TN3270) */
+    }
+    return returnValue;
+}
+
+/*
+ * Select from tty and network...
+ */
+    void
+telnet(user)
+    char *user;
+{
+    sys_telnet_init();
+
+#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
+    {
+	static char local_host[256] = { 0 };
+
+	if (!local_host[0]) {
+		gethostname(local_host, sizeof(local_host));
+		local_host[sizeof(local_host)-1] = 0;
+	}
+	auth_encrypt_init(local_host, hostname, "TELNET", 0);
+	auth_encrypt_user(user);
+    }
+#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION)  */
+#   if !defined(TN3270)
+    if (telnetport) {
+#if	defined(AUTHENTICATION)
+	if (autologin)
+		send_will(TELOPT_AUTHENTICATION, 1);
+#endif
+#ifdef	ENCRYPTION
+	send_do(TELOPT_ENCRYPT, 1);
+	send_will(TELOPT_ENCRYPT, 1);
+#endif	/* ENCRYPTION */
+	send_do(TELOPT_SGA, 1);
+	send_will(TELOPT_TTYPE, 1);
+	send_will(TELOPT_NAWS, 1);
+	send_will(TELOPT_TSPEED, 1);
+	send_will(TELOPT_LFLOW, 1);
+	send_will(TELOPT_LINEMODE, 1);
+	send_will(TELOPT_NEW_ENVIRON, 1);
+	send_do(TELOPT_STATUS, 1);
+	if (env_getvalue((unsigned char *)"DISPLAY"))
+	    send_will(TELOPT_XDISPLOC, 1);
+	if (eight)
+	    tel_enter_binary(eight);
+    }
+#   endif /* !defined(TN3270) */
+
+#   if !defined(TN3270)
+    for (;;) {
+	int schedValue;
+
+	while ((schedValue = Scheduler(0)) != 0) {
+	    if (schedValue == -1) {
+		setcommandmode();
+		return;
+	    }
+	}
+
+	if (Scheduler(1) == -1) {
+	    setcommandmode();
+	    return;
+	}
+    }
+#   else /* !defined(TN3270) */
+    for (;;) {
+	int schedValue;
+
+	while (!In3270 && !shell_active) {
+	    if (Scheduler(1) == -1) {
+		setcommandmode();
+		return;
+	    }
+	}
+
+	while ((schedValue = Scheduler(0)) != 0) {
+	    if (schedValue == -1) {
+		setcommandmode();
+		return;
+	    }
+	}
+		/* If there is data waiting to go out to terminal, don't
+		 * schedule any more data for the terminal.
+		 */
+	if (ring_full_count(&ttyoring)) {
+	    schedValue = 1;
+	} else {
+	    if (shell_active) {
+		if (shell_continue() == 0) {
+		    ConnectScreen();
+		}
+	    } else if (In3270) {
+		schedValue = DoTerminalOutput();
+	    }
+	}
+	if (schedValue && (shell_active == 0)) {
+	    if (Scheduler(1) == -1) {
+		setcommandmode();
+		return;
+	    }
+	}
+    }
+#   endif /* !defined(TN3270) */
+}
+
+#if	0	/* XXX - this not being in is a bug */
+/*
+ * nextitem()
+ *
+ *	Return the address of the next "item" in the TELNET data
+ * stream.  This will be the address of the next character if
+ * the current address is a user data character, or it will
+ * be the address of the character following the TELNET command
+ * if the current address is a TELNET IAC ("I Am a Command")
+ * character.
+ */
+
+    static char *
+nextitem(current)
+    char *current;
+{
+    if ((*current&0xff) != IAC) {
+	return current+1;
+    }
+    switch (*(current+1)&0xff) {
+    case DO:
+    case DONT:
+    case WILL:
+    case WONT:
+	return current+3;
+    case SB:		/* loop forever looking for the SE */
+	{
+	    register char *look = current+2;
+
+	    for (;;) {
+		if ((*look++&0xff) == IAC) {
+		    if ((*look++&0xff) == SE) {
+			return look;
+		    }
+		}
+	    }
+	}
+    default:
+	return current+2;
+    }
+}
+#endif	/* 0 */
+
+/*
+ * netclear()
+ *
+ *	We are about to do a TELNET SYNCH operation.  Clear
+ * the path to the network.
+ *
+ *	Things are a bit tricky since we may have sent the first
+ * byte or so of a previous TELNET command into the network.
+ * So, we have to scan the network buffer from the beginning
+ * until we are up to where we want to be.
+ *
+ *	A side effect of what we do, just to keep things
+ * simple, is to clear the urgent data pointer.  The principal
+ * caller should be setting the urgent data pointer AFTER calling
+ * us in any case.
+ */
+
+    static void
+netclear()
+{
+#if	0	/* XXX */
+    register char *thisitem, *next;
+    char *good;
+#define	wewant(p)	((nfrontp > p) && ((*p&0xff) == IAC) && \
+				((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
+
+    thisitem = netobuf;
+
+    while ((next = nextitem(thisitem)) <= netobuf.send) {
+	thisitem = next;
+    }
+
+    /* Now, thisitem is first before/at boundary. */
+
+    good = netobuf;	/* where the good bytes go */
+
+    while (netoring.add > thisitem) {
+	if (wewant(thisitem)) {
+	    int length;
+
+	    next = thisitem;
+	    do {
+		next = nextitem(next);
+	    } while (wewant(next) && (nfrontp > next));
+	    length = next-thisitem;
+	    memmove(good, thisitem, length);
+	    good += length;
+	    thisitem = next;
+	} else {
+	    thisitem = nextitem(thisitem);
+	}
+    }
+
+#endif	/* 0 */
+}
+
+/*
+ * These routines add various telnet commands to the data stream.
+ */
+
+    static void
+doflush()
+{
+    NET2ADD(IAC, DO);
+    NETADD(TELOPT_TM);
+    flushline = 1;
+    flushout = 1;
+    (void) ttyflush(1);			/* Flush/drop output */
+    /* do printoption AFTER flush, otherwise the output gets tossed... */
+    printoption("SENT", DO, TELOPT_TM);
+}
+
+    void
+xmitAO()
+{
+    NET2ADD(IAC, AO);
+    printoption("SENT", IAC, AO);
+    if (autoflush) {
+	doflush();
+    }
+}
+
+
+    void
+xmitEL()
+{
+    NET2ADD(IAC, EL);
+    printoption("SENT", IAC, EL);
+}
+
+    void
+xmitEC()
+{
+    NET2ADD(IAC, EC);
+    printoption("SENT", IAC, EC);
+}
+
+
+    int
+dosynch()
+{
+    netclear();			/* clear the path to the network */
+    NETADD(IAC);
+    setneturg();
+    NETADD(DM);
+    printoption("SENT", IAC, DM);
+    return 1;
+}
+
+int want_status_response = 0;
+
+    int
+get_status()
+{
+    unsigned char tmp[16];
+    register unsigned char *cp;
+
+    if (my_want_state_is_dont(TELOPT_STATUS)) {
+	printf("Remote side does not support STATUS option\n");
+	return 0;
+    }
+    cp = tmp;
+
+    *cp++ = IAC;
+    *cp++ = SB;
+    *cp++ = TELOPT_STATUS;
+    *cp++ = TELQUAL_SEND;
+    *cp++ = IAC;
+    *cp++ = SE;
+    if (NETROOM() >= cp - tmp) {
+	ring_supply_data(&netoring, tmp, cp-tmp);
+	printsub('>', tmp+2, cp - tmp - 2);
+    }
+    ++want_status_response;
+    return 1;
+}
+
+    void
+intp()
+{
+    NET2ADD(IAC, IP);
+    printoption("SENT", IAC, IP);
+    flushline = 1;
+    if (autoflush) {
+	doflush();
+    }
+    if (autosynch) {
+	dosynch();
+    }
+}
+
+    void
+sendbrk()
+{
+    NET2ADD(IAC, BREAK);
+    printoption("SENT", IAC, BREAK);
+    flushline = 1;
+    if (autoflush) {
+	doflush();
+    }
+    if (autosynch) {
+	dosynch();
+    }
+}
+
+    void
+sendabort()
+{
+    NET2ADD(IAC, ABORT);
+    printoption("SENT", IAC, ABORT);
+    flushline = 1;
+    if (autoflush) {
+	doflush();
+    }
+    if (autosynch) {
+	dosynch();
+    }
+}
+
+    void
+sendsusp()
+{
+    NET2ADD(IAC, SUSP);
+    printoption("SENT", IAC, SUSP);
+    flushline = 1;
+    if (autoflush) {
+	doflush();
+    }
+    if (autosynch) {
+	dosynch();
+    }
+}
+
+    void
+sendeof()
+{
+    NET2ADD(IAC, xEOF);
+    printoption("SENT", IAC, xEOF);
+}
+
+    void
+sendayt()
+{
+    NET2ADD(IAC, AYT);
+    printoption("SENT", IAC, AYT);
+}
+
+/*
+ * Send a window size update to the remote system.
+ */
+
+    void
+sendnaws()
+{
+    long rows, cols;
+    unsigned char tmp[16];
+    register unsigned char *cp;
+
+    if (my_state_is_wont(TELOPT_NAWS))
+	return;
+
+#define	PUTSHORT(cp, x) { if ((*cp++ = ((x)>>8)&0xff) == IAC) *cp++ = IAC; \
+			    if ((*cp++ = ((x))&0xff) == IAC) *cp++ = IAC; }
+
+    if (TerminalWindowSize(&rows, &cols) == 0) {	/* Failed */
+	return;
+    }
+
+    cp = tmp;
+
+    *cp++ = IAC;
+    *cp++ = SB;
+    *cp++ = TELOPT_NAWS;
+    PUTSHORT(cp, cols);
+    PUTSHORT(cp, rows);
+    *cp++ = IAC;
+    *cp++ = SE;
+    if (NETROOM() >= cp - tmp) {
+	ring_supply_data(&netoring, tmp, cp-tmp);
+	printsub('>', tmp+2, cp - tmp - 2);
+    }
+}
+
+    void
+tel_enter_binary(rw)
+    int rw;
+{
+    if (rw&1)
+	send_do(TELOPT_BINARY, 1);
+    if (rw&2)
+	send_will(TELOPT_BINARY, 1);
+}
+
+    void
+tel_leave_binary(rw)
+    int rw;
+{
+    if (rw&1)
+	send_dont(TELOPT_BINARY, 1);
+    if (rw&2)
+	send_wont(TELOPT_BINARY, 1);
+}
diff --git a/telnet.tproj/terminal.c b/telnet.tproj/terminal.c
new file mode 100644
index 0000000..de75e4d
--- /dev/null
+++ b/telnet.tproj/terminal.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)terminal.c	8.2 (Berkeley) 2/16/95";
+#endif /* not lint */
+
+#include <arpa/telnet.h>
+#include <sys/types.h>
+
+#include "ring.h"
+
+#include "externs.h"
+#include "types.h"
+
+Ring		ttyoring, ttyiring;
+unsigned char	ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
+
+int termdata;			/* Debugging flag */
+
+#ifdef	USE_TERMIO
+# ifndef VDISCARD
+cc_t termFlushChar;
+# endif
+# ifndef VLNEXT
+cc_t termLiteralNextChar;
+# endif
+# ifndef VSUSP
+cc_t termSuspChar;
+# endif
+# ifndef VWERASE
+cc_t termWerasChar;
+# endif
+# ifndef VREPRINT
+cc_t termRprntChar;
+# endif
+# ifndef VSTART
+cc_t termStartChar;
+# endif
+# ifndef VSTOP
+cc_t termStopChar;
+# endif
+# ifndef VEOL
+cc_t termForw1Char;
+# endif
+# ifndef VEOL2
+cc_t termForw2Char;
+# endif
+# ifndef VSTATUS
+cc_t termAytChar;
+# endif
+#else
+cc_t termForw2Char;
+cc_t termAytChar;
+#endif
+
+/*
+ * initialize the terminal data structures.
+ */
+
+    void
+init_terminal()
+{
+    if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
+	exit(1);
+    }
+    if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
+	exit(1);
+    }
+    autoflush = TerminalAutoFlush();
+}
+
+
+/*
+ *		Send as much data as possible to the terminal.
+ *
+ *		Return value:
+ *			-1: No useful work done, data waiting to go out.
+ *			 0: No data was waiting, so nothing was done.
+ *			 1: All waiting data was written out.
+ *			 n: All data - n was written out.
+ */
+
+
+    int
+ttyflush(drop)
+    int drop;
+{
+    register int n, n0, n1;
+
+    n0 = ring_full_count(&ttyoring);
+    if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
+	if (drop) {
+	    TerminalFlushOutput();
+	    /* we leave 'n' alone! */
+	} else {
+	    n = TerminalWrite(ttyoring.consume, n);
+	}
+    }
+    if (n > 0) {
+	if (termdata && n) {
+	    Dump('>', ttyoring.consume, n);
+	}
+	/*
+	 * If we wrote everything, and the full count is
+	 * larger than what we wrote, then write the
+	 * rest of the buffer.
+	 */
+	if (n1 == n && n0 > n) {
+		n1 = n0 - n;
+		if (!drop)
+			n1 = TerminalWrite(ttyoring.bottom, n1);
+		if (n1 > 0)
+			n += n1;
+	}
+	ring_consumed(&ttyoring, n);
+    }
+    if (n < 0)
+	return -1;
+    if (n == n0) {
+	if (n0)
+	    return -1;
+	return 0;
+    }
+    return n0 - n + 1;
+}
+
+
+/*
+ * These routines decides on what the mode should be (based on the values
+ * of various global variables).
+ */
+
+
+    int
+getconnmode()
+{
+    extern int linemode;
+    int mode = 0;
+#ifdef	KLUDGELINEMODE
+    extern int kludgelinemode;
+#endif
+
+    if (In3270)
+	return(MODE_FLOW);
+
+    if (my_want_state_is_dont(TELOPT_ECHO))
+	mode |= MODE_ECHO;
+
+    if (localflow)
+	mode |= MODE_FLOW;
+
+    if (my_want_state_is_will(TELOPT_BINARY))
+	mode |= MODE_INBIN;
+
+    if (his_want_state_is_will(TELOPT_BINARY))
+	mode |= MODE_OUTBIN;
+
+#ifdef	KLUDGELINEMODE
+    if (kludgelinemode) {
+	if (my_want_state_is_dont(TELOPT_SGA)) {
+	    mode |= (MODE_TRAPSIG|MODE_EDIT);
+	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
+		mode &= ~MODE_ECHO;
+	    }
+	}
+	return(mode);
+    }
+#endif
+    if (my_want_state_is_will(TELOPT_LINEMODE))
+	mode |= linemode;
+    return(mode);
+}
+
+    void
+setconnmode(force)
+    int force;
+{
+#ifdef	ENCRYPTION
+    static int enc_passwd = 0;
+#endif	/* ENCRYPTION */
+    register int newmode;
+
+    newmode = getconnmode()|(force?MODE_FORCE:0);
+
+    TerminalNewMode(newmode);
+
+#ifdef  ENCRYPTION
+    if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
+	if (my_want_state_is_will(TELOPT_ENCRYPT)
+				&& (enc_passwd == 0) && !encrypt_output) {
+	    encrypt_request_start(0, 0);
+	    enc_passwd = 1;
+	}
+    } else {
+	if (enc_passwd) {
+	    encrypt_request_end();
+	    enc_passwd = 0;
+	}
+    }
+#endif	/* ENCRYPTION */
+
+}
+
+
+    void
+setcommandmode()
+{
+    TerminalNewMode(-1);
+}
diff --git a/telnet.tproj/tn3270.c b/telnet.tproj/tn3270.c
new file mode 100644
index 0000000..875d386
--- /dev/null
+++ b/telnet.tproj/tn3270.c
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tn3270.c	8.2 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <arpa/telnet.h>
+
+#include "general.h"
+
+#include "defines.h"
+#include "ring.h"
+#include "externs.h"
+#include "fdset.h"
+
+#if	defined(TN3270)
+
+#include "../ctlr/screen.h"
+#include "../general/globals.h"
+
+#include "../sys_curses/telextrn.h"
+#include "../ctlr/externs.h"
+
+#if	defined(unix) || defined(__APPLE__)
+int
+	HaveInput,		/* There is input available to scan */
+	cursesdata,		/* Do we dump curses data? */
+	sigiocount;		/* Number of times we got a SIGIO */
+
+char	tline[200];
+char	*transcom = 0;	/* transparent mode command (default: none) */
+#endif	/* defined(unix) || defined(__APPLE__) */
+
+char	Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp;
+
+static char	sb_terminal[] = { IAC, SB,
+			TELOPT_TTYPE, TELQUAL_IS,
+			'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2',
+			IAC, SE };
+#define	SBTERMMODEL	13
+
+static int
+	Sent3270TerminalType;	/* Have we said we are a 3270? */
+
+#endif	/* defined(TN3270) */
+
+
+    void
+init_3270()
+{
+#if	defined(TN3270)
+#if	defined(unix) || defined(__APPLE__)
+    HaveInput = 0;
+    sigiocount = 0;
+#endif	/* defined(unix) || defined(__APPLE__) */
+    Sent3270TerminalType = 0;
+    Ifrontp = Ibackp = Ibuf;
+    init_ctlr();		/* Initialize some things */
+    init_keyboard();
+    init_screen();
+    init_system();
+#endif	/* defined(TN3270) */
+}
+
+
+#if	defined(TN3270)
+
+/*
+ * DataToNetwork - queue up some data to go to network.  If "done" is set,
+ * then when last byte is queued, we add on an IAC EOR sequence (so,
+ * don't call us with "done" until you want that done...)
+ *
+ * We actually do send all the data to the network buffer, since our
+ * only client needs for us to do that.
+ */
+
+    int
+DataToNetwork(buffer, count, done)
+    register char *buffer;	/* where the data is */
+    register int  count;	/* how much to send */
+    int		  done;		/* is this the last of a logical block */
+{
+    register int loop, c;
+    int origCount;
+
+    origCount = count;
+
+    while (count) {
+	/* If not enough room for EORs, IACs, etc., wait */
+	if (NETROOM() < 6) {
+	    fd_set o;
+
+	    FD_ZERO(&o);
+	    netflush();
+	    while (NETROOM() < 6) {
+		FD_SET(net, &o);
+		(void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0,
+						(struct timeval *) 0);
+		netflush();
+	    }
+	}
+	c = ring_empty_count(&netoring);
+	if (c > count) {
+	    c = count;
+	}
+	loop = c;
+	while (loop) {
+	    if (((unsigned char)*buffer) == IAC) {
+		break;
+	    }
+	    buffer++;
+	    loop--;
+	}
+	if ((c = c-loop)) {
+	    ring_supply_data(&netoring, buffer-c, c);
+	    count -= c;
+	}
+	if (loop) {
+	    NET2ADD(IAC, IAC);
+	    count--;
+	    buffer++;
+	}
+    }
+
+    if (done) {
+	NET2ADD(IAC, EOR);
+	netflush();		/* try to move along as quickly as ... */
+    }
+    return(origCount - count);
+}
+
+
+#if	defined(unix) || defined(__APPLE__)
+    void
+inputAvailable(signo)
+	int signo;
+{
+    HaveInput = 1;
+    sigiocount++;
+}
+#endif	/* defined(unix) || defined(__APPLE__) */
+
+    void
+outputPurge()
+{
+    (void) ttyflush(1);
+}
+
+
+/*
+ * The following routines are places where the various tn3270
+ * routines make calls into telnet.c.
+ */
+
+/*
+ * DataToTerminal - queue up some data to go to terminal.
+ *
+ * Note: there are people who call us and depend on our processing
+ * *all* the data at one time (thus the select).
+ */
+
+    int
+DataToTerminal(buffer, count)
+    register char	*buffer;		/* where the data is */
+    register int	count;			/* how much to send */
+{
+    register int c;
+    int origCount;
+
+    origCount = count;
+
+    while (count) {
+	if (TTYROOM() == 0) {
+#if	defined(unix) || defined(__APPLE__)
+	    fd_set o;
+
+	    FD_ZERO(&o);
+#endif	/* defined(unix) || defined(__APPLE__) */
+	    (void) ttyflush(0);
+	    while (TTYROOM() == 0) {
+#if	defined(unix) || defined(__APPLE__)
+		FD_SET(tout, &o);
+		(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
+						(struct timeval *) 0);
+#endif	/* defined(unix) || defined(__APPLE__) */
+		(void) ttyflush(0);
+	    }
+	}
+	c = TTYROOM();
+	if (c > count) {
+	    c = count;
+	}
+	ring_supply_data(&ttyoring, buffer, c);
+	count -= c;
+	buffer += c;
+    }
+    return(origCount);
+}
+
+
+/*
+ * Push3270 - Try to send data along the 3270 output (to screen) direction.
+ */
+
+    int
+Push3270()
+{
+    int save = ring_full_count(&netiring);
+
+    if (save) {
+	if (Ifrontp+save > Ibuf+sizeof Ibuf) {
+	    if (Ibackp != Ibuf) {
+		memmove(Ibuf, Ibackp, Ifrontp-Ibackp);
+		Ifrontp -= (Ibackp-Ibuf);
+		Ibackp = Ibuf;
+	    }
+	}
+	if (Ifrontp+save < Ibuf+sizeof Ibuf) {
+	    (void)telrcv();
+	}
+    }
+    return save != ring_full_count(&netiring);
+}
+
+
+/*
+ * Finish3270 - get the last dregs of 3270 data out to the terminal
+ *		before quitting.
+ */
+
+    void
+Finish3270()
+{
+    while (Push3270() || !DoTerminalOutput()) {
+#if	defined(unix) || defined(__APPLE__)
+	HaveInput = 0;
+#endif	/* defined(unix) || defined(__APPLE__) */
+	;
+    }
+}
+
+
+/* StringToTerminal - output a null terminated string to the terminal */
+
+    void
+StringToTerminal(s)
+    char *s;
+{
+    int count;
+
+    count = strlen(s);
+    if (count) {
+	(void) DataToTerminal(s, count);	/* we know it always goes... */
+    }
+}
+
+
+#if	((!defined(NOT43)) || defined(PUTCHAR))
+/* _putchar - output a single character to the terminal.  This name is so that
+ *	curses(3x) can call us to send out data.
+ */
+
+    void
+_putchar(c)
+    char c;
+{
+#if	defined(sun)		/* SunOS 4.0 bug */
+    c &= 0x7f;
+#endif	/* defined(sun) */
+    if (cursesdata) {
+	Dump('>', &c, 1);
+    }
+    if (!TTYROOM()) {
+	(void) DataToTerminal(&c, 1);
+    } else {
+	TTYADD(c);
+    }
+}
+#endif	/* ((!defined(NOT43)) || defined(PUTCHAR)) */
+
+    void
+SetIn3270()
+{
+    if (Sent3270TerminalType && my_want_state_is_will(TELOPT_BINARY)
+		&& my_want_state_is_do(TELOPT_BINARY) && !donebinarytoggle) {
+	if (!In3270) {
+	    In3270 = 1;
+	    Init3270();		/* Initialize 3270 functions */
+	    /* initialize terminal key mapping */
+	    InitTerminal();	/* Start terminal going */
+	    setconnmode(0);
+	}
+    } else {
+	if (In3270) {
+	    StopScreen(1);
+	    In3270 = 0;
+	    Stop3270();		/* Tell 3270 we aren't here anymore */
+	    setconnmode(0);
+	}
+    }
+}
+
+/*
+ * tn3270_ttype()
+ *
+ *	Send a response to a terminal type negotiation.
+ *
+ *	Return '0' if no more responses to send; '1' if a response sent.
+ */
+
+    int
+tn3270_ttype()
+{
+    /*
+     * Try to send a 3270 type terminal name.  Decide which one based
+     * on the format of our screen, and (in the future) color
+     * capaiblities.
+     */
+    InitTerminal();		/* Sets MaxNumberColumns, MaxNumberLines */
+    if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) {
+	Sent3270TerminalType = 1;
+	if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) {
+	    MaxNumberLines = 27;
+	    MaxNumberColumns = 132;
+	    sb_terminal[SBTERMMODEL] = '5';
+	} else if (MaxNumberLines >= 43) {
+	    MaxNumberLines = 43;
+	    MaxNumberColumns = 80;
+	    sb_terminal[SBTERMMODEL] = '4';
+	} else if (MaxNumberLines >= 32) {
+	    MaxNumberLines = 32;
+	    MaxNumberColumns = 80;
+	    sb_terminal[SBTERMMODEL] = '3';
+	} else {
+	    MaxNumberLines = 24;
+	    MaxNumberColumns = 80;
+	    sb_terminal[SBTERMMODEL] = '2';
+	}
+	NumberLines = 24;		/* before we start out... */
+	NumberColumns = 80;
+	ScreenSize = NumberLines*NumberColumns;
+	if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) {
+	    ExitString("Programming error:  MAXSCREENSIZE too small.\n",
+								1);
+	    /*NOTREACHED*/
+	}
+	printsub('>', sb_terminal+2, sizeof sb_terminal-2);
+	ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal);
+	return 1;
+    } else {
+	return 0;
+    }
+}
+
+#if	defined(unix) || defined(__APPLE__)
+	int
+settranscom(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int i;
+
+	if (argc == 1 && transcom) {
+	   transcom = 0;
+	}
+	if (argc == 1) {
+	   return 1;
+	}
+	transcom = tline;
+	(void) strcpy(transcom, argv[1]);
+	for (i = 2; i < argc; ++i) {
+	    (void) strcat(transcom, " ");
+	    (void) strcat(transcom, argv[i]);
+	}
+	return 1;
+}
+#endif	/* defined(unix) || defined(__APPLE__) */
+
+#endif	/* defined(TN3270) */
diff --git a/telnet.tproj/types.h b/telnet.tproj/types.h
new file mode 100644
index 0000000..42b1b8f
--- /dev/null
+++ b/telnet.tproj/types.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)types.h	8.1 (Berkeley) 6/6/93
+ */
+
+typedef struct {
+    char *modedescriptions;
+    char modetype;
+} Modelist;
+
+extern Modelist modelist[];
+
+typedef struct {
+    int
+	system,			/* what the current time is */
+	echotoggle,		/* last time user entered echo character */
+	modenegotiated,		/* last time operating mode negotiated */
+	didnetreceive,		/* last time we read data from network */
+	gotDM;			/* when did we last see a data mark */
+} Clocks;
+
+extern Clocks clocks;
diff --git a/telnet.tproj/utilities.c b/telnet.tproj/utilities.c
new file mode 100644
index 0000000..2957297
--- /dev/null
+++ b/telnet.tproj/utilities.c
@@ -0,0 +1,962 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)utilities.c	8.3 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#define	TELOPTS
+#define	TELCMDS
+#define	SLC_NAMES
+#include <arpa/telnet.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+
+#include "general.h"
+
+#include "fdset.h"
+
+#include "ring.h"
+
+#include "defines.h"
+
+#include "externs.h"
+
+FILE	*NetTrace = 0;		/* Not in bss, since needs to stay */
+int	prettydump;
+
+/*
+ * upcase()
+ *
+ *	Upcase (in place) the argument.
+ */
+
+    void
+upcase(argument)
+    register char *argument;
+{
+    register int c;
+
+    while ((c = *argument) != 0) {
+	if (islower(c)) {
+	    *argument = toupper(c);
+	}
+	argument++;
+    }
+}
+
+/*
+ * SetSockOpt()
+ *
+ * Compensate for differences in 4.2 and 4.3 systems.
+ */
+
+    int
+SetSockOpt(fd, level, option, yesno)
+    int fd, level, option, yesno;
+{
+#ifndef	NOT43
+    return setsockopt(fd, level, option,
+				(char *)&yesno, sizeof yesno);
+#else	/* NOT43 */
+    if (yesno == 0) {		/* Can't do that in 4.2! */
+	fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n",
+				option);
+	return -1;
+    }
+    return setsockopt(fd, level, option, 0, 0);
+#endif	/* NOT43 */
+}
+
+/*
+ * The following are routines used to print out debugging information.
+ */
+
+unsigned char NetTraceFile[256] = "(standard output)";
+
+    void
+SetNetTrace(file)
+    register char *file;
+{
+    if (NetTrace && NetTrace != stdout)
+	fclose(NetTrace);
+    if (file  && (strcmp(file, "-") != 0)) {
+	NetTrace = fopen(file, "w");
+	if (NetTrace) {
+	    strcpy((char *)NetTraceFile, file);
+	    return;
+	}
+	fprintf(stderr, "Cannot open %s.\n", file);
+    }
+    NetTrace = stdout;
+    strcpy((char *)NetTraceFile, "(standard output)");
+}
+
+    void
+Dump(direction, buffer, length)
+    char direction;
+    unsigned char *buffer;
+    int length;
+{
+#   define BYTES_PER_LINE	32
+#   define min(x,y)	((x<y)? x:y)
+    unsigned char *pThis;
+    int offset;
+    extern pettydump;
+
+    offset = 0;
+
+    while (length) {
+	/* print one line */
+	fprintf(NetTrace, "%c 0x%x\t", direction, offset);
+	pThis = buffer;
+	if (prettydump) {
+	    buffer = buffer + min(length, BYTES_PER_LINE/2);
+	    while (pThis < buffer) {
+		fprintf(NetTrace, "%c%.2x",
+		    (((*pThis)&0xff) == 0xff) ? '*' : ' ',
+		    (*pThis)&0xff);
+		pThis++;
+	    }
+	    length -= BYTES_PER_LINE/2;
+	    offset += BYTES_PER_LINE/2;
+	} else {
+	    buffer = buffer + min(length, BYTES_PER_LINE);
+	    while (pThis < buffer) {
+		fprintf(NetTrace, "%.2x", (*pThis)&0xff);
+		pThis++;
+	    }
+	    length -= BYTES_PER_LINE;
+	    offset += BYTES_PER_LINE;
+	}
+	if (NetTrace == stdout) {
+	    fprintf(NetTrace, "\r\n");
+	} else {
+	    fprintf(NetTrace, "\n");
+	}
+	if (length < 0) {
+	    fflush(NetTrace);
+	    return;
+	}
+	/* find next unique line */
+    }
+    fflush(NetTrace);
+}
+
+
+	void
+printoption(direction, cmd, option)
+	char *direction;
+	int cmd, option;
+{
+	if (!showoptions)
+		return;
+	if (cmd == IAC) {
+		if (TELCMD_OK(option))
+		    fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option));
+		else
+		    fprintf(NetTrace, "%s IAC %d", direction, option);
+	} else {
+		register char *fmt;
+		fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
+			(cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
+		if (fmt) {
+		    fprintf(NetTrace, "%s %s ", direction, fmt);
+		    if (TELOPT_OK(option))
+			fprintf(NetTrace, "%s", TELOPT(option));
+		    else if (option == TELOPT_EXOPL)
+			fprintf(NetTrace, "EXOPL");
+		    else
+			fprintf(NetTrace, "%d", option);
+		} else
+		    fprintf(NetTrace, "%s %d %d", direction, cmd, option);
+	}
+	if (NetTrace == stdout) {
+	    fprintf(NetTrace, "\r\n");
+	    fflush(NetTrace);
+	} else {
+	    fprintf(NetTrace, "\n");
+	}
+	return;
+}
+
+    void
+optionstatus()
+{
+    register int i;
+    extern char will_wont_resp[], do_dont_resp[];
+
+    for (i = 0; i < 256; i++) {
+	if (do_dont_resp[i]) {
+	    if (TELOPT_OK(i))
+		printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
+	    else if (TELCMD_OK(i))
+		printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
+	    else
+		printf("resp DO_DONT %d: %d\n", i,
+				do_dont_resp[i]);
+	    if (my_want_state_is_do(i)) {
+		if (TELOPT_OK(i))
+		    printf("want DO   %s\n", TELOPT(i));
+		else if (TELCMD_OK(i))
+		    printf("want DO   %s\n", TELCMD(i));
+		else
+		    printf("want DO   %d\n", i);
+	    } else {
+		if (TELOPT_OK(i))
+		    printf("want DONT %s\n", TELOPT(i));
+		else if (TELCMD_OK(i))
+		    printf("want DONT %s\n", TELCMD(i));
+		else
+		    printf("want DONT %d\n", i);
+	    }
+	} else {
+	    if (my_state_is_do(i)) {
+		if (TELOPT_OK(i))
+		    printf("     DO   %s\n", TELOPT(i));
+		else if (TELCMD_OK(i))
+		    printf("     DO   %s\n", TELCMD(i));
+		else
+		    printf("     DO   %d\n", i);
+	    }
+	}
+	if (will_wont_resp[i]) {
+	    if (TELOPT_OK(i))
+		printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
+	    else if (TELCMD_OK(i))
+		printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
+	    else
+		printf("resp WILL_WONT %d: %d\n",
+				i, will_wont_resp[i]);
+	    if (my_want_state_is_will(i)) {
+		if (TELOPT_OK(i))
+		    printf("want WILL %s\n", TELOPT(i));
+		else if (TELCMD_OK(i))
+		    printf("want WILL %s\n", TELCMD(i));
+		else
+		    printf("want WILL %d\n", i);
+	    } else {
+		if (TELOPT_OK(i))
+		    printf("want WONT %s\n", TELOPT(i));
+		else if (TELCMD_OK(i))
+		    printf("want WONT %s\n", TELCMD(i));
+		else
+		    printf("want WONT %d\n", i);
+	    }
+	} else {
+	    if (my_state_is_will(i)) {
+		if (TELOPT_OK(i))
+		    printf("     WILL %s\n", TELOPT(i));
+		else if (TELCMD_OK(i))
+		    printf("     WILL %s\n", TELCMD(i));
+		else
+		    printf("     WILL %d\n", i);
+	    }
+	}
+    }
+
+}
+
+    void
+printsub(direction, pointer, length)
+    char direction;	/* '<' or '>' */
+    unsigned char *pointer;	/* where suboption data sits */
+    int		  length;	/* length of suboption data */
+{
+    register int i;
+    char buf[512];
+    extern int want_status_response;
+
+    if (showoptions || direction == 0 ||
+	(want_status_response && (pointer[0] == TELOPT_STATUS))) {
+	if (direction) {
+	    fprintf(NetTrace, "%s IAC SB ",
+				(direction == '<')? "RCVD":"SENT");
+	    if (length >= 3) {
+		register int j;
+
+		i = pointer[length-2];
+		j = pointer[length-1];
+
+		if (i != IAC || j != SE) {
+		    fprintf(NetTrace, "(terminated by ");
+		    if (TELOPT_OK(i))
+			fprintf(NetTrace, "%s ", TELOPT(i));
+		    else if (TELCMD_OK(i))
+			fprintf(NetTrace, "%s ", TELCMD(i));
+		    else
+			fprintf(NetTrace, "%d ", i);
+		    if (TELOPT_OK(j))
+			fprintf(NetTrace, "%s", TELOPT(j));
+		    else if (TELCMD_OK(j))
+			fprintf(NetTrace, "%s", TELCMD(j));
+		    else
+			fprintf(NetTrace, "%d", j);
+		    fprintf(NetTrace, ", not IAC SE!) ");
+		}
+	    }
+	    length -= 2;
+	}
+	if (length < 1) {
+	    fprintf(NetTrace, "(Empty suboption??\?)");
+	    if (NetTrace == stdout)
+		fflush(NetTrace);
+	    return;
+	}
+	switch (pointer[0]) {
+	case TELOPT_TTYPE:
+	    fprintf(NetTrace, "TERMINAL-TYPE ");
+	    switch (pointer[1]) {
+	    case TELQUAL_IS:
+		fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
+		break;
+	    case TELQUAL_SEND:
+		fprintf(NetTrace, "SEND");
+		break;
+	    default:
+		fprintf(NetTrace,
+				"- unknown qualifier %d (0x%x).",
+				pointer[1], pointer[1]);
+	    }
+	    break;
+	case TELOPT_TSPEED:
+	    fprintf(NetTrace, "TERMINAL-SPEED");
+	    if (length < 2) {
+		fprintf(NetTrace, " (empty suboption??\?)");
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case TELQUAL_IS:
+		fprintf(NetTrace, " IS ");
+		fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
+		break;
+	    default:
+		if (pointer[1] == 1)
+		    fprintf(NetTrace, " SEND");
+		else
+		    fprintf(NetTrace, " %d (unknown)", pointer[1]);
+		for (i = 2; i < length; i++)
+		    fprintf(NetTrace, " ?%d?", pointer[i]);
+		break;
+	    }
+	    break;
+
+	case TELOPT_LFLOW:
+	    fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
+	    if (length < 2) {
+		fprintf(NetTrace, " (empty suboption??\?)");
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case LFLOW_OFF:
+		fprintf(NetTrace, " OFF"); break;
+	    case LFLOW_ON:
+		fprintf(NetTrace, " ON"); break;
+	    case LFLOW_RESTART_ANY:
+		fprintf(NetTrace, " RESTART-ANY"); break;
+	    case LFLOW_RESTART_XON:
+		fprintf(NetTrace, " RESTART-XON"); break;
+	    default:
+		fprintf(NetTrace, " %d (unknown)", pointer[1]);
+	    }
+	    for (i = 2; i < length; i++)
+		fprintf(NetTrace, " ?%d?", pointer[i]);
+	    break;
+
+	case TELOPT_NAWS:
+	    fprintf(NetTrace, "NAWS");
+	    if (length < 2) {
+		fprintf(NetTrace, " (empty suboption??\?)");
+		break;
+	    }
+	    if (length == 2) {
+		fprintf(NetTrace, " ?%d?", pointer[1]);
+		break;
+	    }
+	    fprintf(NetTrace, " %d %d (%d)",
+		pointer[1], pointer[2],
+		(int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
+	    if (length == 4) {
+		fprintf(NetTrace, " ?%d?", pointer[3]);
+		break;
+	    }
+	    fprintf(NetTrace, " %d %d (%d)",
+		pointer[3], pointer[4],
+		(int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
+	    for (i = 5; i < length; i++)
+		fprintf(NetTrace, " ?%d?", pointer[i]);
+	    break;
+
+#if	defined(AUTHENTICATION)
+	case TELOPT_AUTHENTICATION:
+	    fprintf(NetTrace, "AUTHENTICATION");
+	    if (length < 2) {
+		fprintf(NetTrace, " (empty suboption??\?)");
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case TELQUAL_REPLY:
+	    case TELQUAL_IS:
+		fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ?
+							"IS" : "REPLY");
+		if (AUTHTYPE_NAME_OK(pointer[2]))
+		    fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2]));
+		else
+		    fprintf(NetTrace, "%d ", pointer[2]);
+		if (length < 3) {
+		    fprintf(NetTrace, "(partial suboption??\?)");
+		    break;
+		}
+		fprintf(NetTrace, "%s|%s",
+			((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
+			"CLIENT" : "SERVER",
+			((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
+			"MUTUAL" : "ONE-WAY");
+
+		auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
+		fprintf(NetTrace, "%s", buf);
+		break;
+
+	    case TELQUAL_SEND:
+		i = 2;
+		fprintf(NetTrace, " SEND ");
+		while (i < length) {
+		    if (AUTHTYPE_NAME_OK(pointer[i]))
+			fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i]));
+		    else
+			fprintf(NetTrace, "%d ", pointer[i]);
+		    if (++i >= length) {
+			fprintf(NetTrace, "(partial suboption??\?)");
+			break;
+		    }
+		    fprintf(NetTrace, "%s|%s ",
+			((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
+							"CLIENT" : "SERVER",
+			((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
+							"MUTUAL" : "ONE-WAY");
+		    ++i;
+		}
+		break;
+
+	    case TELQUAL_NAME:
+		i = 2;
+		fprintf(NetTrace, " NAME \"");
+		while (i < length)
+		    putc(pointer[i++], NetTrace);
+		putc('"', NetTrace);
+		break;
+
+	    default:
+		    for (i = 2; i < length; i++)
+			fprintf(NetTrace, " ?%d?", pointer[i]);
+		    break;
+	    }
+	    break;
+#endif
+
+#ifdef	ENCRYPTION
+	case TELOPT_ENCRYPT:
+	    fprintf(NetTrace, "ENCRYPT");
+	    if (length < 2) {
+		fprintf(NetTrace, " (empty suboption??\?)");
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case ENCRYPT_START:
+		fprintf(NetTrace, " START");
+		break;
+
+	    case ENCRYPT_END:
+		fprintf(NetTrace, " END");
+		break;
+
+	    case ENCRYPT_REQSTART:
+		fprintf(NetTrace, " REQUEST-START");
+		break;
+
+	    case ENCRYPT_REQEND:
+		fprintf(NetTrace, " REQUEST-END");
+		break;
+
+	    case ENCRYPT_IS:
+	    case ENCRYPT_REPLY:
+		fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ?
+							"IS" : "REPLY");
+		if (length < 3) {
+		    fprintf(NetTrace, " (partial suboption??\?)");
+		    break;
+		}
+		if (ENCTYPE_NAME_OK(pointer[2]))
+		    fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2]));
+		else
+		    fprintf(NetTrace, " %d (unknown)", pointer[2]);
+
+		encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf));
+		fprintf(NetTrace, "%s", buf);
+		break;
+
+	    case ENCRYPT_SUPPORT:
+		i = 2;
+		fprintf(NetTrace, " SUPPORT ");
+		while (i < length) {
+		    if (ENCTYPE_NAME_OK(pointer[i]))
+			fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i]));
+		    else
+			fprintf(NetTrace, "%d ", pointer[i]);
+		    i++;
+		}
+		break;
+
+	    case ENCRYPT_ENC_KEYID:
+		fprintf(NetTrace, " ENC_KEYID ");
+		goto encommon;
+
+	    case ENCRYPT_DEC_KEYID:
+		fprintf(NetTrace, " DEC_KEYID ");
+		goto encommon;
+
+	    default:
+		fprintf(NetTrace, " %d (unknown)", pointer[1]);
+	    encommon:
+		for (i = 2; i < length; i++)
+		    fprintf(NetTrace, " %d", pointer[i]);
+		break;
+	    }
+	    break;
+#endif	/* ENCRYPTION */
+
+	case TELOPT_LINEMODE:
+	    fprintf(NetTrace, "LINEMODE ");
+	    if (length < 2) {
+		fprintf(NetTrace, " (empty suboption??\?)");
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case WILL:
+		fprintf(NetTrace, "WILL ");
+		goto common;
+	    case WONT:
+		fprintf(NetTrace, "WONT ");
+		goto common;
+	    case DO:
+		fprintf(NetTrace, "DO ");
+		goto common;
+	    case DONT:
+		fprintf(NetTrace, "DONT ");
+	    common:
+		if (length < 3) {
+		    fprintf(NetTrace, "(no option??\?)");
+		    break;
+		}
+		switch (pointer[2]) {
+		case LM_FORWARDMASK:
+		    fprintf(NetTrace, "Forward Mask");
+		    for (i = 3; i < length; i++)
+			fprintf(NetTrace, " %x", pointer[i]);
+		    break;
+		default:
+		    fprintf(NetTrace, "%d (unknown)", pointer[2]);
+		    for (i = 3; i < length; i++)
+			fprintf(NetTrace, " %d", pointer[i]);
+		    break;
+		}
+		break;
+
+	    case LM_SLC:
+		fprintf(NetTrace, "SLC");
+		for (i = 2; i < length - 2; i += 3) {
+		    if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
+			fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
+		    else
+			fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
+		    switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
+		    case SLC_NOSUPPORT:
+			fprintf(NetTrace, " NOSUPPORT"); break;
+		    case SLC_CANTCHANGE:
+			fprintf(NetTrace, " CANTCHANGE"); break;
+		    case SLC_VARIABLE:
+			fprintf(NetTrace, " VARIABLE"); break;
+		    case SLC_DEFAULT:
+			fprintf(NetTrace, " DEFAULT"); break;
+		    }
+		    fprintf(NetTrace, "%s%s%s",
+			pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
+			pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
+			pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
+		    if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
+						SLC_FLUSHOUT| SLC_LEVELBITS))
+			fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
+		    fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
+		    if ((pointer[i+SLC_VALUE] == IAC) &&
+			(pointer[i+SLC_VALUE+1] == IAC))
+				i++;
+		}
+		for (; i < length; i++)
+		    fprintf(NetTrace, " ?%d?", pointer[i]);
+		break;
+
+	    case LM_MODE:
+		fprintf(NetTrace, "MODE ");
+		if (length < 3) {
+		    fprintf(NetTrace, "(no mode??\?)");
+		    break;
+		}
+		{
+		    char tbuf[64];
+		    sprintf(tbuf, "%s%s%s%s%s",
+			pointer[2]&MODE_EDIT ? "|EDIT" : "",
+			pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
+			pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
+			pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
+			pointer[2]&MODE_ACK ? "|ACK" : "");
+		    fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
+		}
+		if (pointer[2]&~(MODE_MASK))
+		    fprintf(NetTrace, " (0x%x)", pointer[2]);
+		for (i = 3; i < length; i++)
+		    fprintf(NetTrace, " ?0x%x?", pointer[i]);
+		break;
+	    default:
+		fprintf(NetTrace, "%d (unknown)", pointer[1]);
+		for (i = 2; i < length; i++)
+		    fprintf(NetTrace, " %d", pointer[i]);
+	    }
+	    break;
+
+	case TELOPT_STATUS: {
+	    register char *cp;
+	    register int j, k;
+
+	    fprintf(NetTrace, "STATUS");
+
+	    switch (pointer[1]) {
+	    default:
+		if (pointer[1] == TELQUAL_SEND)
+		    fprintf(NetTrace, " SEND");
+		else
+		    fprintf(NetTrace, " %d (unknown)", pointer[1]);
+		for (i = 2; i < length; i++)
+		    fprintf(NetTrace, " ?%d?", pointer[i]);
+		break;
+	    case TELQUAL_IS:
+		if (--want_status_response < 0)
+		    want_status_response = 0;
+		if (NetTrace == stdout)
+		    fprintf(NetTrace, " IS\r\n");
+		else
+		    fprintf(NetTrace, " IS\n");
+
+		for (i = 2; i < length; i++) {
+		    switch(pointer[i]) {
+		    case DO:	cp = "DO"; goto common2;
+		    case DONT:	cp = "DONT"; goto common2;
+		    case WILL:	cp = "WILL"; goto common2;
+		    case WONT:	cp = "WONT"; goto common2;
+		    common2:
+			i++;
+			if (TELOPT_OK((int)pointer[i]))
+			    fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
+			else
+			    fprintf(NetTrace, " %s %d", cp, pointer[i]);
+
+			if (NetTrace == stdout)
+			    fprintf(NetTrace, "\r\n");
+			else
+			    fprintf(NetTrace, "\n");
+			break;
+
+		    case SB:
+			fprintf(NetTrace, " SB ");
+			i++;
+			j = k = i;
+			while (j < length) {
+			    if (pointer[j] == SE) {
+				if (j+1 == length)
+				    break;
+				if (pointer[j+1] == SE)
+				    j++;
+				else
+				    break;
+			    }
+			    pointer[k++] = pointer[j++];
+			}
+			printsub(0, &pointer[i], k - i);
+			if (i < length) {
+			    fprintf(NetTrace, " SE");
+			    i = j;
+			} else
+			    i = j - 1;
+
+			if (NetTrace == stdout)
+			    fprintf(NetTrace, "\r\n");
+			else
+			    fprintf(NetTrace, "\n");
+
+			break;
+
+		    default:
+			fprintf(NetTrace, " %d", pointer[i]);
+			break;
+		    }
+		}
+		break;
+	    }
+	    break;
+	  }
+
+	case TELOPT_XDISPLOC:
+	    fprintf(NetTrace, "X-DISPLAY-LOCATION ");
+	    switch (pointer[1]) {
+	    case TELQUAL_IS:
+		fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
+		break;
+	    case TELQUAL_SEND:
+		fprintf(NetTrace, "SEND");
+		break;
+	    default:
+		fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
+				pointer[1], pointer[1]);
+	    }
+	    break;
+
+	case TELOPT_NEW_ENVIRON:
+	    fprintf(NetTrace, "NEW-ENVIRON ");
+#ifdef	OLD_ENVIRON
+	    goto env_common1;
+	case TELOPT_OLD_ENVIRON:
+	    fprintf(NetTrace, "OLD-ENVIRON");
+	env_common1:
+#endif
+	    switch (pointer[1]) {
+	    case TELQUAL_IS:
+		fprintf(NetTrace, "IS ");
+		goto env_common;
+	    case TELQUAL_SEND:
+		fprintf(NetTrace, "SEND ");
+		goto env_common;
+	    case TELQUAL_INFO:
+		fprintf(NetTrace, "INFO ");
+	    env_common:
+		{
+		    register int noquote = 2;
+#if defined(ENV_HACK) && defined(OLD_ENVIRON)
+		    extern int old_env_var, old_env_value;
+#endif
+		    for (i = 2; i < length; i++ ) {
+			switch (pointer[i]) {
+			case NEW_ENV_VALUE:
+#ifdef OLD_ENVIRON
+		     /*	case NEW_ENV_OVAR: */
+			    if (pointer[0] == TELOPT_OLD_ENVIRON) {
+# ifdef	ENV_HACK
+				if (old_env_var == OLD_ENV_VALUE)
+				    fprintf(NetTrace, "\" (VALUE) " + noquote);
+				else
+# endif
+				    fprintf(NetTrace, "\" VAR " + noquote);
+			    } else
+#endif /* OLD_ENVIRON */
+				fprintf(NetTrace, "\" VALUE " + noquote);
+			    noquote = 2;
+			    break;
+
+			case NEW_ENV_VAR:
+#ifdef OLD_ENVIRON
+		     /* case OLD_ENV_VALUE: */
+			    if (pointer[0] == TELOPT_OLD_ENVIRON) {
+# ifdef	ENV_HACK
+				if (old_env_value == OLD_ENV_VAR)
+				    fprintf(NetTrace, "\" (VAR) " + noquote);
+				else
+# endif
+				    fprintf(NetTrace, "\" VALUE " + noquote);
+			    } else
+#endif /* OLD_ENVIRON */
+				fprintf(NetTrace, "\" VAR " + noquote);
+			    noquote = 2;
+			    break;
+
+			case ENV_ESC:
+			    fprintf(NetTrace, "\" ESC " + noquote);
+			    noquote = 2;
+			    break;
+
+			case ENV_USERVAR:
+			    fprintf(NetTrace, "\" USERVAR " + noquote);
+			    noquote = 2;
+			    break;
+
+			default:
+			def_case:
+			    if (isprint(pointer[i]) && pointer[i] != '"') {
+				if (noquote) {
+				    putc('"', NetTrace);
+				    noquote = 0;
+				}
+				putc(pointer[i], NetTrace);
+			    } else {
+				fprintf(NetTrace, "\" %03o " + noquote,
+							pointer[i]);
+				noquote = 2;
+			    }
+			    break;
+			}
+		    }
+		    if (!noquote)
+			putc('"', NetTrace);
+		    break;
+		}
+	    }
+	    break;
+
+	default:
+	    if (TELOPT_OK(pointer[0]))
+		fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
+	    else
+		fprintf(NetTrace, "%d (unknown)", pointer[0]);
+	    for (i = 1; i < length; i++)
+		fprintf(NetTrace, " %d", pointer[i]);
+	    break;
+	}
+	if (direction) {
+	    if (NetTrace == stdout)
+		fprintf(NetTrace, "\r\n");
+	    else
+		fprintf(NetTrace, "\n");
+	}
+	if (NetTrace == stdout)
+	    fflush(NetTrace);
+    }
+}
+
+/* EmptyTerminal - called to make sure that the terminal buffer is empty.
+ *			Note that we consider the buffer to run all the
+ *			way to the kernel (thus the select).
+ */
+
+    void
+EmptyTerminal()
+{
+#if	defined(unix) || defined(__APPLE__)
+    fd_set	o;
+
+    FD_ZERO(&o);
+#endif	/* defined(unix) || defined(__APPLE__) */
+
+    if (TTYBYTES() == 0) {
+#if	defined(unix) || defined(__APPLE__)
+	FD_SET(tout, &o);
+	(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
+			(struct timeval *) 0);	/* wait for TTLOWAT */
+#endif	/* defined(unix) || defined(__APPLE__) */
+    } else {
+	while (TTYBYTES()) {
+	    (void) ttyflush(0);
+#if	defined(unix) || defined(__APPLE__)
+	    FD_SET(tout, &o);
+	    (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
+				(struct timeval *) 0);	/* wait for TTLOWAT */
+#endif	/* defined(unix) || defined(__APPLE__) */
+	}
+    }
+}
+
+    void
+SetForExit()
+{
+    setconnmode(0);
+#if	defined(TN3270)
+    if (In3270) {
+	Finish3270();
+    }
+#else	/* defined(TN3270) */
+    do {
+	(void)telrcv();			/* Process any incoming data */
+	EmptyTerminal();
+    } while (ring_full_count(&netiring));	/* While there is any */
+#endif	/* defined(TN3270) */
+    setcommandmode();
+    fflush(stdout);
+    fflush(stderr);
+#if	defined(TN3270)
+    if (In3270) {
+	StopScreen(1);
+    }
+#endif	/* defined(TN3270) */
+    setconnmode(0);
+    EmptyTerminal();			/* Flush the path to the tty */
+    setcommandmode();
+}
+
+    void
+Exit(returnCode)
+    int returnCode;
+{
+    SetForExit();
+    exit(returnCode);
+}
+
+    void
+ExitString(string, returnCode)
+    char *string;
+    int returnCode;
+{
+    SetForExit();
+    fwrite(string, 1, strlen(string), stderr);
+    exit(returnCode);
+}
diff --git a/telnetd.tproj/Makefile b/telnetd.tproj/Makefile
new file mode 100644
index 0000000..63a671f
--- /dev/null
+++ b/telnetd.tproj/Makefile
@@ -0,0 +1,56 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = telnetd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = defs.h ext.h pathnames.h telnetd.h
+
+CFILES = authenc.c global.c slc.c state.c sys_term.c telnetd.c\
+         termstat.c utility.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble telnetd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON -DENV_HACK # -DAUTHENTICATION -DENCRYPTION
+WINDOWS_PB_CFLAGS = -DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON -DENV_HACK # -DAUTHENTICATION -DENCRYPTION
+PDO_UNIX_PB_CFLAGS = -DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON -DENV_HACK # -DAUTHENTICATION -DENCRYPTION
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/telnetd.tproj/Makefile.postamble b/telnetd.tproj/Makefile.postamble
new file mode 100644
index 0000000..7ede358
--- /dev/null
+++ b/telnetd.tproj/Makefile.postamble
@@ -0,0 +1,111 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
diff --git a/telnetd.tproj/Makefile.preamble b/telnetd.tproj/Makefile.preamble
new file mode 100644
index 0000000..70aa1d8
--- /dev/null
+++ b/telnetd.tproj/Makefile.preamble
@@ -0,0 +1,119 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR = 
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = -ltelnet
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+-include ../Makefile.include
diff --git a/telnetd.tproj/PB.project b/telnetd.tproj/PB.project
new file mode 100644
index 0000000..8dfbe1c
--- /dev/null
+++ b/telnetd.tproj/PB.project
@@ -0,0 +1,50 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (defs.h, ext.h, pathnames.h, telnetd.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (
+            authenc.c, 
+            global.c, 
+            slc.c, 
+            state.c, 
+            sys_term.c, 
+            telnetd.c, 
+            termstat.c, 
+            utility.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, telnetd.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON -DENV_HACK # -DAUTHENTICATION -DENCRYPTION"; 
+    NEXTSTEP_DOCUMENTEXTENSIONS = (); 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = "-DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON -DENV_HACK # -DAUTHENTICATION -DENCRYPTION"; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = telnetd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = "-DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON -DENV_HACK # -DAUTHENTICATION -DENCRYPTION"; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/telnetd.tproj/authenc.c b/telnetd.tproj/authenc.c
new file mode 100644
index 0000000..7891835
--- /dev/null
+++ b/telnetd.tproj/authenc.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)authenc.c	8.2 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
+#include "telnetd.h"
+#include <libtelnet/misc.h>
+
+	int
+net_write(str, len)
+	unsigned char *str;
+	int len;
+{
+	if (nfrontp + len < netobuf + BUFSIZ) {
+		memmove((void *)nfrontp, (void *)str, len);
+		nfrontp += len;
+		return(len);
+	}
+	return(0);
+}
+
+	void
+net_encrypt()
+{
+#ifdef	ENCRYPTION
+	char *s = (nclearto > nbackp) ? nclearto : nbackp;
+	if (s < nfrontp && encrypt_output) {
+		(*encrypt_output)((unsigned char *)s, nfrontp - s);
+	}
+	nclearto = nfrontp;
+#endif /* ENCRYPTION */
+}
+
+	int
+telnet_spin()
+{
+	ttloop();
+	return(0);
+}
+
+	char *
+telnet_getenv(val)
+	char *val;
+{
+	extern char *getenv();
+	return(getenv(val));
+}
+
+	char *
+telnet_gets(prompt, result, length, echo)
+	char *prompt;
+	char *result;
+	int length;
+	int echo;
+{
+	return((char *)0);
+}
+#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION) */
diff --git a/telnetd.tproj/defs.h b/telnetd.tproj/defs.h
new file mode 100644
index 0000000..1224895
--- /dev/null
+++ b/telnetd.tproj/defs.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)defs.h	8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * Telnet server defines
+ */
+#include <sys/types.h>
+#include <sys/param.h>
+
+#ifndef	BSD
+# define	BSD 43
+#endif
+
+#if	defined(CRAY) && !defined(LINEMODE)
+# define SYSV_TERMIO
+# define LINEMODE
+# define KLUDGELINEMODE
+# define DIAGNOSTICS
+# if defined(UNICOS50) && !defined(UNICOS5)
+#  define UNICOS5
+# endif
+# if !defined(UNICOS5)
+#  define BFTPDAEMON
+#  define HAS_IP_TOS
+# endif
+#endif /* CRAY */
+#if defined(UNICOS5) && !defined(NO_SETSID)
+# define NO_SETSID
+#endif
+
+#if defined(PRINTOPTIONS) && defined(DIAGNOSTICS)
+#define TELOPTS
+#define TELCMDS
+#define	SLC_NAMES
+#endif
+
+#if	defined(SYSV_TERMIO) && !defined(USE_TERMIO)
+# define	USE_TERMIO
+#endif
+
+#include <sys/socket.h>
+#ifndef	CRAY
+#include <sys/wait.h>
+#endif	/* CRAY */
+#include <fcntl.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#ifndef	FILIO_H
+#include <sys/ioctl.h>
+#else
+#include <sys/filio.h>
+#endif
+
+#include <netinet/in.h>
+
+#include <arpa/telnet.h>
+
+#include <stdio.h>
+#ifdef	__STDC__
+#include <stdlib.h>
+#endif
+#include <signal.h>
+#include <errno.h>
+#include <netdb.h>
+#include <syslog.h>
+#ifndef	LOG_DAEMON
+#define	LOG_DAEMON	0
+#endif
+#ifndef	LOG_ODELAY
+#define	LOG_ODELAY	0
+#endif
+#include <ctype.h>
+#ifndef NO_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#ifndef	USE_TERMIO
+#include <sgtty.h>
+#else
+# ifdef	SYSV_TERMIO
+# include <termio.h>
+# else
+#  ifdef __APPLE__
+#   include <sys/termios.h>
+#  else
+#   include <termios.h>
+#  endif
+# endif
+#endif
+#if !defined(USE_TERMIO) || defined(NO_CC_T)
+typedef unsigned char cc_t;
+#endif
+
+#ifdef	__STDC__
+#include <unistd.h>
+#endif
+
+#ifndef _POSIX_VDISABLE
+# ifdef VDISABLE
+#  define _POSIX_VDISABLE VDISABLE
+# else
+#  define _POSIX_VDISABLE ((unsigned char)'\377')
+# endif
+#endif
+
+
+#ifdef	CRAY
+# ifdef	CRAY1
+# include <sys/pty.h>
+#  ifndef FD_ZERO
+# include <sys/select.h>
+#  endif /* FD_ZERO */
+# endif	/* CRAY1 */
+
+#include <memory.h>
+#endif	/* CRAY */
+
+#ifdef __hpux
+#include <sys/ptyio.h>
+#endif
+
+#if	!defined(TIOCSCTTY) && defined(TCSETCTTY)
+# define	TIOCSCTTY TCSETCTTY
+#endif
+
+#ifndef	FD_SET
+#ifndef	HAVE_fd_set
+typedef struct fd_set { int fds_bits[1]; } fd_set;
+#endif
+
+#define	FD_SET(n, p)	((p)->fds_bits[0] |= (1<<(n)))
+#define	FD_CLR(n, p)	((p)->fds_bits[0] &= ~(1<<(n)))
+#define	FD_ISSET(n, p)	((p)->fds_bits[0] & (1<<(n)))
+#define FD_ZERO(p)	((p)->fds_bits[0] = 0)
+#endif	/* FD_SET */
+
+/*
+ * I/O data buffers defines
+ */
+#define	NETSLOP	64
+#ifdef CRAY
+#undef BUFSIZ
+#define BUFSIZ  2048
+#endif
+
+#define	NIACCUM(c)	{   *netip++ = c; \
+			    ncc++; \
+			}
+
+/* clock manipulations */
+#define	settimer(x)	(clocks.x = ++clocks.system)
+#define	sequenceIs(x,y)	(clocks.x < clocks.y)
+
+/*
+ * Linemode support states, in decreasing order of importance
+ */
+#define REAL_LINEMODE	0x04
+#define KLUDGE_OK	0x03
+#define	NO_AUTOKLUDGE	0x02
+#define KLUDGE_LINEMODE	0x01
+#define NO_LINEMODE	0x00
+
+/*
+ * Structures of information for each special character function.
+ */
+typedef struct {
+	unsigned char	flag;		/* the flags for this function */
+	cc_t		val;		/* the value of the special character */
+} slcent, *Slcent;
+
+typedef struct {
+	slcent		defset;		/* the default settings */
+	slcent		current;	/* the current settings */
+	cc_t		*sptr;		/* a pointer to the char in */
+					/* system data structures */
+} slcfun, *Slcfun;
+
+#ifdef DIAGNOSTICS
+/*
+ * Diagnostics capabilities
+ */
+#define	TD_REPORT	0x01	/* Report operations to client */
+#define TD_EXERCISE	0x02	/* Exercise client's implementation */
+#define TD_NETDATA	0x04	/* Display received data stream */
+#define TD_PTYDATA	0x08	/* Display data passed to pty */
+#define	TD_OPTIONS	0x10	/* Report just telnet options */
+#endif /* DIAGNOSTICS */
+
+/*
+ * We keep track of each side of the option negotiation.
+ */
+
+#define	MY_STATE_WILL		0x01
+#define	MY_WANT_STATE_WILL	0x02
+#define	MY_STATE_DO		0x04
+#define	MY_WANT_STATE_DO	0x08
+
+/*
+ * Macros to check the current state of things
+ */
+
+#define	my_state_is_do(opt)		(options[opt]&MY_STATE_DO)
+#define	my_state_is_will(opt)		(options[opt]&MY_STATE_WILL)
+#define my_want_state_is_do(opt)	(options[opt]&MY_WANT_STATE_DO)
+#define my_want_state_is_will(opt)	(options[opt]&MY_WANT_STATE_WILL)
+
+#define	my_state_is_dont(opt)		(!my_state_is_do(opt))
+#define	my_state_is_wont(opt)		(!my_state_is_will(opt))
+#define my_want_state_is_dont(opt)	(!my_want_state_is_do(opt))
+#define my_want_state_is_wont(opt)	(!my_want_state_is_will(opt))
+
+#define	set_my_state_do(opt)		(options[opt] |= MY_STATE_DO)
+#define	set_my_state_will(opt)		(options[opt] |= MY_STATE_WILL)
+#define	set_my_want_state_do(opt)	(options[opt] |= MY_WANT_STATE_DO)
+#define	set_my_want_state_will(opt)	(options[opt] |= MY_WANT_STATE_WILL)
+
+#define	set_my_state_dont(opt)		(options[opt] &= ~MY_STATE_DO)
+#define	set_my_state_wont(opt)		(options[opt] &= ~MY_STATE_WILL)
+#define	set_my_want_state_dont(opt)	(options[opt] &= ~MY_WANT_STATE_DO)
+#define	set_my_want_state_wont(opt)	(options[opt] &= ~MY_WANT_STATE_WILL)
+
+/*
+ * Tricky code here.  What we want to know is if the MY_STATE_WILL
+ * and MY_WANT_STATE_WILL bits have the same value.  Since the two
+ * bits are adjacent, a little arithmatic will show that by adding
+ * in the lower bit, the upper bit will be set if the two bits were
+ * different, and clear if they were the same.
+ */
+#define my_will_wont_is_changing(opt) \
+			((options[opt]+MY_STATE_WILL) & MY_WANT_STATE_WILL)
+
+#define my_do_dont_is_changing(opt) \
+			((options[opt]+MY_STATE_DO) & MY_WANT_STATE_DO)
+
+/*
+ * Make everything symetrical
+ */
+
+#define	HIS_STATE_WILL			MY_STATE_DO
+#define	HIS_WANT_STATE_WILL		MY_WANT_STATE_DO
+#define HIS_STATE_DO			MY_STATE_WILL
+#define HIS_WANT_STATE_DO		MY_WANT_STATE_WILL
+
+#define	his_state_is_do			my_state_is_will
+#define	his_state_is_will		my_state_is_do
+#define his_want_state_is_do		my_want_state_is_will
+#define his_want_state_is_will		my_want_state_is_do
+
+#define	his_state_is_dont		my_state_is_wont
+#define	his_state_is_wont		my_state_is_dont
+#define his_want_state_is_dont		my_want_state_is_wont
+#define his_want_state_is_wont		my_want_state_is_dont
+
+#define	set_his_state_do		set_my_state_will
+#define	set_his_state_will		set_my_state_do
+#define	set_his_want_state_do		set_my_want_state_will
+#define	set_his_want_state_will		set_my_want_state_do
+
+#define	set_his_state_dont		set_my_state_wont
+#define	set_his_state_wont		set_my_state_dont
+#define	set_his_want_state_dont		set_my_want_state_wont
+#define	set_his_want_state_wont		set_my_want_state_dont
+
+#define his_will_wont_is_changing	my_do_dont_is_changing
+#define his_do_dont_is_changing		my_will_wont_is_changing
diff --git a/telnetd.tproj/ext.h b/telnetd.tproj/ext.h
new file mode 100644
index 0000000..18ab636
--- /dev/null
+++ b/telnetd.tproj/ext.h
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ext.h	8.2 (Berkeley) 12/15/93
+ */
+
+/*
+ * Telnet server variable declarations
+ */
+extern char	options[256];
+extern char	do_dont_resp[256];
+extern char	will_wont_resp[256];
+extern int	linemode;	/* linemode on/off */
+#ifdef	LINEMODE
+extern int	uselinemode;	/* what linemode to use (on/off) */
+extern int	editmode;	/* edit modes in use */
+extern int	useeditmode;	/* edit modes to use */
+extern int	alwayslinemode;	/* command line option */
+# ifdef	KLUDGELINEMODE
+extern int	lmodetype;	/* Client support for linemode */
+# endif	/* KLUDGELINEMODE */
+#endif	/* LINEMODE */
+extern int	flowmode;	/* current flow control state */
+extern int	restartany;	/* restart output on any character state */
+#ifdef DIAGNOSTICS
+extern int	diagnostic;	/* telnet diagnostic capabilities */
+#endif /* DIAGNOSTICS */
+#ifdef BFTPDAEMON
+extern int	bftpd;		/* behave as bftp daemon */
+#endif /* BFTPDAEMON */
+#if	defined(SecurID)
+extern int	require_SecurID;
+#endif
+#if	defined(AUTHENTICATION)
+extern int	auth_level;
+#endif
+
+extern slcfun	slctab[NSLC + 1];	/* slc mapping table */
+
+extern char	*terminaltype;
+
+/*
+ * I/O data buffers, pointers, and counters.
+ */
+extern char	ptyobuf[BUFSIZ+NETSLOP], *pfrontp, *pbackp;
+
+extern char	netibuf[BUFSIZ], *netip;
+
+extern char	netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp;
+extern char	*neturg;		/* one past last bye of urgent data */
+
+extern int	pcc, ncc;
+
+#if defined(CRAY2) && defined(UNICOS5)
+extern int unpcc;  /* characters left unprocessed by CRAY-2 terminal routine */
+extern char *unptyip;  /* pointer to remaining characters in buffer */
+#endif
+
+extern int	pty, net;
+#ifdef __APPLE__
+extern char	line[16];
+#else
+extern char	*line;
+#endif /* !NeXT */
+extern int	SYNCHing;		/* we are in TELNET SYNCH mode */
+
+#ifndef	P
+# ifdef	__STDC__
+#  define P(x)	x
+# else
+#  define P(x)	()
+# endif
+#endif
+
+extern void
+	_termstat P((void)),
+	add_slc P((int, int, int)),
+	check_slc P((void)),
+	change_slc P((int, int, int)),
+	cleanup P((int)),
+	clientstat P((int, int, int)),
+	copy_termbuf P((char *, int)),
+	deferslc P((void)),
+	defer_terminit P((void)),
+	do_opt_slc P((unsigned char *, int)),
+	doeof P((void)),
+	dooption P((int)),
+	dontoption P((int)),
+	edithost P((char *, char *)),
+	fatal P((int, char *)),
+	fatalperror P((int, char *)),
+	get_slc_defaults P((void)),
+	init_env P((void)),
+	init_termbuf P((void)),
+	interrupt P((void)),
+	localstat P((void)),
+	flowstat P((void)),
+	netclear P((void)),
+	netflush P((void)),
+#ifdef DIAGNOSTICS
+	printoption P((char *, int)),
+	printdata P((char *, char *, int)),
+	printsub P((int, unsigned char *, int)),
+#endif
+	ptyflush P((void)),
+	putchr P((int)),
+	putf P((char *, char *)),
+	recv_ayt P((void)),
+	send_do P((int, int)),
+	send_dont P((int, int)),
+	send_slc P((void)),
+	send_status P((void)),
+	send_will P((int, int)),
+	send_wont P((int, int)),
+	sendbrk P((void)),
+	sendsusp P((void)),
+	set_termbuf P((void)),
+	start_login P((char *, int, char *)),
+	start_slc P((int)),
+#if	defined(AUTHENTICATION)
+	start_slave P((char *)),
+#else
+	start_slave P((char *, int, char *)),
+#endif
+	suboption P((void)),
+	telrcv P((void)),
+	ttloop P((void)),
+	tty_binaryin P((int)),
+	tty_binaryout P((int));
+
+extern int
+	end_slc P((unsigned char **)),
+	getnpty P((void)),
+#ifndef convex
+	getpty P((int *)),
+#endif
+	login_tty P((int)),
+	spcset P((int, cc_t *, cc_t **)),
+	stilloob P((int)),
+	terminit P((void)),
+	termstat P((void)),
+	tty_flowmode P((void)),
+	tty_restartany P((void)),
+	tty_isbinaryin P((void)),
+	tty_isbinaryout P((void)),
+	tty_iscrnl P((void)),
+	tty_isecho P((void)),
+	tty_isediting P((void)),
+	tty_islitecho P((void)),
+	tty_isnewmap P((void)),
+	tty_israw P((void)),
+	tty_issofttab P((void)),
+	tty_istrapsig P((void)),
+	tty_linemode P((void));
+
+extern void
+	tty_rspeed P((int)),
+	tty_setecho P((int)),
+	tty_setedit P((int)),
+	tty_setlinemode P((int)),
+	tty_setlitecho P((int)),
+	tty_setsig P((int)),
+	tty_setsofttab P((int)),
+	tty_tspeed P((int)),
+	willoption P((int)),
+	wontoption P((int)),
+	writenet P((unsigned char *, int));
+
+#ifdef	ENCRYPTION
+extern void	(*encrypt_output) P((unsigned char *, int));
+extern int	(*decrypt_input) P((int));
+extern char	*nclearto;
+#endif	/* ENCRYPTION */
+
+
+/*
+ * The following are some clocks used to decide how to interpret
+ * the relationship between various variables.
+ */
+
+extern struct {
+    int
+	system,			/* what the current time is */
+	echotoggle,		/* last time user entered echo character */
+	modenegotiated,		/* last time operating mode negotiated */
+	didnetreceive,		/* last time we read data from network */
+	ttypesubopt,		/* ttype subopt is received */
+	tspeedsubopt,		/* tspeed subopt is received */
+	environsubopt,		/* environ subopt is received */
+	oenvironsubopt,		/* old environ subopt is received */
+	xdisplocsubopt,		/* xdisploc subopt is received */
+	baseline,		/* time started to do timed action */
+	gotDM;			/* when did we last see a data mark */
+} clocks;
+
+
+#if	defined(CRAY2) && defined(UNICOS5)
+extern int	needtermstat;
+#endif
+
+#ifndef	DEFAULT_IM
+# ifdef CRAY
+#  define DEFAULT_IM	"\r\n\r\nCray UNICOS (%h) (%t)\r\n\r\r\n\r"
+# else
+#  ifdef sun
+#   define DEFAULT_IM	"\r\n\r\nSunOS UNIX (%h) (%t)\r\n\r\r\n\r"
+#  else
+#   ifdef ultrix
+#    define DEFAULT_IM	"\r\n\r\nULTRIX (%h) (%t)\r\n\r\r\n\r"
+#   else
+#    define DEFAULT_IM	"\r\n\r\n4.4 BSD (%h) (%t)\r\n\r\r\n\r"
+#   endif
+#  endif
+# endif
+#endif
diff --git a/telnetd.tproj/global.c b/telnetd.tproj/global.c
new file mode 100644
index 0000000..ebed4ed
--- /dev/null
+++ b/telnetd.tproj/global.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)global.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * Allocate global variables.  We do this
+ * by including the header file that defines
+ * them all as externs, but first we define
+ * the keyword "extern" to be nothing, so that
+ * we will actually allocate the space.
+ */
+
+#include "defs.h"
+#define extern
+#include "ext.h"
diff --git a/telnetd.tproj/pathnames.h b/telnetd.tproj/pathnames.h
new file mode 100644
index 0000000..c9ac41f
--- /dev/null
+++ b/telnetd.tproj/pathnames.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/4/93
+ */
+
+#if BSD > 43
+
+# include <paths.h>
+
+# ifndef _PATH_LOGIN
+#  define	_PATH_LOGIN	"/usr/bin/login"
+# endif
+
+#else
+ 
+# define	_PATH_TTY	"/dev/tty"
+# ifndef _PATH_LOGIN
+#  define	_PATH_LOGIN	"/bin/login"
+# endif
+
+#endif
+
+#ifdef BFTPDAEMON
+#define		BFTPPATH	"/usr/ucb/bftp"
+#endif  /* BFTPDAEMON */
diff --git a/telnetd.tproj/slc.c b/telnetd.tproj/slc.c
new file mode 100644
index 0000000..a7b280d
--- /dev/null
+++ b/telnetd.tproj/slc.c
@@ -0,0 +1,514 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)slc.c	8.2 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#include "telnetd.h"
+
+#ifdef	LINEMODE
+/*
+ * local varibles
+ */
+static unsigned char	*def_slcbuf = (unsigned char *)0;
+static int		def_slclen = 0;
+static int		slcchange;	/* change to slc is requested */
+static unsigned char	*slcptr;	/* pointer into slc buffer */
+static unsigned char	slcbuf[NSLC*6];	/* buffer for slc negotiation */
+
+/*
+ * send_slc
+ *
+ * Write out the current special characters to the client.
+ */
+	void
+send_slc()
+{
+	register int i;
+
+	/*
+	 * Send out list of triplets of special characters
+	 * to client.  We only send info on the characters
+	 * that are currently supported.
+	 */
+	for (i = 1; i <= NSLC; i++) {
+		if ((slctab[i].defset.flag & SLC_LEVELBITS) == SLC_NOSUPPORT)
+			continue;
+		add_slc((unsigned char)i, slctab[i].current.flag,
+							slctab[i].current.val);
+	}
+
+}  /* end of send_slc */
+
+/*
+ * default_slc
+ *
+ * Set pty special characters to all the defaults.
+ */
+	void
+default_slc()
+{
+	register int i;
+
+	for (i = 1; i <= NSLC; i++) {
+		slctab[i].current.val = slctab[i].defset.val;
+		if (slctab[i].current.val == (cc_t)(_POSIX_VDISABLE))
+			slctab[i].current.flag = SLC_NOSUPPORT;
+		else
+			slctab[i].current.flag = slctab[i].defset.flag;
+		if (slctab[i].sptr) {
+			*(slctab[i].sptr) = slctab[i].defset.val;
+		}
+	}
+	slcchange = 1;
+
+}  /* end of default_slc */
+#endif	/* LINEMODE */
+
+/*
+ * get_slc_defaults
+ *
+ * Initialize the slc mapping table.
+ */
+	void
+get_slc_defaults()
+{
+	register int i;
+
+	init_termbuf();
+
+	for (i = 1; i <= NSLC; i++) {
+		slctab[i].defset.flag =
+			spcset(i, &slctab[i].defset.val, &slctab[i].sptr);
+		slctab[i].current.flag = SLC_NOSUPPORT;
+		slctab[i].current.val = 0;
+	}
+
+}  /* end of get_slc_defaults */
+
+#ifdef	LINEMODE
+/*
+ * add_slc
+ *
+ * Add an slc triplet to the slc buffer.
+ */
+	void
+add_slc(func, flag, val)
+	register char func, flag;
+	register cc_t val;
+{
+
+	if ((*slcptr++ = (unsigned char)func) == 0xff)
+		*slcptr++ = 0xff;
+
+	if ((*slcptr++ = (unsigned char)flag) == 0xff)
+		*slcptr++ = 0xff;
+
+	if ((*slcptr++ = (unsigned char)val) == 0xff)
+		*slcptr++ = 0xff;
+
+}  /* end of add_slc */
+
+/*
+ * start_slc
+ *
+ * Get ready to process incoming slc's and respond to them.
+ *
+ * The parameter getit is non-zero if it is necessary to grab a copy
+ * of the terminal control structures.
+ */
+	void
+start_slc(getit)
+	register int getit;
+{
+
+	slcchange = 0;
+	if (getit)
+		init_termbuf();
+	(void) sprintf((char *)slcbuf, "%c%c%c%c",
+					IAC, SB, TELOPT_LINEMODE, LM_SLC);
+	slcptr = slcbuf + 4;
+
+}  /* end of start_slc */
+
+/*
+ * end_slc
+ *
+ * Finish up the slc negotiation.  If something to send, then send it.
+ */
+	int
+end_slc(bufp)
+	register unsigned char **bufp;
+{
+	register int len;
+	void netflush();
+
+	/*
+	 * If a change has occured, store the new terminal control
+	 * structures back to the terminal driver.
+	 */
+	if (slcchange) {
+		set_termbuf();
+	}
+
+	/*
+	 * If the pty state has not yet been fully processed and there is a
+	 * deferred slc request from the client, then do not send any
+	 * sort of slc negotiation now.  We will respond to the client's
+	 * request very soon.
+	 */
+	if (def_slcbuf && (terminit() == 0)) {
+		return(0);
+	}
+
+	if (slcptr > (slcbuf + 4)) {
+		if (bufp) {
+			*bufp = &slcbuf[4];
+			return(slcptr - slcbuf - 4);
+		} else {
+			(void) sprintf((char *)slcptr, "%c%c", IAC, SE);
+			slcptr += 2;
+			len = slcptr - slcbuf;
+			writenet(slcbuf, len);
+			netflush();  /* force it out immediately */
+			DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2););
+		}
+	}
+	return (0);
+
+}  /* end of end_slc */
+
+/*
+ * process_slc
+ *
+ * Figure out what to do about the client's slc
+ */
+	void
+process_slc(func, flag, val)
+	register unsigned char func, flag;
+	register cc_t val;
+{
+	register int hislevel, mylevel, ack;
+
+	/*
+	 * Ensure that we know something about this function
+	 */
+	if (func > NSLC) {
+		add_slc(func, SLC_NOSUPPORT, 0);
+		return;
+	}
+
+	/*
+	 * Process the special case requests of 0 SLC_DEFAULT 0
+	 * and 0 SLC_VARIABLE 0.  Be a little forgiving here, don't
+	 * worry about whether the value is actually 0 or not.
+	 */
+	if (func == 0) {
+		if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) {
+			default_slc();
+			send_slc();
+		} else if (flag == SLC_VARIABLE) {
+			send_slc();
+		}
+		return;
+	}
+
+	/*
+	 * Appears to be a function that we know something about.  So
+	 * get on with it and see what we know.
+	 */
+
+	hislevel = flag & SLC_LEVELBITS;
+	mylevel = slctab[func].current.flag & SLC_LEVELBITS;
+	ack = flag & SLC_ACK;
+	/*
+	 * ignore the command if:
+	 * the function value and level are the same as what we already have;
+	 * or the level is the same and the ack bit is set
+	 */
+	if (hislevel == mylevel && (val == slctab[func].current.val || ack)) {
+		return;
+	} else if (ack) {
+		/*
+		 * If we get here, we got an ack, but the levels don't match.
+		 * This shouldn't happen.  If it does, it is probably because
+		 * we have sent two requests to set a variable without getting
+		 * a response between them, and this is the first response.
+		 * So, ignore it, and wait for the next response.
+		 */
+		return;
+	} else {
+		change_slc(func, flag, val);
+	}
+
+}  /* end of process_slc */
+
+/*
+ * change_slc
+ *
+ * Process a request to change one of our special characters.
+ * Compare client's request with what we are capable of supporting.
+ */
+	void
+change_slc(func, flag, val)
+	register char func, flag;
+	register cc_t val;
+{
+	register int hislevel, mylevel;
+
+	hislevel = flag & SLC_LEVELBITS;
+	mylevel = slctab[func].defset.flag & SLC_LEVELBITS;
+	/*
+	 * If client is setting a function to NOSUPPORT
+	 * or DEFAULT, then we can easily and directly
+	 * accomodate the request.
+	 */
+	if (hislevel == SLC_NOSUPPORT) {
+		slctab[func].current.flag = flag;
+		slctab[func].current.val = (cc_t)_POSIX_VDISABLE;
+		flag |= SLC_ACK;
+		add_slc(func, flag, val);
+		return;
+	}
+	if (hislevel == SLC_DEFAULT) {
+		/*
+		 * Special case here.  If client tells us to use
+		 * the default on a function we don't support, then
+		 * return NOSUPPORT instead of what we may have as a
+		 * default level of DEFAULT.
+		 */
+		if (mylevel == SLC_DEFAULT) {
+			slctab[func].current.flag = SLC_NOSUPPORT;
+		} else {
+			slctab[func].current.flag = slctab[func].defset.flag;
+		}
+		slctab[func].current.val = slctab[func].defset.val;
+		add_slc(func, slctab[func].current.flag,
+						slctab[func].current.val);
+		return;
+	}
+
+	/*
+	 * Client wants us to change to a new value or he
+	 * is telling us that he can't change to our value.
+	 * Some of the slc's we support and can change,
+	 * some we do support but can't change,
+	 * and others we don't support at all.
+	 * If we can change it then we have a pointer to
+	 * the place to put the new value, so change it,
+	 * otherwise, continue the negotiation.
+	 */
+	if (slctab[func].sptr) {
+		/*
+		 * We can change this one.
+		 */
+		slctab[func].current.val = val;
+		*(slctab[func].sptr) = val;
+		slctab[func].current.flag = flag;
+		flag |= SLC_ACK;
+		slcchange = 1;
+		add_slc(func, flag, val);
+	} else {
+		/*
+		* It is not possible for us to support this
+		* request as he asks.
+		*
+		* If our level is DEFAULT, then just ack whatever was
+		* sent.
+		*
+		* If he can't change and we can't change,
+		* then degenerate to NOSUPPORT.
+		*
+		* Otherwise we send our level back to him, (CANTCHANGE
+		* or NOSUPPORT) and if CANTCHANGE, send
+		* our value as well.
+		*/
+		if (mylevel == SLC_DEFAULT) {
+			slctab[func].current.flag = flag;
+			slctab[func].current.val = val;
+			flag |= SLC_ACK;
+		} else if (hislevel == SLC_CANTCHANGE &&
+				    mylevel == SLC_CANTCHANGE) {
+			flag &= ~SLC_LEVELBITS;
+			flag |= SLC_NOSUPPORT;
+			slctab[func].current.flag = flag;
+		} else {
+			flag &= ~SLC_LEVELBITS;
+			flag |= mylevel;
+			slctab[func].current.flag = flag;
+			if (mylevel == SLC_CANTCHANGE) {
+				slctab[func].current.val =
+					slctab[func].defset.val;
+				val = slctab[func].current.val;
+			}
+		}
+		add_slc(func, flag, val);
+	}
+
+}  /* end of change_slc */
+
+#if	defined(USE_TERMIO) && (VEOF == VMIN)
+cc_t oldeofc = '\004';
+#endif
+
+/*
+ * check_slc
+ *
+ * Check the special characters in use and notify the client if any have
+ * changed.  Only those characters that are capable of being changed are
+ * likely to have changed.  If a local change occurs, kick the support level
+ * and flags up to the defaults.
+ */
+	void
+check_slc()
+{
+	register int i;
+
+	for (i = 1; i <= NSLC; i++) {
+#if	defined(USE_TERMIO) && (VEOF == VMIN)
+		/*
+		 * In a perfect world this would be a neat little
+		 * function.  But in this world, we should not notify
+		 * client of changes to the VEOF char when
+		 * ICANON is off, because it is not representing
+		 * a special character.
+		 */
+		if (i == SLC_EOF) {
+			if (!tty_isediting())
+				continue;
+			else if (slctab[i].sptr)
+				oldeofc = *(slctab[i].sptr);
+		}
+#endif	/* defined(USE_TERMIO) && defined(SYSV_TERMIO) */
+		if (slctab[i].sptr &&
+				(*(slctab[i].sptr) != slctab[i].current.val)) {
+			slctab[i].current.val = *(slctab[i].sptr);
+			if (*(slctab[i].sptr) == (cc_t)_POSIX_VDISABLE)
+				slctab[i].current.flag = SLC_NOSUPPORT;
+			else
+				slctab[i].current.flag = slctab[i].defset.flag;
+			add_slc((unsigned char)i, slctab[i].current.flag,
+						slctab[i].current.val);
+		}
+	}
+}  /* check_slc */
+
+/*
+ * do_opt_slc
+ *
+ * Process an slc option buffer.  Defer processing of incoming slc's
+ * until after the terminal state has been processed.  Save the first slc
+ * request that comes along, but discard all others.
+ *
+ * ptr points to the beginning of the buffer, len is the length.
+ */
+	void
+do_opt_slc(ptr, len)
+	register unsigned char *ptr;
+	register int len;
+{
+	register unsigned char func, flag;
+	cc_t val;
+	register unsigned char *end = ptr + len;
+
+	if (terminit()) {  /* go ahead */
+		while (ptr < end) {
+			func = *ptr++;
+			if (ptr >= end) break;
+			flag = *ptr++;
+			if (ptr >= end) break;
+			val = (cc_t)*ptr++;
+
+			process_slc(func, flag, val);
+
+		}
+	} else {
+		/*
+		 * save this slc buffer if it is the first, otherwise dump
+		 * it.
+		 */
+		if (def_slcbuf == (unsigned char *)0) {
+			def_slclen = len;
+			def_slcbuf = (unsigned char *)malloc((unsigned)len);
+			if (def_slcbuf == (unsigned char *)0)
+				return;  /* too bad */
+			memmove(def_slcbuf, ptr, len);
+		}
+	}
+
+}  /* end of do_opt_slc */
+
+/*
+ * deferslc
+ *
+ * Do slc stuff that was deferred.
+ */
+	void
+deferslc()
+{
+	if (def_slcbuf) {
+		start_slc(1);
+		do_opt_slc(def_slcbuf, def_slclen);
+		(void) end_slc(0);
+		free(def_slcbuf);
+		def_slcbuf = (unsigned char *)0;
+		def_slclen = 0;
+	}
+
+}  /* end of deferslc */
+
+#endif	/* LINEMODE */
diff --git a/telnetd.tproj/state.c b/telnetd.tproj/state.c
new file mode 100644
index 0000000..60de854
--- /dev/null
+++ b/telnetd.tproj/state.c
@@ -0,0 +1,1635 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)state.c	8.5 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#include "telnetd.h"
+#if	defined(AUTHENTICATION)
+#include <libtelnet/auth.h>
+#endif
+
+unsigned char	doopt[] = { IAC, DO, '%', 'c', 0 };
+unsigned char	dont[] = { IAC, DONT, '%', 'c', 0 };
+unsigned char	will[] = { IAC, WILL, '%', 'c', 0 };
+unsigned char	wont[] = { IAC, WONT, '%', 'c', 0 };
+int	not42 = 1;
+
+/*
+ * Buffer for sub-options, and macros
+ * for suboptions buffer manipulations
+ */
+unsigned char subbuffer[512], *subpointer= subbuffer, *subend= subbuffer;
+
+#define	SB_CLEAR()	subpointer = subbuffer
+#define	SB_TERM()	{ subend = subpointer; SB_CLEAR(); }
+#define	SB_ACCUM(c)	if (subpointer < (subbuffer+sizeof subbuffer)) { \
+				*subpointer++ = (c); \
+			}
+#define	SB_GET()	((*subpointer++)&0xff)
+#define	SB_EOF()	(subpointer >= subend)
+#define	SB_LEN()	(subend - subpointer)
+
+#ifdef	ENV_HACK
+unsigned char *subsave;
+#define SB_SAVE()	subsave = subpointer;
+#define	SB_RESTORE()	subpointer = subsave;
+#endif
+
+
+/*
+ * State for recv fsm
+ */
+#define	TS_DATA		0	/* base state */
+#define	TS_IAC		1	/* look for double IAC's */
+#define	TS_CR		2	/* CR-LF ->'s CR */
+#define	TS_SB		3	/* throw away begin's... */
+#define	TS_SE		4	/* ...end's (suboption negotiation) */
+#define	TS_WILL		5	/* will option negotiation */
+#define	TS_WONT		6	/* wont " */
+#define	TS_DO		7	/* do " */
+#define	TS_DONT		8	/* dont " */
+
+	void
+telrcv()
+{
+	register int c;
+	static int state = TS_DATA;
+#if	defined(CRAY2) && defined(UNICOS5)
+	char *opfrontp = pfrontp;
+#endif
+
+	while (ncc > 0) {
+		if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
+			break;
+		c = *netip++ & 0377, ncc--;
+#ifdef	ENCRYPTION
+		if (decrypt_input)
+			c = (*decrypt_input)(c);
+#endif	/* ENCRYPTION */
+		switch (state) {
+
+		case TS_CR:
+			state = TS_DATA;
+			/* Strip off \n or \0 after a \r */
+			if ((c == 0) || (c == '\n')) {
+				break;
+			}
+			/* FALL THROUGH */
+
+		case TS_DATA:
+			if (c == IAC) {
+				state = TS_IAC;
+				break;
+			}
+			/*
+			 * We now map \r\n ==> \r for pragmatic reasons.
+			 * Many client implementations send \r\n when
+			 * the user hits the CarriageReturn key.
+			 *
+			 * We USED to map \r\n ==> \n, since \r\n says
+			 * that we want to be in column 1 of the next
+			 * printable line, and \n is the standard
+			 * unix way of saying that (\r is only good
+			 * if CRMOD is set, which it normally is).
+			 */
+			if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) {
+				int nc = *netip;
+#ifdef	ENCRYPTION
+				if (decrypt_input)
+					nc = (*decrypt_input)(nc & 0xff);
+#endif	/* ENCRYPTION */
+#ifdef	LINEMODE
+				/*
+				 * If we are operating in linemode,
+				 * convert to local end-of-line.
+				 */
+				if (linemode && (ncc > 0) && (('\n' == nc) ||
+					 ((0 == nc) && tty_iscrnl())) ) {
+					netip++; ncc--;
+					c = '\n';
+				} else
+#endif
+				{
+#ifdef	ENCRYPTION
+					if (decrypt_input)
+						(void)(*decrypt_input)(-1);
+#endif	/* ENCRYPTION */
+					state = TS_CR;
+				}
+			}
+			*pfrontp++ = c;
+			break;
+
+		case TS_IAC:
+gotiac:			switch (c) {
+
+			/*
+			 * Send the process on the pty side an
+			 * interrupt.  Do this with a NULL or
+			 * interrupt char; depending on the tty mode.
+			 */
+			case IP:
+				DIAG(TD_OPTIONS,
+					printoption("td: recv IAC", c));
+				interrupt();
+				break;
+
+			case BREAK:
+				DIAG(TD_OPTIONS,
+					printoption("td: recv IAC", c));
+				sendbrk();
+				break;
+
+			/*
+			 * Are You There?
+			 */
+			case AYT:
+				DIAG(TD_OPTIONS,
+					printoption("td: recv IAC", c));
+				recv_ayt();
+				break;
+
+			/*
+			 * Abort Output
+			 */
+			case AO:
+			    {
+				DIAG(TD_OPTIONS,
+					printoption("td: recv IAC", c));
+				ptyflush();	/* half-hearted */
+				init_termbuf();
+
+				if (slctab[SLC_AO].sptr &&
+				    *slctab[SLC_AO].sptr != (cc_t)(_POSIX_VDISABLE)) {
+				    *pfrontp++ =
+					(unsigned char)*slctab[SLC_AO].sptr;
+				}
+
+				netclear();	/* clear buffer back */
+				*nfrontp++ = IAC;
+				*nfrontp++ = DM;
+				neturg = nfrontp-1; /* off by one XXX */
+				DIAG(TD_OPTIONS,
+					printoption("td: send IAC", DM));
+				break;
+			    }
+
+			/*
+			 * Erase Character and
+			 * Erase Line
+			 */
+			case EC:
+			case EL:
+			    {
+				cc_t ch;
+
+				DIAG(TD_OPTIONS,
+					printoption("td: recv IAC", c));
+				ptyflush();	/* half-hearted */
+				init_termbuf();
+				if (c == EC)
+					ch = *slctab[SLC_EC].sptr;
+				else
+					ch = *slctab[SLC_EL].sptr;
+				if (ch != (cc_t)(_POSIX_VDISABLE))
+					*pfrontp++ = (unsigned char)ch;
+				break;
+			    }
+
+			/*
+			 * Check for urgent data...
+			 */
+			case DM:
+				DIAG(TD_OPTIONS,
+					printoption("td: recv IAC", c));
+				SYNCHing = stilloob(net);
+				settimer(gotDM);
+				break;
+
+
+			/*
+			 * Begin option subnegotiation...
+			 */
+			case SB:
+				state = TS_SB;
+				SB_CLEAR();
+				continue;
+
+			case WILL:
+				state = TS_WILL;
+				continue;
+
+			case WONT:
+				state = TS_WONT;
+				continue;
+
+			case DO:
+				state = TS_DO;
+				continue;
+
+			case DONT:
+				state = TS_DONT;
+				continue;
+			case EOR:
+				if (his_state_is_will(TELOPT_EOR))
+					doeof();
+				break;
+
+			/*
+			 * Handle RFC 10xx Telnet linemode option additions
+			 * to command stream (EOF, SUSP, ABORT).
+			 */
+			case xEOF:
+				doeof();
+				break;
+
+			case SUSP:
+				sendsusp();
+				break;
+
+			case ABORT:
+				sendbrk();
+				break;
+
+			case IAC:
+				*pfrontp++ = c;
+				break;
+			}
+			state = TS_DATA;
+			break;
+
+		case TS_SB:
+			if (c == IAC) {
+				state = TS_SE;
+			} else {
+				SB_ACCUM(c);
+			}
+			break;
+
+		case TS_SE:
+			if (c != SE) {
+				if (c != IAC) {
+					/*
+					 * bad form of suboption negotiation.
+					 * handle it in such a way as to avoid
+					 * damage to local state.  Parse
+					 * suboption buffer found so far,
+					 * then treat remaining stream as
+					 * another command sequence.
+					 */
+
+					/* for DIAGNOSTICS */
+					SB_ACCUM(IAC);
+					SB_ACCUM(c);
+					subpointer -= 2;
+
+					SB_TERM();
+					suboption();
+					state = TS_IAC;
+					goto gotiac;
+				}
+				SB_ACCUM(c);
+				state = TS_SB;
+			} else {
+				/* for DIAGNOSTICS */
+				SB_ACCUM(IAC);
+				SB_ACCUM(SE);
+				subpointer -= 2;
+
+				SB_TERM();
+				suboption();	/* handle sub-option */
+				state = TS_DATA;
+			}
+			break;
+
+		case TS_WILL:
+			willoption(c);
+			state = TS_DATA;
+			continue;
+
+		case TS_WONT:
+			wontoption(c);
+			state = TS_DATA;
+			continue;
+
+		case TS_DO:
+			dooption(c);
+			state = TS_DATA;
+			continue;
+
+		case TS_DONT:
+			dontoption(c);
+			state = TS_DATA;
+			continue;
+
+		default:
+			syslog(LOG_ERR, "telnetd: panic state=%d\n", state);
+			printf("telnetd: panic state=%d\n", state);
+			exit(1);
+		}
+	}
+#if	defined(CRAY2) && defined(UNICOS5)
+	if (!linemode) {
+		char	xptyobuf[BUFSIZ+NETSLOP];
+		char	xbuf2[BUFSIZ];
+		register char *cp;
+		int n = pfrontp - opfrontp, oc;
+		memmove(xptyobuf, opfrontp, n);
+		pfrontp = opfrontp;
+		pfrontp += term_input(xptyobuf, pfrontp, n, BUFSIZ+NETSLOP,
+					xbuf2, &oc, BUFSIZ);
+		for (cp = xbuf2; oc > 0; --oc)
+			if ((*nfrontp++ = *cp++) == IAC)
+				*nfrontp++ = IAC;
+	}
+#endif	/* defined(CRAY2) && defined(UNICOS5) */
+}  /* end of telrcv */
+
+/*
+ * The will/wont/do/dont state machines are based on Dave Borman's
+ * Telnet option processing state machine.
+ *
+ * These correspond to the following states:
+ *	my_state = the last negotiated state
+ *	want_state = what I want the state to go to
+ *	want_resp = how many requests I have sent
+ * All state defaults are negative, and resp defaults to 0.
+ *
+ * When initiating a request to change state to new_state:
+ *
+ * if ((want_resp == 0 && new_state == my_state) || want_state == new_state) {
+ *	do nothing;
+ * } else {
+ *	want_state = new_state;
+ *	send new_state;
+ *	want_resp++;
+ * }
+ *
+ * When receiving new_state:
+ *
+ * if (want_resp) {
+ *	want_resp--;
+ *	if (want_resp && (new_state == my_state))
+ *		want_resp--;
+ * }
+ * if ((want_resp == 0) && (new_state != want_state)) {
+ *	if (ok_to_switch_to new_state)
+ *		want_state = new_state;
+ *	else
+ *		want_resp++;
+ *	send want_state;
+ * }
+ * my_state = new_state;
+ *
+ * Note that new_state is implied in these functions by the function itself.
+ * will and do imply positive new_state, wont and dont imply negative.
+ *
+ * Finally, there is one catch.  If we send a negative response to a
+ * positive request, my_state will be the positive while want_state will
+ * remain negative.  my_state will revert to negative when the negative
+ * acknowlegment arrives from the peer.  Thus, my_state generally tells
+ * us not only the last negotiated state, but also tells us what the peer
+ * wants to be doing as well.  It is important to understand this difference
+ * as we may wish to be processing data streams based on our desired state
+ * (want_state) or based on what the peer thinks the state is (my_state).
+ *
+ * This all works fine because if the peer sends a positive request, the data
+ * that we receive prior to negative acknowlegment will probably be affected
+ * by the positive state, and we can process it as such (if we can; if we
+ * can't then it really doesn't matter).  If it is that important, then the
+ * peer probably should be buffering until this option state negotiation
+ * is complete.
+ *
+ */
+	void
+send_do(option, init)
+	int option, init;
+{
+	if (init) {
+		if ((do_dont_resp[option] == 0 && his_state_is_will(option)) ||
+		    his_want_state_is_will(option))
+			return;
+		/*
+		 * Special case for TELOPT_TM:  We send a DO, but pretend
+		 * that we sent a DONT, so that we can send more DOs if
+		 * we want to.
+		 */
+		if (option == TELOPT_TM)
+			set_his_want_state_wont(option);
+		else
+			set_his_want_state_will(option);
+		do_dont_resp[option]++;
+	}
+	(void) sprintf(nfrontp, (char *)doopt, option);
+	nfrontp += sizeof (dont) - 2;
+
+	DIAG(TD_OPTIONS, printoption("td: send do", option));
+}
+
+#ifdef	AUTHENTICATION
+extern void auth_request();
+#endif
+#ifdef	LINEMODE
+extern void doclientstat();
+#endif
+#ifdef	ENCRYPTION
+extern void encrypt_send_support();
+#endif	/* ENCRYPTION */
+
+	void
+willoption(option)
+	int option;
+{
+	int changeok = 0;
+	void (*func)() = 0;
+
+	/*
+	 * process input from peer.
+	 */
+
+	DIAG(TD_OPTIONS, printoption("td: recv will", option));
+
+	if (do_dont_resp[option]) {
+		do_dont_resp[option]--;
+		if (do_dont_resp[option] && his_state_is_will(option))
+			do_dont_resp[option]--;
+	}
+	if (do_dont_resp[option] == 0) {
+	    if (his_want_state_is_wont(option)) {
+		switch (option) {
+
+		case TELOPT_BINARY:
+			init_termbuf();
+			tty_binaryin(1);
+			set_termbuf();
+			changeok++;
+			break;
+
+		case TELOPT_ECHO:
+			/*
+			 * See comments below for more info.
+			 */
+			not42 = 0;	/* looks like a 4.2 system */
+			break;
+
+		case TELOPT_TM:
+#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
+			/*
+			 * This telnetd implementation does not really
+			 * support timing marks, it just uses them to
+			 * support the kludge linemode stuff.  If we
+			 * receive a will or wont TM in response to our
+			 * do TM request that may have been sent to
+			 * determine kludge linemode support, process
+			 * it, otherwise TM should get a negative
+			 * response back.
+			 */
+			/*
+			 * Handle the linemode kludge stuff.
+			 * If we are not currently supporting any
+			 * linemode at all, then we assume that this
+			 * is the client telling us to use kludge
+			 * linemode in response to our query.  Set the
+			 * linemode type that is to be supported, note
+			 * that the client wishes to use linemode, and
+			 * eat the will TM as though it never arrived.
+			 */
+			if (lmodetype < KLUDGE_LINEMODE) {
+				lmodetype = KLUDGE_LINEMODE;
+				clientstat(TELOPT_LINEMODE, WILL, 0);
+				send_wont(TELOPT_SGA, 1);
+			} else if (lmodetype == NO_AUTOKLUDGE) {
+				lmodetype = KLUDGE_OK;
+			}
+#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
+			/*
+			 * We never respond to a WILL TM, and
+			 * we leave the state WONT.
+			 */
+			return;
+
+		case TELOPT_LFLOW:
+			/*
+			 * If we are going to support flow control
+			 * option, then don't worry peer that we can't
+			 * change the flow control characters.
+			 */
+			slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS;
+			slctab[SLC_XON].defset.flag |= SLC_DEFAULT;
+			slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS;
+			slctab[SLC_XOFF].defset.flag |= SLC_DEFAULT;
+		case TELOPT_TTYPE:
+		case TELOPT_SGA:
+		case TELOPT_NAWS:
+		case TELOPT_TSPEED:
+		case TELOPT_XDISPLOC:
+		case TELOPT_NEW_ENVIRON:
+		case TELOPT_OLD_ENVIRON:
+			changeok++;
+			break;
+
+#ifdef	LINEMODE
+		case TELOPT_LINEMODE:
+# ifdef	KLUDGELINEMODE
+			/*
+			 * Note client's desire to use linemode.
+			 */
+			lmodetype = REAL_LINEMODE;
+# endif	/* KLUDGELINEMODE */
+			func = doclientstat;
+			changeok++;
+			break;
+#endif	/* LINEMODE */
+
+#ifdef	AUTHENTICATION
+		case TELOPT_AUTHENTICATION:
+			func = auth_request;
+			changeok++;
+			break;
+#endif
+
+#ifdef	ENCRYPTION
+		case TELOPT_ENCRYPT:
+			func = encrypt_send_support;
+			changeok++;
+			break;
+#endif	/* ENCRYPTION */
+
+		default:
+			break;
+		}
+		if (changeok) {
+			set_his_want_state_will(option);
+			send_do(option, 0);
+		} else {
+			do_dont_resp[option]++;
+			send_dont(option, 0);
+		}
+	    } else {
+		/*
+		 * Option processing that should happen when
+		 * we receive conformation of a change in
+		 * state that we had requested.
+		 */
+		switch (option) {
+		case TELOPT_ECHO:
+			not42 = 0;	/* looks like a 4.2 system */
+			/*
+			 * Egads, he responded "WILL ECHO".  Turn
+			 * it off right now!
+			 */
+			send_dont(option, 1);
+			/*
+			 * "WILL ECHO".  Kludge upon kludge!
+			 * A 4.2 client is now echoing user input at
+			 * the tty.  This is probably undesireable and
+			 * it should be stopped.  The client will
+			 * respond WONT TM to the DO TM that we send to
+			 * check for kludge linemode.  When the WONT TM
+			 * arrives, linemode will be turned off and a
+			 * change propogated to the pty.  This change
+			 * will cause us to process the new pty state
+			 * in localstat(), which will notice that
+			 * linemode is off and send a WILL ECHO
+			 * so that we are properly in character mode and
+			 * all is well.
+			 */
+			break;
+#ifdef	LINEMODE
+		case TELOPT_LINEMODE:
+# ifdef	KLUDGELINEMODE
+			/*
+			 * Note client's desire to use linemode.
+			 */
+			lmodetype = REAL_LINEMODE;
+# endif	/* KLUDGELINEMODE */
+			func = doclientstat;
+			break;
+#endif	/* LINEMODE */
+
+#ifdef	AUTHENTICATION
+		case TELOPT_AUTHENTICATION:
+			func = auth_request;
+			break;
+#endif
+
+#ifdef	ENCRYPTION
+		case TELOPT_ENCRYPT:
+			func = encrypt_send_support;
+			break;
+#endif	/* ENCRYPTION */
+		case TELOPT_LFLOW:
+			func = flowstat;
+			break;
+		}
+	    }
+	}
+	set_his_state_will(option);
+	if (func)
+		(*func)();
+}  /* end of willoption */
+
+	void
+send_dont(option, init)
+	int option, init;
+{
+	if (init) {
+		if ((do_dont_resp[option] == 0 && his_state_is_wont(option)) ||
+		    his_want_state_is_wont(option))
+			return;
+		set_his_want_state_wont(option);
+		do_dont_resp[option]++;
+	}
+	(void) sprintf(nfrontp, (char *)dont, option);
+	nfrontp += sizeof (doopt) - 2;
+
+	DIAG(TD_OPTIONS, printoption("td: send dont", option));
+}
+
+	void
+wontoption(option)
+	int option;
+{
+	/*
+	 * Process client input.
+	 */
+
+	DIAG(TD_OPTIONS, printoption("td: recv wont", option));
+
+	if (do_dont_resp[option]) {
+		do_dont_resp[option]--;
+		if (do_dont_resp[option] && his_state_is_wont(option))
+			do_dont_resp[option]--;
+	}
+	if (do_dont_resp[option] == 0) {
+	    if (his_want_state_is_will(option)) {
+		/* it is always ok to change to negative state */
+		switch (option) {
+		case TELOPT_ECHO:
+			not42 = 1; /* doesn't seem to be a 4.2 system */
+			break;
+
+		case TELOPT_BINARY:
+			init_termbuf();
+			tty_binaryin(0);
+			set_termbuf();
+			break;
+
+#ifdef	LINEMODE
+		case TELOPT_LINEMODE:
+# ifdef	KLUDGELINEMODE
+			/*
+			 * If real linemode is supported, then client is
+			 * asking to turn linemode off.
+			 */
+			if (lmodetype != REAL_LINEMODE)
+				break;
+# endif	/* KLUDGELINEMODE */
+			clientstat(TELOPT_LINEMODE, WONT, 0);
+			break;
+#endif	/* LINEMODE */
+
+		case TELOPT_TM:
+			/*
+			 * If we get a WONT TM, and had sent a DO TM,
+			 * don't respond with a DONT TM, just leave it
+			 * as is.  Short circut the state machine to
+			 * achive this.
+			 */
+			set_his_want_state_wont(TELOPT_TM);
+			return;
+
+		case TELOPT_LFLOW:
+			/*
+			 * If we are not going to support flow control
+			 * option, then let peer know that we can't
+			 * change the flow control characters.
+			 */
+			slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS;
+			slctab[SLC_XON].defset.flag |= SLC_CANTCHANGE;
+			slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS;
+			slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE;
+			break;
+
+#if	defined(AUTHENTICATION)
+		case TELOPT_AUTHENTICATION:
+			auth_finished(0, AUTH_REJECT);
+			break;
+#endif
+
+		/*
+		 * For options that we might spin waiting for
+		 * sub-negotiation, if the client turns off the
+		 * option rather than responding to the request,
+		 * we have to treat it here as if we got a response
+		 * to the sub-negotiation, (by updating the timers)
+		 * so that we'll break out of the loop.
+		 */
+		case TELOPT_TTYPE:
+			settimer(ttypesubopt);
+			break;
+
+		case TELOPT_TSPEED:
+			settimer(tspeedsubopt);
+			break;
+
+		case TELOPT_XDISPLOC:
+			settimer(xdisplocsubopt);
+			break;
+
+		case TELOPT_OLD_ENVIRON:
+			settimer(oenvironsubopt);
+			break;
+
+		case TELOPT_NEW_ENVIRON:
+			settimer(environsubopt);
+			break;
+
+		default:
+			break;
+		}
+		set_his_want_state_wont(option);
+		if (his_state_is_will(option))
+			send_dont(option, 0);
+	    } else {
+		switch (option) {
+		case TELOPT_TM:
+#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
+			if (lmodetype < NO_AUTOKLUDGE) {
+				lmodetype = NO_LINEMODE;
+				clientstat(TELOPT_LINEMODE, WONT, 0);
+				send_will(TELOPT_SGA, 1);
+				send_will(TELOPT_ECHO, 1);
+			}
+#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
+			break;
+
+#if	defined(AUTHENTICATION)
+		case TELOPT_AUTHENTICATION:
+			auth_finished(0, AUTH_REJECT);
+			break;
+#endif
+		default:
+			break;
+		}
+	    }
+	}
+	set_his_state_wont(option);
+
+}  /* end of wontoption */
+
+	void
+send_will(option, init)
+	int option, init;
+{
+	if (init) {
+		if ((will_wont_resp[option] == 0 && my_state_is_will(option))||
+		    my_want_state_is_will(option))
+			return;
+		set_my_want_state_will(option);
+		will_wont_resp[option]++;
+	}
+	(void) sprintf(nfrontp, (char *)will, option);
+	nfrontp += sizeof (doopt) - 2;
+
+	DIAG(TD_OPTIONS, printoption("td: send will", option));
+}
+
+#if	!defined(LINEMODE) || !defined(KLUDGELINEMODE)
+/*
+ * When we get a DONT SGA, we will try once to turn it
+ * back on.  If the other side responds DONT SGA, we
+ * leave it at that.  This is so that when we talk to
+ * clients that understand KLUDGELINEMODE but not LINEMODE,
+ * we'll keep them in char-at-a-time mode.
+ */
+int turn_on_sga = 0;
+#endif
+
+	void
+dooption(option)
+	int option;
+{
+	int changeok = 0;
+
+	/*
+	 * Process client input.
+	 */
+
+	DIAG(TD_OPTIONS, printoption("td: recv do", option));
+
+	if (will_wont_resp[option]) {
+		will_wont_resp[option]--;
+		if (will_wont_resp[option] && my_state_is_will(option))
+			will_wont_resp[option]--;
+	}
+	if ((will_wont_resp[option] == 0) && (my_want_state_is_wont(option))) {
+		switch (option) {
+		case TELOPT_ECHO:
+#ifdef	LINEMODE
+# ifdef	KLUDGELINEMODE
+			if (lmodetype == NO_LINEMODE)
+# else
+			if (his_state_is_wont(TELOPT_LINEMODE))
+# endif
+#endif
+			{
+				init_termbuf();
+				tty_setecho(1);
+				set_termbuf();
+			}
+			changeok++;
+			break;
+
+		case TELOPT_BINARY:
+			init_termbuf();
+			tty_binaryout(1);
+			set_termbuf();
+			changeok++;
+			break;
+
+		case TELOPT_SGA:
+#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
+			/*
+			 * If kludge linemode is in use, then we must
+			 * process an incoming do SGA for linemode
+			 * purposes.
+			 */
+			if (lmodetype == KLUDGE_LINEMODE) {
+				/*
+				 * Receipt of "do SGA" in kludge
+				 * linemode is the peer asking us to
+				 * turn off linemode.  Make note of
+				 * the request.
+				 */
+				clientstat(TELOPT_LINEMODE, WONT, 0);
+				/*
+				 * If linemode did not get turned off
+				 * then don't tell peer that we did.
+				 * Breaking here forces a wont SGA to
+				 * be returned.
+				 */
+				if (linemode)
+					break;
+			}
+#else
+			turn_on_sga = 0;
+#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
+			changeok++;
+			break;
+
+		case TELOPT_STATUS:
+			changeok++;
+			break;
+
+		case TELOPT_TM:
+			/*
+			 * Special case for TM.  We send a WILL, but
+			 * pretend we sent a WONT.
+			 */
+			send_will(option, 0);
+			set_my_want_state_wont(option);
+			set_my_state_wont(option);
+			return;
+
+		case TELOPT_LOGOUT:
+			/*
+			 * When we get a LOGOUT option, respond
+			 * with a WILL LOGOUT, make sure that
+			 * it gets written out to the network,
+			 * and then just go away...
+			 */
+			set_my_want_state_will(TELOPT_LOGOUT);
+			send_will(TELOPT_LOGOUT, 0);
+			set_my_state_will(TELOPT_LOGOUT);
+			(void)netflush();
+			cleanup(0);
+			/* NOT REACHED */
+			break;
+
+#ifdef	ENCRYPTION
+		case TELOPT_ENCRYPT:
+			changeok++;
+			break;
+#endif	/* ENCRYPTION */
+		case TELOPT_LINEMODE:
+		case TELOPT_TTYPE:
+		case TELOPT_NAWS:
+		case TELOPT_TSPEED:
+		case TELOPT_LFLOW:
+		case TELOPT_XDISPLOC:
+#ifdef	TELOPT_ENVIRON
+		case TELOPT_NEW_ENVIRON:
+#endif
+		case TELOPT_OLD_ENVIRON:
+		default:
+			break;
+		}
+		if (changeok) {
+			set_my_want_state_will(option);
+			send_will(option, 0);
+		} else {
+			will_wont_resp[option]++;
+			send_wont(option, 0);
+		}
+	}
+	set_my_state_will(option);
+
+}  /* end of dooption */
+
+	void
+send_wont(option, init)
+	int option, init;
+{
+	if (init) {
+		if ((will_wont_resp[option] == 0 && my_state_is_wont(option)) ||
+		    my_want_state_is_wont(option))
+			return;
+		set_my_want_state_wont(option);
+		will_wont_resp[option]++;
+	}
+	(void) sprintf(nfrontp, (char *)wont, option);
+	nfrontp += sizeof (wont) - 2;
+
+	DIAG(TD_OPTIONS, printoption("td: send wont", option));
+}
+
+	void
+dontoption(option)
+	int option;
+{
+	/*
+	 * Process client input.
+	 */
+
+
+	DIAG(TD_OPTIONS, printoption("td: recv dont", option));
+
+	if (will_wont_resp[option]) {
+		will_wont_resp[option]--;
+		if (will_wont_resp[option] && my_state_is_wont(option))
+			will_wont_resp[option]--;
+	}
+	if ((will_wont_resp[option] == 0) && (my_want_state_is_will(option))) {
+		switch (option) {
+		case TELOPT_BINARY:
+			init_termbuf();
+			tty_binaryout(0);
+			set_termbuf();
+			break;
+
+		case TELOPT_ECHO:	/* we should stop echoing */
+#ifdef	LINEMODE
+# ifdef	KLUDGELINEMODE
+			if ((lmodetype != REAL_LINEMODE) &&
+			    (lmodetype != KLUDGE_LINEMODE))
+# else
+			if (his_state_is_wont(TELOPT_LINEMODE))
+# endif
+#endif
+			{
+				init_termbuf();
+				tty_setecho(0);
+				set_termbuf();
+			}
+			break;
+
+		case TELOPT_SGA:
+#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
+			/*
+			 * If kludge linemode is in use, then we
+			 * must process an incoming do SGA for
+			 * linemode purposes.
+			 */
+			if ((lmodetype == KLUDGE_LINEMODE) ||
+			    (lmodetype == KLUDGE_OK)) {
+				/*
+				 * The client is asking us to turn
+				 * linemode on.
+				 */
+				lmodetype = KLUDGE_LINEMODE;
+				clientstat(TELOPT_LINEMODE, WILL, 0);
+				/*
+				 * If we did not turn line mode on,
+				 * then what do we say?  Will SGA?
+				 * This violates design of telnet.
+				 * Gross.  Very Gross.
+				 */
+			}
+			break;
+#else
+			set_my_want_state_wont(option);
+			if (my_state_is_will(option))
+				send_wont(option, 0);
+			set_my_state_wont(option);
+			if (turn_on_sga ^= 1)
+				send_will(option, 1);
+			return;
+#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
+
+		default:
+			break;
+		}
+
+		set_my_want_state_wont(option);
+		if (my_state_is_will(option))
+			send_wont(option, 0);
+	}
+	set_my_state_wont(option);
+
+}  /* end of dontoption */
+
+#ifdef	ENV_HACK
+int env_ovar = -1;
+int env_ovalue = -1;
+#else	/* ENV_HACK */
+# define env_ovar OLD_ENV_VAR
+# define env_ovalue OLD_ENV_VALUE
+#endif	/* ENV_HACK */
+
+/*
+ * suboption()
+ *
+ *	Look at the sub-option buffer, and try to be helpful to the other
+ * side.
+ *
+ *	Currently we recognize:
+ *
+ *	Terminal type is
+ *	Linemode
+ *	Window size
+ *	Terminal speed
+ */
+	void
+suboption()
+{
+    register int subchar;
+
+    DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);});
+
+    subchar = SB_GET();
+    switch (subchar) {
+    case TELOPT_TSPEED: {
+	register int xspeed, rspeed;
+
+	if (his_state_is_wont(TELOPT_TSPEED))	/* Ignore if option disabled */
+		break;
+
+	settimer(tspeedsubopt);
+
+	if (SB_EOF() || SB_GET() != TELQUAL_IS)
+		return;
+
+	xspeed = atoi((char *)subpointer);
+
+	while (SB_GET() != ',' && !SB_EOF());
+	if (SB_EOF())
+		return;
+
+	rspeed = atoi((char *)subpointer);
+	clientstat(TELOPT_TSPEED, xspeed, rspeed);
+
+	break;
+
+    }  /* end of case TELOPT_TSPEED */
+
+    case TELOPT_TTYPE: {		/* Yaaaay! */
+	static char terminalname[41];
+
+	if (his_state_is_wont(TELOPT_TTYPE))	/* Ignore if option disabled */
+		break;
+	settimer(ttypesubopt);
+
+	if (SB_EOF() || SB_GET() != TELQUAL_IS) {
+	    return;		/* ??? XXX but, this is the most robust */
+	}
+
+	terminaltype = terminalname;
+
+	while ((terminaltype < (terminalname + sizeof terminalname-1)) &&
+								    !SB_EOF()) {
+	    register int c;
+
+	    c = SB_GET();
+	    if (isupper(c)) {
+		c = tolower(c);
+	    }
+	    *terminaltype++ = c;    /* accumulate name */
+	}
+	*terminaltype = 0;
+	terminaltype = terminalname;
+	break;
+    }  /* end of case TELOPT_TTYPE */
+
+    case TELOPT_NAWS: {
+	register int xwinsize, ywinsize;
+
+	if (his_state_is_wont(TELOPT_NAWS))	/* Ignore if option disabled */
+		break;
+
+	if (SB_EOF())
+		return;
+	xwinsize = SB_GET() << 8;
+	if (SB_EOF())
+		return;
+	xwinsize |= SB_GET();
+	if (SB_EOF())
+		return;
+	ywinsize = SB_GET() << 8;
+	if (SB_EOF())
+		return;
+	ywinsize |= SB_GET();
+	clientstat(TELOPT_NAWS, xwinsize, ywinsize);
+
+	break;
+
+    }  /* end of case TELOPT_NAWS */
+
+#ifdef	LINEMODE
+    case TELOPT_LINEMODE: {
+	register int request;
+
+	if (his_state_is_wont(TELOPT_LINEMODE))	/* Ignore if option disabled */
+		break;
+	/*
+	 * Process linemode suboptions.
+	 */
+	if (SB_EOF())
+	    break;		/* garbage was sent */
+	request = SB_GET();	/* get will/wont */
+
+	if (SB_EOF())
+	    break;		/* another garbage check */
+
+	if (request == LM_SLC) {  /* SLC is not preceeded by WILL or WONT */
+		/*
+		 * Process suboption buffer of slc's
+		 */
+		start_slc(1);
+		do_opt_slc(subpointer, subend - subpointer);
+		(void) end_slc(0);
+		break;
+	} else if (request == LM_MODE) {
+		if (SB_EOF())
+		    return;
+		useeditmode = SB_GET();  /* get mode flag */
+		clientstat(LM_MODE, 0, 0);
+		break;
+	}
+
+	if (SB_EOF())
+	    break;
+	switch (SB_GET()) {  /* what suboption? */
+	case LM_FORWARDMASK:
+		/*
+		 * According to spec, only server can send request for
+		 * forwardmask, and client can only return a positive response.
+		 * So don't worry about it.
+		 */
+
+	default:
+		break;
+	}
+	break;
+    }  /* end of case TELOPT_LINEMODE */
+#endif
+    case TELOPT_STATUS: {
+	int mode;
+
+	if (SB_EOF())
+	    break;
+	mode = SB_GET();
+	switch (mode) {
+	case TELQUAL_SEND:
+	    if (my_state_is_will(TELOPT_STATUS))
+		send_status();
+	    break;
+
+	case TELQUAL_IS:
+	    break;
+
+	default:
+	    break;
+	}
+	break;
+    }  /* end of case TELOPT_STATUS */
+
+    case TELOPT_XDISPLOC: {
+	if (SB_EOF() || SB_GET() != TELQUAL_IS)
+		return;
+	settimer(xdisplocsubopt);
+	subpointer[SB_LEN()] = '\0';
+	(void)setenv("DISPLAY", (char *)subpointer, 1);
+	break;
+    }  /* end of case TELOPT_XDISPLOC */
+
+#ifdef	TELOPT_NEW_ENVIRON
+    case TELOPT_NEW_ENVIRON:
+#endif
+    case TELOPT_OLD_ENVIRON: {
+	register int c;
+	register char *cp, *varp, *valp;
+
+	if (SB_EOF())
+		return;
+	c = SB_GET();
+	if (c == TELQUAL_IS) {
+		if (subchar == TELOPT_OLD_ENVIRON)
+			settimer(oenvironsubopt);
+		else
+			settimer(environsubopt);
+	} else if (c != TELQUAL_INFO) {
+		return;
+	}
+
+#ifdef	TELOPT_NEW_ENVIRON
+	if (subchar == TELOPT_NEW_ENVIRON) {
+	    while (!SB_EOF()) {
+		c = SB_GET();
+		if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR))
+			break;
+	    }
+	} else
+#endif
+	{
+#ifdef	ENV_HACK
+	    /*
+	     * We only want to do this if we haven't already decided
+	     * whether or not the other side has its VALUE and VAR
+	     * reversed.
+	     */
+	    if (env_ovar < 0) {
+		register int last = -1;		/* invalid value */
+		int empty = 0;
+		int got_var = 0, got_value = 0, got_uservar = 0;
+
+		/*
+		 * The other side might have its VALUE and VAR values
+		 * reversed.  To be interoperable, we need to determine
+		 * which way it is.  If the first recognized character
+		 * is a VAR or VALUE, then that will tell us what
+		 * type of client it is.  If the fist recognized
+		 * character is a USERVAR, then we continue scanning
+		 * the suboption looking for two consecutive
+		 * VAR or VALUE fields.  We should not get two
+		 * consecutive VALUE fields, so finding two
+		 * consecutive VALUE or VAR fields will tell us
+		 * what the client is.
+		 */
+		SB_SAVE();
+		while (!SB_EOF()) {
+			c = SB_GET();
+			switch(c) {
+			case OLD_ENV_VAR:
+				if (last < 0 || last == OLD_ENV_VAR
+				    || (empty && (last == OLD_ENV_VALUE)))
+					goto env_ovar_ok;
+				got_var++;
+				last = OLD_ENV_VAR;
+				break;
+			case OLD_ENV_VALUE:
+				if (last < 0 || last == OLD_ENV_VALUE
+				    || (empty && (last == OLD_ENV_VAR)))
+					goto env_ovar_wrong;
+				got_value++;
+				last = OLD_ENV_VALUE;
+				break;
+			case ENV_USERVAR:
+				/* count strings of USERVAR as one */
+				if (last != ENV_USERVAR)
+					got_uservar++;
+				if (empty) {
+					if (last == OLD_ENV_VALUE)
+						goto env_ovar_ok;
+					if (last == OLD_ENV_VAR)
+						goto env_ovar_wrong;
+				}
+				last = ENV_USERVAR;
+				break;
+			case ENV_ESC:
+				if (!SB_EOF())
+					c = SB_GET();
+				/* FALL THROUGH */
+			default:
+				empty = 0;
+				continue;
+			}
+			empty = 1;
+		}
+		if (empty) {
+			if (last == OLD_ENV_VALUE)
+				goto env_ovar_ok;
+			if (last == OLD_ENV_VAR)
+				goto env_ovar_wrong;
+		}
+		/*
+		 * Ok, the first thing was a USERVAR, and there
+		 * are not two consecutive VAR or VALUE commands,
+		 * and none of the VAR or VALUE commands are empty.
+		 * If the client has sent us a well-formed option,
+		 * then the number of VALUEs received should always
+		 * be less than or equal to the number of VARs and
+		 * USERVARs received.
+		 *
+		 * If we got exactly as many VALUEs as VARs and
+		 * USERVARs, the client has the same definitions.
+		 *
+		 * If we got exactly as many VARs as VALUEs and
+		 * USERVARS, the client has reversed definitions.
+		 */
+		if (got_uservar + got_var == got_value) {
+	    env_ovar_ok:
+			env_ovar = OLD_ENV_VAR;
+			env_ovalue = OLD_ENV_VALUE;
+		} else if (got_uservar + got_value == got_var) {
+	    env_ovar_wrong:
+			env_ovar = OLD_ENV_VALUE;
+			env_ovalue = OLD_ENV_VAR;
+			DIAG(TD_OPTIONS, {sprintf(nfrontp,
+				"ENVIRON VALUE and VAR are reversed!\r\n");
+				nfrontp += strlen(nfrontp);});
+
+		}
+	    }
+	    SB_RESTORE();
+#endif
+
+	    while (!SB_EOF()) {
+		c = SB_GET();
+		if ((c == env_ovar) || (c == ENV_USERVAR))
+			break;
+	    }
+	}
+
+	if (SB_EOF())
+		return;
+
+	cp = varp = (char *)subpointer;
+	valp = 0;
+
+	while (!SB_EOF()) {
+		c = SB_GET();
+		if (subchar == TELOPT_OLD_ENVIRON) {
+			if (c == env_ovar)
+				c = NEW_ENV_VAR;
+			else if (c == env_ovalue)
+				c = NEW_ENV_VALUE;
+		}
+		switch (c) {
+
+		case NEW_ENV_VALUE:
+			*cp = '\0';
+			cp = valp = (char *)subpointer;
+			break;
+
+		case NEW_ENV_VAR:
+		case ENV_USERVAR:
+			*cp = '\0';
+			if (valp)
+				(void)setenv(varp, valp, 1);
+			else
+				unsetenv(varp);
+			cp = varp = (char *)subpointer;
+			valp = 0;
+			break;
+
+		case ENV_ESC:
+			if (SB_EOF())
+				break;
+			c = SB_GET();
+			/* FALL THROUGH */
+		default:
+			*cp++ = c;
+			break;
+		}
+	}
+	*cp = '\0';
+	if (valp)
+		(void)setenv(varp, valp, 1);
+	else
+		unsetenv(varp);
+	break;
+    }  /* end of case TELOPT_NEW_ENVIRON */
+#if	defined(AUTHENTICATION)
+    case TELOPT_AUTHENTICATION:
+	if (SB_EOF())
+		break;
+	switch(SB_GET()) {
+	case TELQUAL_SEND:
+	case TELQUAL_REPLY:
+		/*
+		 * These are sent by us and cannot be sent by
+		 * the client.
+		 */
+		break;
+	case TELQUAL_IS:
+		auth_is(subpointer, SB_LEN());
+		break;
+	case TELQUAL_NAME:
+		auth_name(subpointer, SB_LEN());
+		break;
+	}
+	break;
+#endif
+#ifdef	ENCRYPTION
+    case TELOPT_ENCRYPT:
+	if (SB_EOF())
+		break;
+	switch(SB_GET()) {
+	case ENCRYPT_SUPPORT:
+		encrypt_support(subpointer, SB_LEN());
+		break;
+	case ENCRYPT_IS:
+		encrypt_is(subpointer, SB_LEN());
+		break;
+	case ENCRYPT_REPLY:
+		encrypt_reply(subpointer, SB_LEN());
+		break;
+	case ENCRYPT_START:
+		encrypt_start(subpointer, SB_LEN());
+		break;
+	case ENCRYPT_END:
+		encrypt_end();
+		break;
+	case ENCRYPT_REQSTART:
+		encrypt_request_start(subpointer, SB_LEN());
+		break;
+	case ENCRYPT_REQEND:
+		/*
+		 * We can always send an REQEND so that we cannot
+		 * get stuck encrypting.  We should only get this
+		 * if we have been able to get in the correct mode
+		 * anyhow.
+		 */
+		encrypt_request_end();
+		break;
+	case ENCRYPT_ENC_KEYID:
+		encrypt_enc_keyid(subpointer, SB_LEN());
+		break;
+	case ENCRYPT_DEC_KEYID:
+		encrypt_dec_keyid(subpointer, SB_LEN());
+		break;
+	default:
+		break;
+	}
+	break;
+#endif	/* ENCRYPTION */
+
+    default:
+	break;
+    }  /* end of switch */
+
+}  /* end of suboption */
+
+	void
+doclientstat()
+{
+	clientstat(TELOPT_LINEMODE, WILL, 0);
+}
+
+#define	ADD(c)	 *ncp++ = c
+#define	ADD_DATA(c) { *ncp++ = c; if (c == SE || c == IAC) *ncp++ = c; }
+	void
+send_status()
+{
+	unsigned char statusbuf[256];
+	register unsigned char *ncp;
+	register unsigned char i;
+
+	ncp = statusbuf;
+
+	netflush();	/* get rid of anything waiting to go out */
+
+	ADD(IAC);
+	ADD(SB);
+	ADD(TELOPT_STATUS);
+	ADD(TELQUAL_IS);
+
+	/*
+	 * We check the want_state rather than the current state,
+	 * because if we received a DO/WILL for an option that we
+	 * don't support, and the other side didn't send a DONT/WONT
+	 * in response to our WONT/DONT, then the "state" will be
+	 * WILL/DO, and the "want_state" will be WONT/DONT.  We
+	 * need to go by the latter.
+	 */
+	for (i = 0; i < (unsigned char)NTELOPTS; i++) {
+		if (my_want_state_is_will(i)) {
+			ADD(WILL);
+			ADD_DATA(i);
+		}
+		if (his_want_state_is_will(i)) {
+			ADD(DO);
+			ADD_DATA(i);
+		}
+	}
+
+	if (his_want_state_is_will(TELOPT_LFLOW)) {
+		ADD(SB);
+		ADD(TELOPT_LFLOW);
+		if (flowmode) {
+			ADD(LFLOW_ON);
+		} else {
+			ADD(LFLOW_OFF);
+		}
+		ADD(SE);
+
+		if (restartany >= 0) {
+			ADD(SB);
+			ADD(TELOPT_LFLOW);
+			if (restartany) {
+				ADD(LFLOW_RESTART_ANY);
+			} else {
+				ADD(LFLOW_RESTART_XON);
+			}
+			ADD(SE);
+		}
+	}
+
+#ifdef	LINEMODE
+	if (his_want_state_is_will(TELOPT_LINEMODE)) {
+		unsigned char *cp, *cpe;
+		int len;
+
+		ADD(SB);
+		ADD(TELOPT_LINEMODE);
+		ADD(LM_MODE);
+		ADD_DATA(editmode);
+		ADD(SE);
+
+		ADD(SB);
+		ADD(TELOPT_LINEMODE);
+		ADD(LM_SLC);
+		start_slc(0);
+		send_slc();
+		len = end_slc(&cp);
+		for (cpe = cp + len; cp < cpe; cp++)
+			ADD_DATA(*cp);
+		ADD(SE);
+	}
+#endif	/* LINEMODE */
+
+	ADD(IAC);
+	ADD(SE);
+
+	writenet(statusbuf, ncp - statusbuf);
+	netflush();	/* Send it on its way */
+
+	DIAG(TD_OPTIONS,
+		{printsub('>', statusbuf, ncp - statusbuf); netflush();});
+}
diff --git a/telnetd.tproj/sys_term.c b/telnetd.tproj/sys_term.c
new file mode 100644
index 0000000..61d116e
--- /dev/null
+++ b/telnetd.tproj/sys_term.c
@@ -0,0 +1,2306 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)sys_term.c	8.4 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#include "telnetd.h"
+#include "pathnames.h"
+
+#if	defined(AUTHENTICATION)
+#include <libtelnet/auth.h>
+#endif
+
+#if defined(CRAY) || defined(__hpux)
+# define PARENT_DOES_UTMP
+#endif
+
+#ifdef	NEWINIT
+#include <initreq.h>
+int	utmp_len = MAXHOSTNAMELEN;	/* sizeof(init_request.host) */
+#else	/* NEWINIT*/
+# ifdef	UTMPX
+# include <utmpx.h>
+struct	utmpx wtmp;
+# else
+# include <utmp.h>
+struct	utmp wtmp;
+# endif /* UTMPX */
+
+int	utmp_len = sizeof(wtmp.ut_host);
+# ifndef PARENT_DOES_UTMP
+char	wtmpf[]	= "/usr/adm/wtmp";
+char	utmpf[] = "/var/run/utmp";
+# else /* PARENT_DOES_UTMP */
+char	wtmpf[]	= "/etc/wtmp";
+# endif /* PARENT_DOES_UTMP */
+
+# ifdef CRAY
+#include <tmpdir.h>
+#include <sys/wait.h>
+#  if (UNICOS_LVL == '7.0') || (UNICOS_LVL == '7.1')
+#   define UNICOS7x
+#  endif
+
+#  ifdef UNICOS7x
+#include <sys/sysv.h>
+#include <sys/secstat.h>
+extern int secflag;
+extern struct sysv sysv;
+#  endif /* UNICOS7x */
+# endif	/* CRAY */
+#endif	/* NEWINIT */
+
+#ifdef	STREAMSPTY
+#include <sac.h>
+#include <sys/stropts.h>
+#endif
+
+#define SCPYN(a, b)	(void) strncpy(a, b, sizeof(a))
+#define SCMPN(a, b)	strncmp(a, b, sizeof(a))
+
+#ifdef	STREAMS
+#include <sys/stream.h>
+#endif
+#ifdef __hpux
+#include <sys/resource.h>
+#include <sys/proc.h>
+#endif
+#include <sys/tty.h>
+#ifdef	t_erase
+#undef	t_erase
+#undef	t_kill
+#undef	t_intrc
+#undef	t_quitc
+#undef	t_startc
+#undef	t_stopc
+#undef	t_eofc
+#undef	t_brkc
+#undef	t_suspc
+#undef	t_dsuspc
+#undef	t_rprntc
+#undef	t_flushc
+#undef	t_werasc
+#undef	t_lnextc
+#endif
+
+#if defined(UNICOS5) && defined(CRAY2) && !defined(EXTPROC)
+# define EXTPROC 0400
+#endif
+
+#ifndef	USE_TERMIO
+struct termbuf {
+	struct sgttyb sg;
+	struct tchars tc;
+	struct ltchars ltc;
+	int state;
+	int lflags;
+} termbuf, termbuf2;
+# define	cfsetospeed(tp, val)	(tp)->sg.sg_ospeed = (val)
+# define	cfsetispeed(tp, val)	(tp)->sg.sg_ispeed = (val)
+# define	cfgetospeed(tp)		(tp)->sg.sg_ospeed
+# define	cfgetispeed(tp)		(tp)->sg.sg_ispeed
+#else	/* USE_TERMIO */
+# ifdef	SYSV_TERMIO
+#	define termios termio
+# endif
+# ifndef	TCSANOW
+#  ifdef TCSETS
+#   define	TCSANOW		TCSETS
+#   define	TCSADRAIN	TCSETSW
+#   define	tcgetattr(f, t)	ioctl(f, TCGETS, (char *)t)
+#  else
+#   ifdef TCSETA
+#    define	TCSANOW		TCSETA
+#    define	TCSADRAIN	TCSETAW
+#    define	tcgetattr(f, t)	ioctl(f, TCGETA, (char *)t)
+#   else
+#    define	TCSANOW		TIOCSETA
+#    define	TCSADRAIN	TIOCSETAW
+#    define	tcgetattr(f, t)	ioctl(f, TIOCGETA, (char *)t)
+#   endif
+#  endif
+#  define	tcsetattr(f, a, t)	ioctl(f, a, t)
+#  define	cfsetospeed(tp, val)	(tp)->c_cflag &= ~CBAUD; \
+					(tp)->c_cflag |= (val)
+#  define	cfgetospeed(tp)		((tp)->c_cflag & CBAUD)
+#  ifdef CIBAUD
+#   define	cfsetispeed(tp, val)	(tp)->c_cflag &= ~CIBAUD; \
+					(tp)->c_cflag |= ((val)<<IBSHIFT)
+#   define	cfgetispeed(tp)		(((tp)->c_cflag & CIBAUD)>>IBSHIFT)
+#  else
+#   define	cfsetispeed(tp, val)	(tp)->c_cflag &= ~CBAUD; \
+					(tp)->c_cflag |= (val)
+#   define	cfgetispeed(tp)		((tp)->c_cflag & CBAUD)
+#  endif
+# endif /* TCSANOW */
+struct termios termbuf, termbuf2;	/* pty control structure */
+# ifdef  STREAMSPTY
+int ttyfd = -1;
+# endif
+#endif	/* USE_TERMIO */
+
+/*
+ * init_termbuf()
+ * copy_termbuf(cp)
+ * set_termbuf()
+ *
+ * These three routines are used to get and set the "termbuf" structure
+ * to and from the kernel.  init_termbuf() gets the current settings.
+ * copy_termbuf() hands in a new "termbuf" to write to the kernel, and
+ * set_termbuf() writes the structure into the kernel.
+ */
+
+	void
+init_termbuf()
+{
+#ifndef	USE_TERMIO
+	(void) ioctl(pty, TIOCGETP, (char *)&termbuf.sg);
+	(void) ioctl(pty, TIOCGETC, (char *)&termbuf.tc);
+	(void) ioctl(pty, TIOCGLTC, (char *)&termbuf.ltc);
+# ifdef	TIOCGSTATE
+	(void) ioctl(pty, TIOCGSTATE, (char *)&termbuf.state);
+# endif
+#else
+# ifdef  STREAMSPTY
+	(void) tcgetattr(ttyfd, &termbuf);
+# else
+	(void) tcgetattr(pty, &termbuf);
+# endif
+#endif
+	termbuf2 = termbuf;
+}
+
+#if	defined(LINEMODE) && defined(TIOCPKT_IOCTL)
+	void
+copy_termbuf(cp, len)
+	char *cp;
+	int len;
+{
+	if (len > sizeof(termbuf))
+		len = sizeof(termbuf);
+	memmove((char *)&termbuf, cp, len);
+	termbuf2 = termbuf;
+}
+#endif	/* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
+
+	void
+set_termbuf()
+{
+	/*
+	 * Only make the necessary changes.
+	 */
+#ifndef	USE_TERMIO
+	if (memcmp((char *)&termbuf.sg, (char *)&termbuf2.sg,
+							sizeof(termbuf.sg)))
+		(void) ioctl(pty, TIOCSETN, (char *)&termbuf.sg);
+	if (memcmp((char *)&termbuf.tc, (char *)&termbuf2.tc,
+							sizeof(termbuf.tc)))
+		(void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc);
+	if (memcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc,
+							sizeof(termbuf.ltc)))
+		(void) ioctl(pty, TIOCSLTC, (char *)&termbuf.ltc);
+	if (termbuf.lflags != termbuf2.lflags)
+		(void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags);
+#else	/* USE_TERMIO */
+	if (memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))
+# ifdef  STREAMSPTY
+		(void) tcsetattr(ttyfd, TCSANOW, &termbuf);
+# else
+		(void) tcsetattr(pty, TCSANOW, &termbuf);
+# endif
+# if	defined(CRAY2) && defined(UNICOS5)
+	needtermstat = 1;
+# endif
+#endif	/* USE_TERMIO */
+}
+
+
+/*
+ * spcset(func, valp, valpp)
+ *
+ * This function takes various special characters (func), and
+ * sets *valp to the current value of that character, and
+ * *valpp to point to where in the "termbuf" structure that
+ * value is kept.
+ *
+ * It returns the SLC_ level of support for this function.
+ */
+
+#ifndef	USE_TERMIO
+	int
+spcset(func, valp, valpp)
+	int func;
+	cc_t *valp;
+	cc_t **valpp;
+{
+	switch(func) {
+	case SLC_EOF:
+		*valp = termbuf.tc.t_eofc;
+		*valpp = (cc_t *)&termbuf.tc.t_eofc;
+		return(SLC_VARIABLE);
+	case SLC_EC:
+		*valp = termbuf.sg.sg_erase;
+		*valpp = (cc_t *)&termbuf.sg.sg_erase;
+		return(SLC_VARIABLE);
+	case SLC_EL:
+		*valp = termbuf.sg.sg_kill;
+		*valpp = (cc_t *)&termbuf.sg.sg_kill;
+		return(SLC_VARIABLE);
+	case SLC_IP:
+		*valp = termbuf.tc.t_intrc;
+		*valpp = (cc_t *)&termbuf.tc.t_intrc;
+		return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
+	case SLC_ABORT:
+		*valp = termbuf.tc.t_quitc;
+		*valpp = (cc_t *)&termbuf.tc.t_quitc;
+		return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
+	case SLC_XON:
+		*valp = termbuf.tc.t_startc;
+		*valpp = (cc_t *)&termbuf.tc.t_startc;
+		return(SLC_VARIABLE);
+	case SLC_XOFF:
+		*valp = termbuf.tc.t_stopc;
+		*valpp = (cc_t *)&termbuf.tc.t_stopc;
+		return(SLC_VARIABLE);
+	case SLC_AO:
+		*valp = termbuf.ltc.t_flushc;
+		*valpp = (cc_t *)&termbuf.ltc.t_flushc;
+		return(SLC_VARIABLE);
+	case SLC_SUSP:
+		*valp = termbuf.ltc.t_suspc;
+		*valpp = (cc_t *)&termbuf.ltc.t_suspc;
+		return(SLC_VARIABLE);
+	case SLC_EW:
+		*valp = termbuf.ltc.t_werasc;
+		*valpp = (cc_t *)&termbuf.ltc.t_werasc;
+		return(SLC_VARIABLE);
+	case SLC_RP:
+		*valp = termbuf.ltc.t_rprntc;
+		*valpp = (cc_t *)&termbuf.ltc.t_rprntc;
+		return(SLC_VARIABLE);
+	case SLC_LNEXT:
+		*valp = termbuf.ltc.t_lnextc;
+		*valpp = (cc_t *)&termbuf.ltc.t_lnextc;
+		return(SLC_VARIABLE);
+	case SLC_FORW1:
+		*valp = termbuf.tc.t_brkc;
+		*valpp = (cc_t *)&termbuf.ltc.t_lnextc;
+		return(SLC_VARIABLE);
+	case SLC_BRK:
+	case SLC_SYNCH:
+	case SLC_AYT:
+	case SLC_EOR:
+		*valp = (cc_t)0;
+		*valpp = (cc_t *)0;
+		return(SLC_DEFAULT);
+	default:
+		*valp = (cc_t)0;
+		*valpp = (cc_t *)0;
+		return(SLC_NOSUPPORT);
+	}
+}
+
+#else	/* USE_TERMIO */
+
+	int
+spcset(func, valp, valpp)
+	int func;
+	cc_t *valp;
+	cc_t **valpp;
+{
+
+#define	setval(a, b)	*valp = termbuf.c_cc[a]; \
+			*valpp = &termbuf.c_cc[a]; \
+			return(b);
+#define	defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT);
+
+	switch(func) {
+	case SLC_EOF:
+		setval(VEOF, SLC_VARIABLE);
+	case SLC_EC:
+		setval(VERASE, SLC_VARIABLE);
+	case SLC_EL:
+		setval(VKILL, SLC_VARIABLE);
+	case SLC_IP:
+		setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
+	case SLC_ABORT:
+		setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
+	case SLC_XON:
+#ifdef	VSTART
+		setval(VSTART, SLC_VARIABLE);
+#else
+		defval(0x13);
+#endif
+	case SLC_XOFF:
+#ifdef	VSTOP
+		setval(VSTOP, SLC_VARIABLE);
+#else
+		defval(0x11);
+#endif
+	case SLC_EW:
+#ifdef	VWERASE
+		setval(VWERASE, SLC_VARIABLE);
+#else
+		defval(0);
+#endif
+	case SLC_RP:
+#ifdef	VREPRINT
+		setval(VREPRINT, SLC_VARIABLE);
+#else
+		defval(0);
+#endif
+	case SLC_LNEXT:
+#ifdef	VLNEXT
+		setval(VLNEXT, SLC_VARIABLE);
+#else
+		defval(0);
+#endif
+	case SLC_AO:
+#if	!defined(VDISCARD) && defined(VFLUSHO)
+# define VDISCARD VFLUSHO
+#endif
+#ifdef	VDISCARD
+		setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
+#else
+		defval(0);
+#endif
+	case SLC_SUSP:
+#ifdef	VSUSP
+		setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
+#else
+		defval(0);
+#endif
+#ifdef	VEOL
+	case SLC_FORW1:
+		setval(VEOL, SLC_VARIABLE);
+#endif
+#ifdef	VEOL2
+	case SLC_FORW2:
+		setval(VEOL2, SLC_VARIABLE);
+#endif
+	case SLC_AYT:
+#ifdef	VSTATUS
+		setval(VSTATUS, SLC_VARIABLE);
+#else
+		defval(0);
+#endif
+
+	case SLC_BRK:
+	case SLC_SYNCH:
+	case SLC_EOR:
+		defval(0);
+
+	default:
+		*valp = 0;
+		*valpp = 0;
+		return(SLC_NOSUPPORT);
+	}
+}
+#endif	/* USE_TERMIO */
+
+#ifdef CRAY
+/*
+ * getnpty()
+ *
+ * Return the number of pty's configured into the system.
+ */
+	int
+getnpty()
+{
+#ifdef _SC_CRAY_NPTY
+	int numptys;
+
+	if ((numptys = sysconf(_SC_CRAY_NPTY)) != -1)
+		return numptys;
+	else
+#endif /* _SC_CRAY_NPTY */
+		return 128;
+}
+#endif /* CRAY */
+
+#ifndef	convex
+/*
+ * getpty()
+ *
+ * Allocate a pty.  As a side effect, the external character
+ * array "line" contains the name of the slave side.
+ *
+ * Returns the file descriptor of the opened pty.
+ */
+#ifndef __APPLE__
+#ifndef	__GNUC__
+char *line = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+#else
+static char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+char *line = Xline;
+#endif
+#ifdef	CRAY
+char *myline = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+#endif	/* CRAY */
+#endif /* !NeXT */
+
+	int
+getpty(ptynum)
+int *ptynum;
+{
+	register int p;
+#ifdef	STREAMSPTY
+	int t;
+	char *ptsname();
+
+	p = open("/dev/ptmx", 2);
+	if (p > 0) {
+		grantpt(p);
+		unlockpt(p);
+		strcpy(line, ptsname(p));
+		return(p);
+	}
+
+#else	/* ! STREAMSPTY */
+#ifndef CRAY
+	register char *cp, *p1, *p2;
+	register int i;
+#if defined(sun) && defined(TIOCGPGRP) && BSD < 199207
+	int dummy;
+#endif
+
+#ifndef	__hpux
+	(void) sprintf(line, "/dev/ptyXX");
+	p1 = &line[8];
+	p2 = &line[9];
+#else
+	(void) sprintf(line, "/dev/ptym/ptyXX");
+	p1 = &line[13];
+	p2 = &line[14];
+#endif
+
+	for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) {
+		struct stat stb;
+
+		*p1 = *cp;
+		*p2 = '0';
+		/*
+		 * This stat() check is just to keep us from
+		 * looping through all 256 combinations if there
+		 * aren't that many ptys available.
+		 */
+		if (stat(line, &stb) < 0)
+			break;
+		for (i = 0; i < 16; i++) {
+			*p2 = "0123456789abcdef"[i];
+			p = open(line, 2);
+			if (p > 0) {
+#ifndef	__hpux
+				line[5] = 't';
+#else
+				for (p1 = &line[8]; *p1; p1++)
+					*p1 = *(p1+1);
+				line[9] = 't';
+#endif
+				chown(line, 0, 0);
+				chmod(line, 0600);
+#if defined(sun) && defined(TIOCGPGRP) && BSD < 199207
+				if (ioctl(p, TIOCGPGRP, &dummy) == 0
+				    || errno != EIO) {
+					chmod(line, 0666);
+					close(p);
+					line[5] = 'p';
+				} else
+#endif /* defined(sun) && defined(TIOCGPGRP) && BSD < 199207 */
+					return(p);
+			}
+		}
+	}
+#else	/* CRAY */
+	extern lowpty, highpty;
+	struct stat sb;
+
+	for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) {
+		(void) sprintf(myline, "/dev/pty/%03d", *ptynum);
+		p = open(myline, 2);
+		if (p < 0)
+			continue;
+		(void) sprintf(line, "/dev/ttyp%03d", *ptynum);
+		/*
+		 * Here are some shenanigans to make sure that there
+		 * are no listeners lurking on the line.
+		 */
+		if(stat(line, &sb) < 0) {
+			(void) close(p);
+			continue;
+		}
+		if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
+			chown(line, 0, 0);
+			chmod(line, 0600);
+			(void)close(p);
+			p = open(myline, 2);
+			if (p < 0)
+				continue;
+		}
+		/*
+		 * Now it should be safe...check for accessability.
+		 */
+		if (access(line, 6) == 0)
+			return(p);
+		else {
+			/* no tty side to pty so skip it */
+			(void) close(p);
+		}
+	}
+#endif	/* CRAY */
+#endif	/* STREAMSPTY */
+	return(-1);
+}
+#endif	/* convex */
+
+#ifdef	LINEMODE
+/*
+ * tty_flowmode()	Find out if flow control is enabled or disabled.
+ * tty_linemode()	Find out if linemode (external processing) is enabled.
+ * tty_setlinemod(on)	Turn on/off linemode.
+ * tty_isecho()		Find out if echoing is turned on.
+ * tty_setecho(on)	Enable/disable character echoing.
+ * tty_israw()		Find out if terminal is in RAW mode.
+ * tty_binaryin(on)	Turn on/off BINARY on input.
+ * tty_binaryout(on)	Turn on/off BINARY on output.
+ * tty_isediting()	Find out if line editing is enabled.
+ * tty_istrapsig()	Find out if signal trapping is enabled.
+ * tty_setedit(on)	Turn on/off line editing.
+ * tty_setsig(on)	Turn on/off signal trapping.
+ * tty_issofttab()	Find out if tab expansion is enabled.
+ * tty_setsofttab(on)	Turn on/off soft tab expansion.
+ * tty_islitecho()	Find out if typed control chars are echoed literally
+ * tty_setlitecho()	Turn on/off literal echo of control chars
+ * tty_tspeed(val)	Set transmit speed to val.
+ * tty_rspeed(val)	Set receive speed to val.
+ */
+
+#ifdef convex
+static int linestate;
+#endif
+
+	int
+tty_linemode()
+{
+#ifndef convex
+#ifndef	USE_TERMIO
+	return(termbuf.state & TS_EXTPROC);
+#else
+	return(termbuf.c_lflag & EXTPROC);
+#endif
+#else
+	return(linestate);
+#endif
+}
+
+	void
+tty_setlinemode(on)
+	int on;
+{
+#ifdef	TIOCEXT
+# ifndef convex
+	set_termbuf();
+# else
+	linestate = on;
+# endif
+	(void) ioctl(pty, TIOCEXT, (char *)&on);
+# ifndef convex
+	init_termbuf();
+# endif
+#else	/* !TIOCEXT */
+# ifdef	EXTPROC
+	if (on)
+		termbuf.c_lflag |= EXTPROC;
+	else
+		termbuf.c_lflag &= ~EXTPROC;
+# endif
+#endif	/* TIOCEXT */
+}
+#endif	/* LINEMODE */
+
+	int
+tty_isecho()
+{
+#ifndef USE_TERMIO
+	return (termbuf.sg.sg_flags & ECHO);
+#else
+	return (termbuf.c_lflag & ECHO);
+#endif
+}
+
+	int
+tty_flowmode()
+{
+#ifndef USE_TERMIO
+	return(((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0) ? 1 : 0);
+#else
+	return((termbuf.c_iflag & IXON) ? 1 : 0);
+#endif
+}
+
+	int
+tty_restartany()
+{
+#ifndef USE_TERMIO
+# ifdef	DECCTQ
+	return((termbuf.lflags & DECCTQ) ? 0 : 1);
+# else
+	return(-1);
+# endif
+#else
+	return((termbuf.c_iflag & IXANY) ? 1 : 0);
+#endif
+}
+
+	void
+tty_setecho(on)
+	int on;
+{
+#ifndef	USE_TERMIO
+	if (on)
+		termbuf.sg.sg_flags |= ECHO|CRMOD;
+	else
+		termbuf.sg.sg_flags &= ~(ECHO|CRMOD);
+#else
+	if (on)
+		termbuf.c_lflag |= ECHO;
+	else
+		termbuf.c_lflag &= ~ECHO;
+#endif
+}
+
+	int
+tty_israw()
+{
+#ifndef USE_TERMIO
+	return(termbuf.sg.sg_flags & RAW);
+#else
+	return(!(termbuf.c_lflag & ICANON));
+#endif
+}
+
+#if	defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
+	int
+tty_setraw(on)
+{
+#  ifndef USE_TERMIO
+	if (on)
+		termbuf.sg.sg_flags |= RAW;
+	else
+		termbuf.sg.sg_flags &= ~RAW;
+#  else
+	if (on)
+		termbuf.c_lflag &= ~ICANON;
+	else
+		termbuf.c_lflag |= ICANON;
+#  endif
+}
+#endif
+
+	void
+tty_binaryin(on)
+	int on;
+{
+#ifndef	USE_TERMIO
+	if (on)
+		termbuf.lflags |= LPASS8;
+	else
+		termbuf.lflags &= ~LPASS8;
+#else
+	if (on) {
+		termbuf.c_iflag &= ~ISTRIP;
+	} else {
+		termbuf.c_iflag |= ISTRIP;
+	}
+#endif
+}
+
+	void
+tty_binaryout(on)
+	int on;
+{
+#ifndef	USE_TERMIO
+	if (on)
+		termbuf.lflags |= LLITOUT;
+	else
+		termbuf.lflags &= ~LLITOUT;
+#else
+	if (on) {
+		termbuf.c_cflag &= ~(CSIZE|PARENB);
+		termbuf.c_cflag |= CS8;
+		termbuf.c_oflag &= ~OPOST;
+	} else {
+		termbuf.c_cflag &= ~CSIZE;
+		termbuf.c_cflag |= CS7|PARENB;
+		termbuf.c_oflag |= OPOST;
+	}
+#endif
+}
+
+	int
+tty_isbinaryin()
+{
+#ifndef	USE_TERMIO
+	return(termbuf.lflags & LPASS8);
+#else
+	return(!(termbuf.c_iflag & ISTRIP));
+#endif
+}
+
+	int
+tty_isbinaryout()
+{
+#ifndef	USE_TERMIO
+	return(termbuf.lflags & LLITOUT);
+#else
+	return(!(termbuf.c_oflag&OPOST));
+#endif
+}
+
+#ifdef	LINEMODE
+	int
+tty_isediting()
+{
+#ifndef USE_TERMIO
+	return(!(termbuf.sg.sg_flags & (CBREAK|RAW)));
+#else
+	return(termbuf.c_lflag & ICANON);
+#endif
+}
+
+	int
+tty_istrapsig()
+{
+#ifndef USE_TERMIO
+	return(!(termbuf.sg.sg_flags&RAW));
+#else
+	return(termbuf.c_lflag & ISIG);
+#endif
+}
+
+	void
+tty_setedit(on)
+	int on;
+{
+#ifndef USE_TERMIO
+	if (on)
+		termbuf.sg.sg_flags &= ~CBREAK;
+	else
+		termbuf.sg.sg_flags |= CBREAK;
+#else
+	if (on)
+		termbuf.c_lflag |= ICANON;
+	else
+		termbuf.c_lflag &= ~ICANON;
+#endif
+}
+
+	void
+tty_setsig(on)
+	int on;
+{
+#ifndef	USE_TERMIO
+	if (on)
+		;
+#else
+	if (on)
+		termbuf.c_lflag |= ISIG;
+	else
+		termbuf.c_lflag &= ~ISIG;
+#endif
+}
+#endif	/* LINEMODE */
+
+	int
+tty_issofttab()
+{
+#ifndef	USE_TERMIO
+	return (termbuf.sg.sg_flags & XTABS);
+#else
+# ifdef	OXTABS
+	return (termbuf.c_oflag & OXTABS);
+# endif
+# ifdef	TABDLY
+	return ((termbuf.c_oflag & TABDLY) == TAB3);
+# endif
+#endif
+}
+
+	void
+tty_setsofttab(on)
+	int on;
+{
+#ifndef	USE_TERMIO
+	if (on)
+		termbuf.sg.sg_flags |= XTABS;
+	else
+		termbuf.sg.sg_flags &= ~XTABS;
+#else
+	if (on) {
+# ifdef	OXTABS
+		termbuf.c_oflag |= OXTABS;
+# endif
+# ifdef	TABDLY
+		termbuf.c_oflag &= ~TABDLY;
+		termbuf.c_oflag |= TAB3;
+# endif
+	} else {
+# ifdef	OXTABS
+		termbuf.c_oflag &= ~OXTABS;
+# endif
+# ifdef	TABDLY
+		termbuf.c_oflag &= ~TABDLY;
+		termbuf.c_oflag |= TAB0;
+# endif
+	}
+#endif
+}
+
+	int
+tty_islitecho()
+{
+#ifndef	USE_TERMIO
+	return (!(termbuf.lflags & LCTLECH));
+#else
+# ifdef	ECHOCTL
+	return (!(termbuf.c_lflag & ECHOCTL));
+# endif
+# ifdef	TCTLECH
+	return (!(termbuf.c_lflag & TCTLECH));
+# endif
+# if	!defined(ECHOCTL) && !defined(TCTLECH)
+	return (0);	/* assumes ctl chars are echoed '^x' */
+# endif
+#endif
+}
+
+	void
+tty_setlitecho(on)
+	int on;
+{
+#ifndef	USE_TERMIO
+	if (on)
+		termbuf.lflags &= ~LCTLECH;
+	else
+		termbuf.lflags |= LCTLECH;
+#else
+# ifdef	ECHOCTL
+	if (on)
+		termbuf.c_lflag &= ~ECHOCTL;
+	else
+		termbuf.c_lflag |= ECHOCTL;
+# endif
+# ifdef	TCTLECH
+	if (on)
+		termbuf.c_lflag &= ~TCTLECH;
+	else
+		termbuf.c_lflag |= TCTLECH;
+# endif
+#endif
+}
+
+	int
+tty_iscrnl()
+{
+#ifndef	USE_TERMIO
+	return (termbuf.sg.sg_flags & CRMOD);
+#else
+	return (termbuf.c_iflag & ICRNL);
+#endif
+}
+
+/*
+ * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD).
+ */
+#if B4800 != 4800
+#define	DECODE_BAUD
+#endif
+
+#ifdef	DECODE_BAUD
+
+/*
+ * A table of available terminal speeds
+ */
+struct termspeeds {
+	int	speed;
+	int	value;
+} termspeeds[] = {
+	{ 0,      B0 },      { 50,    B50 },    { 75,     B75 },
+	{ 110,    B110 },    { 134,   B134 },   { 150,    B150 },
+	{ 200,    B200 },    { 300,   B300 },   { 600,    B600 },
+	{ 1200,   B1200 },   { 1800,  B1800 },  { 2400,   B2400 },
+	{ 4800,   B4800 },
+#ifdef	B7200
+	{ 7200,  B7200 },
+#endif
+	{ 9600,   B9600 },
+#ifdef	B14400
+	{ 14400,  B14400 },
+#endif
+#ifdef	B19200
+	{ 19200,  B19200 },
+#endif
+#ifdef	B28800
+	{ 28800,  B28800 },
+#endif
+#ifdef	B38400
+	{ 38400,  B38400 },
+#endif
+#ifdef	B57600
+	{ 57600,  B57600 },
+#endif
+#ifdef	B115200
+	{ 115200, B115200 },
+#endif
+#ifdef	B230400
+	{ 230400, B230400 },
+#endif
+	{ -1,     0 }
+};
+#endif	/* DECODE_BUAD */
+
+	void
+tty_tspeed(val)
+	int val;
+{
+#ifdef	DECODE_BAUD
+	register struct termspeeds *tp;
+
+	for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
+		;
+	if (tp->speed == -1)	/* back up to last valid value */
+		--tp;
+	cfsetospeed(&termbuf, tp->value);
+#else	/* DECODE_BUAD */
+	cfsetospeed(&termbuf, val);
+#endif	/* DECODE_BUAD */
+}
+
+	void
+tty_rspeed(val)
+	int val;
+{
+#ifdef	DECODE_BAUD
+	register struct termspeeds *tp;
+
+	for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
+		;
+	if (tp->speed == -1)	/* back up to last valid value */
+		--tp;
+	cfsetispeed(&termbuf, tp->value);
+#else	/* DECODE_BAUD */
+	cfsetispeed(&termbuf, val);
+#endif	/* DECODE_BAUD */
+}
+
+#if	defined(CRAY2) && defined(UNICOS5)
+	int
+tty_isnewmap()
+{
+	return((termbuf.c_oflag & OPOST) && (termbuf.c_oflag & ONLCR) &&
+			!(termbuf.c_oflag & ONLRET));
+}
+#endif
+
+#ifdef PARENT_DOES_UTMP
+# ifndef NEWINIT
+extern	struct utmp wtmp;
+extern char wtmpf[];
+# else	/* NEWINIT */
+int	gotalarm;
+
+	/* ARGSUSED */
+	void
+nologinproc(sig)
+	int sig;
+{
+	gotalarm++;
+}
+# endif	/* NEWINIT */
+#endif /* PARENT_DOES_UTMP */
+
+#ifndef	NEWINIT
+# ifdef PARENT_DOES_UTMP
+extern void utmp_sig_init P((void));
+extern void utmp_sig_reset P((void));
+extern void utmp_sig_wait P((void));
+extern void utmp_sig_notify P((int));
+# endif /* PARENT_DOES_UTMP */
+#endif
+
+/*
+ * getptyslave()
+ *
+ * Open the slave side of the pty, and do any initialization
+ * that is necessary.  The return value is a file descriptor
+ * for the slave side.
+ */
+	int
+getptyslave()
+{
+	register int t = -1;
+
+#if	!defined(CRAY) || !defined(NEWINIT)
+# ifdef	LINEMODE
+	int waslm;
+# endif
+# ifdef	TIOCGWINSZ
+	struct winsize ws;
+	extern int def_row, def_col;
+# endif
+	extern int def_tspeed, def_rspeed;
+	/*
+	 * Opening the slave side may cause initilization of the
+	 * kernel tty structure.  We need remember the state of
+	 * 	if linemode was turned on
+	 *	terminal window size
+	 *	terminal speed
+	 * so that we can re-set them if we need to.
+	 */
+# ifdef	LINEMODE
+	waslm = tty_linemode();
+# endif
+
+
+	/*
+	 * Make sure that we don't have a controlling tty, and
+	 * that we are the session (process group) leader.
+	 */
+# ifdef	TIOCNOTTY
+	t = open(_PATH_TTY, O_RDWR);
+	if (t >= 0) {
+		(void) ioctl(t, TIOCNOTTY, (char *)0);
+		(void) close(t);
+	}
+# endif
+
+
+# ifdef PARENT_DOES_UTMP
+	/*
+	 * Wait for our parent to get the utmp stuff to get done.
+	 */
+	utmp_sig_wait();
+# endif
+
+	t = cleanopen(line);
+	if (t < 0)
+		fatalperror(net, line);
+
+#ifdef  STREAMSPTY
+#ifdef	USE_TERMIO
+	ttyfd = t;
+#endif
+	if (ioctl(t, I_PUSH, "ptem") < 0)
+		fatal(net, "I_PUSH ptem");
+	if (ioctl(t, I_PUSH, "ldterm") < 0)
+		fatal(net, "I_PUSH ldterm");
+	if (ioctl(t, I_PUSH, "ttcompat") < 0)
+		fatal(net, "I_PUSH ttcompat");
+	if (ioctl(pty, I_PUSH, "pckt") < 0)
+		fatal(net, "I_PUSH pckt");
+#endif
+
+	/*
+	 * set up the tty modes as we like them to be.
+	 */
+	init_termbuf();
+# ifdef	TIOCGWINSZ
+	if (def_row || def_col) {
+		memset((char *)&ws, 0, sizeof(ws));
+		ws.ws_col = def_col;
+		ws.ws_row = def_row;
+		(void)ioctl(t, TIOCSWINSZ, (char *)&ws);
+	}
+# endif
+
+	/*
+	 * Settings for sgtty based systems
+	 */
+# ifndef	USE_TERMIO
+	termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS;
+# endif	/* USE_TERMIO */
+
+	/*
+	 * Settings for UNICOS (and HPUX)
+	 */
+# if defined(CRAY) || defined(__hpux)
+	termbuf.c_oflag = OPOST|ONLCR|TAB3;
+	termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
+	termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
+	termbuf.c_cflag = EXTB|HUPCL|CS8;
+# endif
+
+	/*
+	 * Settings for all other termios/termio based
+	 * systems, other than 4.4BSD.  In 4.4BSD the
+	 * kernel does the initial terminal setup.
+	 */
+# if defined(USE_TERMIO) && !(defined(CRAY) || defined(__hpux)) && (BSD <= 43)
+#  ifndef	OXTABS
+#   define OXTABS	0
+#  endif
+	termbuf.c_lflag |= ECHO;
+	termbuf.c_oflag |= ONLCR|OXTABS;
+	termbuf.c_iflag |= ICRNL;
+	termbuf.c_iflag &= ~IXOFF;
+# endif /* defined(USE_TERMIO) && !defined(CRAY) && (BSD <= 43) */
+	tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);
+	tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);
+# ifdef	LINEMODE
+	if (waslm)
+		tty_setlinemode(1);
+# endif	/* LINEMODE */
+
+	/*
+	 * Set the tty modes, and make this our controlling tty.
+	 */
+	set_termbuf();
+	if (login_tty(t) == -1)
+		fatalperror(net, "login_tty");
+#endif	/* !defined(CRAY) || !defined(NEWINIT) */
+	if (net > 2)
+		(void) close(net);
+#if	defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
+	/*
+	 * Leave the pty open so that we can write out the rlogin
+	 * protocol for /bin/login, if the authentication works.
+	 */
+#else
+	if (pty > 2) {
+		(void) close(pty);
+		pty = -1;
+	}
+#endif
+}
+
+#if	!defined(CRAY) || !defined(NEWINIT)
+#ifndef	O_NOCTTY
+#define	O_NOCTTY	0
+#endif
+/*
+ * Open the specified slave side of the pty,
+ * making sure that we have a clean tty.
+ */
+	int
+cleanopen(line)
+	char *line;
+{
+	register int t;
+#ifdef	UNICOS7x
+	struct secstat secbuf;
+#endif	/* UNICOS7x */
+
+#ifndef STREAMSPTY
+	/*
+	 * Make sure that other people can't open the
+	 * slave side of the connection.
+	 */
+	(void) chown(line, 0, 0);
+	(void) chmod(line, 0600);
+#endif
+
+# if !defined(CRAY) && (BSD > 43)
+	(void) revoke(line);
+# endif
+#ifdef	UNICOS7x
+	if (secflag) {
+		if (secstat(line, &secbuf) < 0)
+			return(-1);
+		if (setulvl(secbuf.st_slevel) < 0)
+			return(-1);
+		if (setucmp(secbuf.st_compart) < 0)
+			return(-1);
+	}
+#endif	/* UNICOS7x */
+
+	t = open(line, O_RDWR|O_NOCTTY);
+
+#ifdef	UNICOS7x
+	if (secflag) {
+		if (setulvl(sysv.sy_minlvl) < 0)
+			return(-1);
+		if (setucmp(0) < 0)
+			return(-1);
+	}
+#endif	/* UNICOS7x */
+
+	if (t < 0)
+		return(-1);
+
+	/*
+	 * Hangup anybody else using this ttyp, then reopen it for
+	 * ourselves.
+	 */
+# if !(defined(CRAY) || defined(__hpux)) && (BSD <= 43) && !defined(STREAMSPTY)
+	(void) signal(SIGHUP, SIG_IGN);
+	vhangup();
+	(void) signal(SIGHUP, SIG_DFL);
+	t = open(line, O_RDWR|O_NOCTTY);
+	if (t < 0)
+		return(-1);
+# endif
+# if	defined(CRAY) && defined(TCVHUP)
+	{
+		register int i;
+		(void) signal(SIGHUP, SIG_IGN);
+		(void) ioctl(t, TCVHUP, (char *)0);
+		(void) signal(SIGHUP, SIG_DFL);
+
+#ifdef	UNICOS7x
+		if (secflag) {
+			if (secstat(line, &secbuf) < 0)
+				return(-1);
+			if (setulvl(secbuf.st_slevel) < 0)
+				return(-1);
+			if (setucmp(secbuf.st_compart) < 0)
+				return(-1);
+		}
+#endif	/* UNICOS7x */
+
+		i = open(line, O_RDWR);
+
+#ifdef	UNICOS7x
+		if (secflag) {
+			if (setulvl(sysv.sy_minlvl) < 0)
+				return(-1);
+			if (setucmp(0) < 0)
+				return(-1);
+		}
+#endif	/* UNICOS7x */
+
+		if (i < 0)
+			return(-1);
+		(void) close(t);
+		t = i;
+	}
+# endif	/* defined(CRAY) && defined(TCVHUP) */
+	return(t);
+}
+#endif	/* !defined(CRAY) || !defined(NEWINIT) */
+
+#if BSD <= 43
+
+	int
+login_tty(t)
+	int t;
+{
+	if (setsid() < 0) {
+#ifdef ultrix
+		/*
+		 * The setsid() may have failed because we
+		 * already have a pgrp == pid.  Zero out
+		 * our pgrp and try again...
+		 */
+		if ((setpgrp(0, 0) < 0) || (setsid() < 0))
+#endif
+			fatalperror(net, "setsid()");
+	}
+# ifdef	TIOCSCTTY
+	if (ioctl(t, TIOCSCTTY, (char *)0) < 0)
+		fatalperror(net, "ioctl(sctty)");
+#  if defined(CRAY)
+	/*
+	 * Close the hard fd to /dev/ttypXXX, and re-open through
+	 * the indirect /dev/tty interface.
+	 */
+	close(t);
+	if ((t = open("/dev/tty", O_RDWR)) < 0)
+		fatalperror(net, "open(/dev/tty)");
+#  endif
+# else
+	/*
+	 * We get our controlling tty assigned as a side-effect
+	 * of opening up a tty device.  But on BSD based systems,
+	 * this only happens if our process group is zero.  The
+	 * setsid() call above may have set our pgrp, so clear
+	 * it out before opening the tty...
+	 */
+#  ifndef SOLARIS
+	(void) setpgrp(0, 0);
+#  else
+	(void) setpgrp();
+#  endif
+	close(open(line, O_RDWR));
+# endif
+	if (t != 0)
+		(void) dup2(t, 0);
+	if (t != 1)
+		(void) dup2(t, 1);
+	if (t != 2)
+		(void) dup2(t, 2);
+	if (t > 2)
+		close(t);
+	return(0);
+}
+#endif	/* BSD <= 43 */
+
+#ifdef	NEWINIT
+char *gen_id = "fe";
+#endif
+
+/*
+ * startslave(host)
+ *
+ * Given a hostname, do whatever
+ * is necessary to startup the login process on the slave side of the pty.
+ */
+
+/* ARGSUSED */
+	void
+startslave(host, autologin, autoname)
+	char *host;
+	int autologin;
+	char *autoname;
+{
+	register int i;
+	long time();
+	char name[256];
+#ifdef	NEWINIT
+	extern char *ptyip;
+	struct init_request request;
+	void nologinproc();
+	register int n;
+#endif	/* NEWINIT */
+
+#if	defined(AUTHENTICATION)
+	if (!autoname || !autoname[0])
+		autologin = 0;
+
+	if (autologin < auth_level) {
+		fatal(net, "Authorization failed");
+		exit(1);
+	}
+#endif
+
+#ifndef	NEWINIT
+# ifdef	PARENT_DOES_UTMP
+	utmp_sig_init();
+# endif	/* PARENT_DOES_UTMP */
+
+	if ((i = fork()) < 0)
+		fatalperror(net, "fork");
+	if (i) {
+# ifdef PARENT_DOES_UTMP
+		/*
+		 * Cray parent will create utmp entry for child and send
+		 * signal to child to tell when done.  Child waits for signal
+		 * before doing anything important.
+		 */
+		register int pid = i;
+		void sigjob P((int));
+
+		setpgrp();
+		utmp_sig_reset();		/* reset handler to default */
+		/*
+		 * Create utmp entry for child
+		 */
+		(void) time(&wtmp.ut_time);
+		wtmp.ut_type = LOGIN_PROCESS;
+		wtmp.ut_pid = pid;
+		SCPYN(wtmp.ut_user, "LOGIN");
+		SCPYN(wtmp.ut_host, host);
+		SCPYN(wtmp.ut_line, line + sizeof("/dev/") - 1);
+#ifndef	__hpux
+		SCPYN(wtmp.ut_id, wtmp.ut_line+3);
+#else
+		SCPYN(wtmp.ut_id, wtmp.ut_line+7);
+#endif
+		pututline(&wtmp);
+		endutent();
+		if ((i = open(wtmpf, O_WRONLY|O_APPEND)) >= 0) {
+			(void) write(i, (char *)&wtmp, sizeof(struct utmp));
+			(void) close(i);
+		}
+#ifdef	CRAY
+		(void) signal(WJSIGNAL, sigjob);
+#endif
+		utmp_sig_notify(pid);
+# endif	/* PARENT_DOES_UTMP */
+	} else {
+		getptyslave(autologin);
+		start_login(host, autologin, autoname);
+		/*NOTREACHED*/
+	}
+#else	/* NEWINIT */
+
+	/*
+	 * Init will start up login process if we ask nicely.  We only wait
+	 * for it to start up and begin normal telnet operation.
+	 */
+	if ((i = open(INIT_FIFO, O_WRONLY)) < 0) {
+		char tbuf[128];
+		(void) sprintf(tbuf, "Can't open %s\n", INIT_FIFO);
+		fatalperror(net, tbuf);
+	}
+	memset((char *)&request, 0, sizeof(request));
+	request.magic = INIT_MAGIC;
+	SCPYN(request.gen_id, gen_id);
+	SCPYN(request.tty_id, &line[8]);
+	SCPYN(request.host, host);
+	SCPYN(request.term_type, terminaltype ? terminaltype : "network");
+#if	!defined(UNICOS5)
+	request.signal = SIGCLD;
+	request.pid = getpid();
+#endif
+#ifdef BFTPDAEMON
+	/*
+	 * Are we working as the bftp daemon?
+	 */
+	if (bftpd) {
+		SCPYN(request.exec_name, BFTPPATH);
+	}
+#endif /* BFTPDAEMON */
+	if (write(i, (char *)&request, sizeof(request)) < 0) {
+		char tbuf[128];
+		(void) sprintf(tbuf, "Can't write to %s\n", INIT_FIFO);
+		fatalperror(net, tbuf);
+	}
+	(void) close(i);
+	(void) signal(SIGALRM, nologinproc);
+	for (i = 0; ; i++) {
+		char tbuf[128];
+		alarm(15);
+		n = read(pty, ptyip, BUFSIZ);
+		if (i == 3 || n >= 0 || !gotalarm)
+			break;
+		gotalarm = 0;
+		sprintf(tbuf, "telnetd: waiting for /etc/init to start login process on %s\r\n", line);
+		(void) write(net, tbuf, strlen(tbuf));
+	}
+	if (n < 0 && gotalarm)
+		fatal(net, "/etc/init didn't start login process");
+	pcc += n;
+	alarm(0);
+	(void) signal(SIGALRM, SIG_DFL);
+
+	return;
+#endif	/* NEWINIT */
+}
+
+char	*envinit[3];
+extern char **environ;
+
+	void
+init_env()
+{
+	extern char *getenv();
+	char **envp;
+
+	envp = envinit;
+	if (*envp = getenv("TZ"))
+		*envp++ -= 3;
+#if	defined(CRAY) || defined(__hpux)
+	else
+		*envp++ = "TZ=GMT0";
+#endif
+	*envp = 0;
+	environ = envinit;
+}
+
+#ifndef	NEWINIT
+
+/*
+ * start_login(host)
+ *
+ * Assuming that we are now running as a child processes, this
+ * function will turn us into the login process.
+ */
+
+	void
+start_login(host, autologin, name)
+	char *host;
+	int autologin;
+	char *name;
+{
+	register char *cp;
+	register char **argv;
+	char **addarg();
+	extern char *getenv();
+#ifdef	UTMPX
+	register int pid = getpid();
+	struct utmpx utmpx;
+#endif
+#ifdef SOLARIS
+	char *term;
+	char termbuf[64];
+#endif
+
+#ifdef	UTMPX
+	/*
+	 * Create utmp entry for child
+	 */
+
+	memset(&utmpx, 0, sizeof(utmpx));
+	SCPYN(utmpx.ut_user, ".telnet");
+	SCPYN(utmpx.ut_line, line + sizeof("/dev/") - 1);
+	utmpx.ut_pid = pid;
+	utmpx.ut_id[0] = 't';
+	utmpx.ut_id[1] = 'n';
+	utmpx.ut_id[2] = SC_WILDC;
+	utmpx.ut_id[3] = SC_WILDC;
+	utmpx.ut_type = LOGIN_PROCESS;
+	(void) time(&utmpx.ut_tv.tv_sec);
+	if (pututxline(&utmpx) == NULL)
+		fatal(net, "pututxline failed");
+#endif
+
+	/*
+	 * -h : pass on name of host.
+	 *		WARNING:  -h is accepted by login if and only if
+	 *			getuid() == 0.
+	 * -p : don't clobber the environment (so terminal type stays set).
+	 *
+	 * -f : force this login, he has already been authenticated
+	 */
+	argv = addarg(0, "login");
+
+#if	!defined(NO_LOGIN_H)
+
+# if	defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
+	/*
+	 * Don't add the "-h host" option if we are going
+	 * to be adding the "-r host" option down below...
+	 */
+	if ((auth_level < 0) || (autologin != AUTH_VALID))
+# endif
+	{
+		argv = addarg(argv, "-h");
+		argv = addarg(argv, host);
+#ifdef	SOLARIS
+		/*
+		 * SVR4 version of -h takes TERM= as second arg, or -
+		 */
+		term = getenv("TERM");
+		if (term == NULL || term[0] == 0) {
+			term = "-";
+		} else {
+			strcpy(termbuf, "TERM=");
+			strncat(termbuf, term, sizeof(termbuf) - 6);
+			term = termbuf;
+		}
+		argv = addarg(argv, term);
+#endif
+	}
+#endif
+#if	!defined(NO_LOGIN_P)
+	argv = addarg(argv, "-p");
+#endif
+#ifdef	LINEMODE
+	/*
+	 * Set the environment variable "LINEMODE" to either
+	 * "real" or "kludge" if we are operating in either
+	 * real or kludge linemode.
+	 */
+	if (lmodetype == REAL_LINEMODE)
+		setenv("LINEMODE", "real", 1);
+# ifdef KLUDGELINEMODE
+	else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK)
+		setenv("LINEMODE", "kludge", 1);
+# endif
+#endif
+#ifdef	BFTPDAEMON
+	/*
+	 * Are we working as the bftp daemon?  If so, then ask login
+	 * to start bftp instead of shell.
+	 */
+	if (bftpd) {
+		argv = addarg(argv, "-e");
+		argv = addarg(argv, BFTPPATH);
+	} else
+#endif
+#if	defined (SecurID)
+	/*
+	 * don't worry about the -f that might get sent.
+	 * A -s is supposed to override it anyhow.
+	 */
+	if (require_SecurID)
+		argv = addarg(argv, "-s");
+#endif
+#if	defined (AUTHENTICATION)
+	if (auth_level >= 0 && autologin == AUTH_VALID) {
+# if	!defined(NO_LOGIN_F)
+		argv = addarg(argv, "-f");
+		argv = addarg(argv, name);
+# else
+#  if defined(LOGIN_R)
+		/*
+		 * We don't have support for "login -f", but we
+		 * can fool /bin/login into thinking that we are
+		 * rlogind, and allow us to log in without a
+		 * password.  The rlogin protocol expects
+		 *	local-user\0remote-user\0term/speed\0
+		 */
+
+		if (pty > 2) {
+			register char *cp;
+			char speed[128];
+			int isecho, israw, xpty, len;
+			extern int def_rspeed;
+#  ifndef LOGIN_HOST
+			/*
+			 * Tell login that we are coming from "localhost".
+			 * If we passed in the real host name, then the
+			 * user would have to allow .rhost access from
+			 * every machine that they want authenticated
+			 * access to work from, which sort of defeats
+			 * the purpose of an authenticated login...
+			 * So, we tell login that the session is coming
+			 * from "localhost", and the user will only have
+			 * to have "localhost" in their .rhost file.
+			 */
+#			define LOGIN_HOST "localhost"
+#  endif
+			argv = addarg(argv, "-r");
+			argv = addarg(argv, LOGIN_HOST);
+
+			xpty = pty;
+# ifndef  STREAMSPTY
+			pty = 0;
+# else
+			ttyfd = 0;
+# endif
+			init_termbuf();
+			isecho = tty_isecho();
+			israw = tty_israw();
+			if (isecho || !israw) {
+				tty_setecho(0);		/* Turn off echo */
+				tty_setraw(1);		/* Turn on raw */
+				set_termbuf();
+			}
+			len = strlen(name)+1;
+			write(xpty, name, len);
+			write(xpty, name, len);
+			sprintf(speed, "%s/%d", (cp = getenv("TERM")) ? cp : "",
+				(def_rspeed > 0) ? def_rspeed : 9600);
+			len = strlen(speed)+1;
+			write(xpty, speed, len);
+
+			if (isecho || !israw) {
+				init_termbuf();
+				tty_setecho(isecho);
+				tty_setraw(israw);
+				set_termbuf();
+				if (!israw) {
+					/*
+					 * Write a newline to ensure
+					 * that login will be able to
+					 * read the line...
+					 */
+					write(xpty, "\n", 1);
+				}
+			}
+			pty = xpty;
+		}
+#  else
+		argv = addarg(argv, name);
+#  endif
+# endif
+	} else
+#endif
+	if (getenv("USER")) {
+		argv = addarg(argv, getenv("USER"));
+#if	defined(LOGIN_ARGS) && defined(NO_LOGIN_P)
+		{
+			register char **cpp;
+			for (cpp = environ; *cpp; cpp++)
+				argv = addarg(argv, *cpp);
+		}
+#endif
+		/*
+		 * Assume that login will set the USER variable
+		 * correctly.  For SysV systems, this means that
+		 * USER will no longer be set, just LOGNAME by
+		 * login.  (The problem is that if the auto-login
+		 * fails, and the user then specifies a different
+		 * account name, he can get logged in with both
+		 * LOGNAME and USER in his environment, but the
+		 * USER value will be wrong.
+		 */
+		unsetenv("USER");
+	}
+#ifdef	SOLARIS
+	else {
+		char **p;
+
+		argv = addarg(argv, "");	/* no login name */
+		for (p = environ; *p; p++) {
+			argv = addarg(argv, *p);
+		}
+	}
+#endif	/* SOLARIS */
+#if	defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
+	if (pty > 2)
+		close(pty);
+#endif
+	closelog();
+	/*
+	 * This sleep(1) is in here so that telnetd can
+	 * finish up with the tty.  There's a race condition
+	 * the login banner message gets lost...
+	 */
+	sleep(1);
+	execv(_PATH_LOGIN, argv);
+
+	syslog(LOG_ERR, "%s: %m\n", _PATH_LOGIN);
+	fatalperror(net, _PATH_LOGIN);
+	/*NOTREACHED*/
+}
+
+	char **
+addarg(argv, val)
+	register char **argv;
+	register char *val;
+{
+	register char **cpp;
+
+	if (argv == NULL) {
+		/*
+		 * 10 entries, a leading length, and a null
+		 */
+		argv = (char **)malloc(sizeof(*argv) * 12);
+		if (argv == NULL)
+			return(NULL);
+		*argv++ = (char *)10;
+		*argv = (char *)0;
+	}
+	for (cpp = argv; *cpp; cpp++)
+		;
+	if (cpp == &argv[(int)argv[-1]]) {
+		--argv;
+		*argv = (char *)((int)(*argv) + 10);
+		argv = (char **)realloc(argv, sizeof(*argv)*((int)(*argv) + 2));
+		if (argv == NULL)
+			return(NULL);
+		argv++;
+		cpp = &argv[(int)argv[-1] - 10];
+	}
+	*cpp++ = val;
+	*cpp = 0;
+	return(argv);
+}
+#endif	/* NEWINIT */
+
+/*
+ * cleanup()
+ *
+ * This is the routine to call when we are all through, to
+ * clean up anything that needs to be cleaned up.
+ */
+	/* ARGSUSED */
+	void
+cleanup(sig)
+	int sig;
+{
+#ifndef	PARENT_DOES_UTMP
+# if (BSD > 43) || defined(convex)
+	char *p;
+
+	p = line + sizeof("/dev/") - 1;
+	if (logout(p))
+		logwtmp(p, "", "");
+	(void)chmod(line, 0666);
+	(void)chown(line, 0, 0);
+	*p = 'p';
+	(void)chmod(line, 0666);
+	(void)chown(line, 0, 0);
+	(void) shutdown(net, 2);
+	exit(1);
+# else
+	void rmut();
+
+	rmut();
+	vhangup();	/* XXX */
+	(void) shutdown(net, 2);
+	exit(1);
+# endif
+#else	/* PARENT_DOES_UTMP */
+# ifdef	NEWINIT
+	(void) shutdown(net, 2);
+	exit(1);
+# else	/* NEWINIT */
+#  ifdef CRAY
+	static int incleanup = 0;
+	register int t;
+	int child_status; /* status of child process as returned by waitpid */
+	int flags = WNOHANG|WUNTRACED;
+
+	/*
+	 * 1: Pick up the zombie, if we are being called
+	 *    as the signal handler.
+	 * 2: If we are a nested cleanup(), return.
+	 * 3: Try to clean up TMPDIR.
+	 * 4: Fill in utmp with shutdown of process.
+	 * 5: Close down the network and pty connections.
+	 * 6: Finish up the TMPDIR cleanup, if needed.
+	 */
+	if (sig == SIGCHLD) {
+		while (waitpid(-1, &child_status, flags) > 0)
+			;	/* VOID */
+		/* Check if the child process was stopped
+		 * rather than exited.  We want cleanup only if
+		 * the child has died.
+		 */
+		if (WIFSTOPPED(child_status)) {
+			return;
+		}
+	}
+	t = sigblock(sigmask(SIGCHLD));
+	if (incleanup) {
+		sigsetmask(t);
+		return;
+	}
+	incleanup = 1;
+	sigsetmask(t);
+#ifdef	UNICOS7x
+	if (secflag) {
+		/*
+		 *	We need to set ourselves back to a null
+		 *	label to clean up.
+		 */
+
+		setulvl(sysv.sy_minlvl);
+		setucmp((long)0);
+	}
+#endif	/* UNICOS7x */
+
+	t = cleantmp(&wtmp);
+	setutent();	/* just to make sure */
+#  endif /* CRAY */
+	rmut(line);
+	close(pty);
+	(void) shutdown(net, 2);
+#  ifdef CRAY
+	if (t == 0)
+		cleantmp(&wtmp);
+#  endif /* CRAY */
+	exit(1);
+# endif	/* NEWINT */
+#endif	/* PARENT_DOES_UTMP */
+}
+
+#if defined(PARENT_DOES_UTMP) && !defined(NEWINIT)
+/*
+ * _utmp_sig_rcv
+ * utmp_sig_init
+ * utmp_sig_wait
+ *	These three functions are used to coordinate the handling of
+ *	the utmp file between the server and the soon-to-be-login shell.
+ *	The server actually creates the utmp structure, the child calls
+ *	utmp_sig_wait(), until the server calls utmp_sig_notify() and
+ *	signals the future-login shell to proceed.
+ */
+static int caught=0;		/* NZ when signal intercepted */
+static void (*func)();		/* address of previous handler */
+
+	void
+_utmp_sig_rcv(sig)
+	int sig;
+{
+	caught = 1;
+	(void) signal(SIGUSR1, func);
+}
+
+	void
+utmp_sig_init()
+{
+	/*
+	 * register signal handler for UTMP creation
+	 */
+	if ((int)(func = signal(SIGUSR1, _utmp_sig_rcv)) == -1)
+		fatalperror(net, "telnetd/signal");
+}
+
+	void
+utmp_sig_reset()
+{
+	(void) signal(SIGUSR1, func);	/* reset handler to default */
+}
+
+# ifdef __hpux
+# define sigoff() /* do nothing */
+# define sigon() /* do nothing */
+# endif
+
+	void
+utmp_sig_wait()
+{
+	/*
+	 * Wait for parent to write our utmp entry.
+	 */
+	sigoff();
+	while (caught == 0) {
+		pause();	/* wait until we get a signal (sigon) */
+		sigoff();	/* turn off signals while we check caught */
+	}
+	sigon();		/* turn on signals again */
+}
+
+	void
+utmp_sig_notify(pid)
+{
+	kill(pid, SIGUSR1);
+}
+
+# ifdef CRAY
+static int gotsigjob = 0;
+
+	/*ARGSUSED*/
+	void
+sigjob(sig)
+	int sig;
+{
+	register int jid;
+	register struct jobtemp *jp;
+
+	while ((jid = waitjob(NULL)) != -1) {
+		if (jid == 0) {
+			return;
+		}
+		gotsigjob++;
+		jobend(jid, NULL, NULL);
+	}
+}
+
+/*
+ *	jid_getutid:
+ *		called by jobend() before calling cleantmp()
+ *		to find the correct $TMPDIR to cleanup.
+ */
+
+	struct utmp *
+jid_getutid(jid)
+	int jid;
+{
+	struct utmp *cur = NULL;
+
+	setutent();	/* just to make sure */
+	while (cur = getutent()) {
+		if ( (cur->ut_type != NULL) && (jid == cur->ut_jid) ) {
+			return(cur);
+		}
+	}
+
+	return(0);
+}
+
+/*
+ * Clean up the TMPDIR that login created.
+ * The first time this is called we pick up the info
+ * from the utmp.  If the job has already gone away,
+ * then we'll clean up and be done.  If not, then
+ * when this is called the second time it will wait
+ * for the signal that the job is done.
+ */
+	int
+cleantmp(wtp)
+	register struct utmp *wtp;
+{
+	struct utmp *utp;
+	static int first = 1;
+	register int mask, omask, ret;
+	extern struct utmp *getutid P((const struct utmp *_Id));
+
+
+	mask = sigmask(WJSIGNAL);
+
+	if (first == 0) {
+		omask = sigblock(mask);
+		while (gotsigjob == 0)
+			sigpause(omask);
+		return(1);
+	}
+	first = 0;
+	setutent();	/* just to make sure */
+
+	utp = getutid(wtp);
+	if (utp == 0) {
+		syslog(LOG_ERR, "Can't get /var/run/utmp entry to clean TMPDIR");
+		return(-1);
+	}
+	/*
+	 * Nothing to clean up if the user shell was never started.
+	 */
+	if (utp->ut_type != USER_PROCESS || utp->ut_jid == 0)
+		return(1);
+
+	/*
+	 * Block the WJSIGNAL while we are in jobend().
+	 */
+	omask = sigblock(mask);
+	ret = jobend(utp->ut_jid, utp->ut_tpath, utp->ut_user);
+	sigsetmask(omask);
+	return(ret);
+}
+
+	int
+jobend(jid, path, user)
+	register int jid;
+	register char *path;
+	register char *user;
+{
+	static int saved_jid = 0;
+	static int pty_saved_jid = 0;
+	static char saved_path[sizeof(wtmp.ut_tpath)+1];
+	static char saved_user[sizeof(wtmp.ut_user)+1];
+
+	/*
+	 * this little piece of code comes into play
+	 * only when ptyreconnect is used to reconnect
+	 * to an previous session.
+	 *
+	 * this is the only time when the
+	 * "saved_jid != jid" code is executed.
+	 */
+
+	if ( saved_jid && saved_jid != jid ) {
+		if (!path) {	/* called from signal handler */
+			pty_saved_jid = jid;
+		} else {
+			pty_saved_jid = saved_jid;
+		}
+	}
+
+	if (path) {
+		strncpy(saved_path, path, sizeof(wtmp.ut_tpath));
+		strncpy(saved_user, user, sizeof(wtmp.ut_user));
+		saved_path[sizeof(saved_path)] = '\0';
+		saved_user[sizeof(saved_user)] = '\0';
+	}
+	if (saved_jid == 0) {
+		saved_jid = jid;
+		return(0);
+	}
+
+	/* if the jid has changed, get the correct entry from the utmp file */
+
+	if ( saved_jid != jid ) {
+		struct utmp *utp = NULL;
+		struct utmp *jid_getutid();
+
+		utp = jid_getutid(pty_saved_jid);
+
+		if (utp == 0) {
+			syslog(LOG_ERR, "Can't get /var/run/utmp entry to clean TMPDIR");
+			return(-1);
+		}
+
+		cleantmpdir(jid, utp->ut_tpath, utp->ut_user);
+		return(1);
+	}
+
+	cleantmpdir(jid, saved_path, saved_user);
+	return(1);
+}
+
+/*
+ * Fork a child process to clean up the TMPDIR
+ */
+cleantmpdir(jid, tpath, user)
+	register int jid;
+	register char *tpath;
+	register char *user;
+{
+	switch(fork()) {
+	case -1:
+		syslog(LOG_ERR, "TMPDIR cleanup(%s): fork() failed: %m\n",
+							tpath);
+		break;
+	case 0:
+		execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, 0);
+		syslog(LOG_ERR, "TMPDIR cleanup(%s): execl(%s) failed: %m\n",
+							tpath, CLEANTMPCMD);
+		exit(1);
+	default:
+		/*
+		 * Forget about child.  We will exit, and
+		 * /etc/init will pick it up.
+		 */
+		break;
+	}
+}
+# endif /* CRAY */
+#endif	/* defined(PARENT_DOES_UTMP) && !defined(NEWINIT) */
+
+/*
+ * rmut()
+ *
+ * This is the function called by cleanup() to
+ * remove the utmp entry for this person.
+ */
+
+#ifdef	UTMPX
+	void
+rmut()
+{
+	register f;
+	int found = 0;
+	struct utmp *u, *utmp;
+	int nutmp;
+	struct stat statbf;
+
+	struct utmpx *utxp, utmpx;
+
+	/*
+	 * This updates the utmpx and utmp entries and make a wtmp/x entry
+	 */
+
+	SCPYN(utmpx.ut_line, line + sizeof("/dev/") - 1);
+	utxp = getutxline(&utmpx);
+	if (utxp) {
+		utxp->ut_type = DEAD_PROCESS;
+		utxp->ut_exit.e_termination = 0;
+		utxp->ut_exit.e_exit = 0;
+		(void) time(&utmpx.ut_tv.tv_sec);
+		utmpx.ut_tv.tv_usec = 0;
+		modutx(utxp);
+	}
+	endutxent();
+}  /* end of rmut */
+#endif
+
+#if	!defined(UTMPX) && !(defined(CRAY) || defined(__hpux)) && BSD <= 43
+	void
+rmut()
+{
+	register f;
+	int found = 0;
+	struct utmp *u, *utmp;
+	int nutmp;
+	struct stat statbf;
+
+	f = open(utmpf, O_RDWR);
+	if (f >= 0) {
+		(void) fstat(f, &statbf);
+		utmp = (struct utmp *)malloc((unsigned)statbf.st_size);
+		if (!utmp)
+			syslog(LOG_ERR, "utmp malloc failed");
+		if (statbf.st_size && utmp) {
+			nutmp = read(f, (char *)utmp, (int)statbf.st_size);
+			nutmp /= sizeof(struct utmp);
+
+			for (u = utmp ; u < &utmp[nutmp] ; u++) {
+				if (SCMPN(u->ut_line, line+5) ||
+				    u->ut_name[0]==0)
+					continue;
+				(void) lseek(f, ((long)u)-((long)utmp), L_SET);
+				SCPYN(u->ut_name, "");
+				SCPYN(u->ut_host, "");
+				(void) time(&u->ut_time);
+				(void) write(f, (char *)u, sizeof(wtmp));
+				found++;
+			}
+		}
+		(void) close(f);
+	}
+	if (found) {
+		f = open(wtmpf, O_WRONLY|O_APPEND);
+		if (f >= 0) {
+			SCPYN(wtmp.ut_line, line+5);
+			SCPYN(wtmp.ut_name, "");
+			SCPYN(wtmp.ut_host, "");
+			(void) time(&wtmp.ut_time);
+			(void) write(f, (char *)&wtmp, sizeof(wtmp));
+			(void) close(f);
+		}
+	}
+	(void) chmod(line, 0666);
+	(void) chown(line, 0, 0);
+	line[strlen("/dev/")] = 'p';
+	(void) chmod(line, 0666);
+	(void) chown(line, 0, 0);
+}  /* end of rmut */
+#endif	/* CRAY */
+
+#ifdef __hpux
+rmut (line)
+char *line;
+{
+	struct utmp utmp;
+	struct utmp *utptr;
+	int fd;			/* for /etc/wtmp */
+
+	utmp.ut_type = USER_PROCESS;
+	(void) strncpy(utmp.ut_id, line+12, sizeof(utmp.ut_id));
+	(void) setutent();
+	utptr = getutid(&utmp);
+	/* write it out only if it exists */
+	if (utptr) {
+		utptr->ut_type = DEAD_PROCESS;
+		utptr->ut_time = time((long *) 0);
+		(void) pututline(utptr);
+		/* set wtmp entry if wtmp file exists */
+		if ((fd = open(wtmpf, O_WRONLY | O_APPEND)) >= 0) {
+			(void) write(fd, utptr, sizeof(utmp));
+			(void) close(fd);
+		}
+	}
+	(void) endutent();
+
+	(void) chmod(line, 0666);
+	(void) chown(line, 0, 0);
+	line[14] = line[13];
+	line[13] = line[12];
+	line[8] = 'm';
+	line[9] = '/';
+	line[10] = 'p';
+	line[11] = 't';
+	line[12] = 'y';
+	(void) chmod(line, 0666);
+	(void) chown(line, 0, 0);
+}
+#endif
diff --git a/telnetd.tproj/telnetd.8 b/telnetd.tproj/telnetd.8
new file mode 100644
index 0000000..f618385
--- /dev/null
+++ b/telnetd.tproj/telnetd.8
@@ -0,0 +1,607 @@
+.\" Copyright (c) 1983, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)telnetd.8	8.4 (Berkeley) 6/1/94
+.\"
+.Dd June 1, 1994
+.Dt TELNETD 8
+.Os BSD 4.2
+.Sh NAME
+.Nm telnetd
+.Nd DARPA
+.Tn TELNET
+protocol server
+.Sh SYNOPSIS
+.Nm /usr/libexec/telnetd
+.Op Fl BUhlkns
+.Op Fl D Ar debugmode
+.Op Fl I Ns Ar initid
+.Op Fl S Ar tos
+.Op Fl X Ar authtype
+.Op Fl a Ar authmode
+.Op Fl edebug
+.Op Fl r Ns Ar lowpty-highpty
+.Op Fl u Ar len
+.Op Fl debug Op Ar port
+.Sh DESCRIPTION
+The
+.Nm telnetd
+command is a server which supports the
+.Tn DARPA
+standard
+.Tn TELNET
+virtual terminal protocol.
+.Nm Telnetd
+is normally invoked by the internet server (see
+.Xr inetd 8 )
+for requests to connect to the
+.Tn TELNET
+port as indicated by the
+.Pa /etc/services
+file (see
+.Xr services 5 ) .
+The
+.Fl debug
+option may be used to start up
+.Nm telnetd
+manually, instead of through
+.Xr inetd 8 .
+If started up this way, 
+.Ar port
+may be specified to run
+.Nm telnetd
+on an alternate
+.Tn TCP
+port number.
+.Pp
+The
+.Nm telnetd
+command accepts the following options:
+.Bl -tag -width "-a authmode"
+.It Fl a Ar authmode
+This option may be used for specifying what mode should
+be used for authentication.
+Note that this option is only useful if
+.Nm telnetd
+has been compiled with support for the
+.Dv AUTHENTICATION
+option.
+There are several valid values for
+.Ar authmode:
+.Bl -tag -width debug
+.It debug
+Turns on authentication debugging code.
+.It user
+Only allow connections when the remote user
+can provide valid authentication information
+to identify the remote user,
+and is allowed access to the specified account
+without providing a password.
+.It valid
+Only allow connections when the remote user
+can provide valid authentication information
+to identify the remote user.
+The
+.Xr login 1
+command will provide any additional user verification
+needed if the remote user is not allowed automatic
+access to the specified account.
+.It other
+Only allow connections that supply some authentication information.
+This option is currently not supported
+by any of the existing authentication mechanisms,
+and is thus the same as specifying
+.Fl a
+.Cm valid .
+.It none
+This is the default state.
+Authentication information is not required.
+If no or insufficient authentication information
+is provided, then the
+.Xr login 1
+program will provide the necessary user
+verification.
+.It off
+This disables the authentication code.
+All user verification will happen through the
+.Xr login 1
+program.
+.El
+.It Fl B
+Specifies bftp server mode.  In this mode,
+.Nm telnetd
+causes login to start a
+.Xr bftp 1
+session rather than the user's
+normal shell.  In bftp daemon mode normal
+logins are not supported, and it must be used
+on a port other than the normal
+.Tn TELNET
+port.
+.It Fl D Ar debugmode
+This option may be used for debugging purposes.
+This allows
+.Nm telnetd
+to print out debugging information
+to the connection, allowing the user to see what
+.Nm telnetd
+is doing.
+There are several possible values for 
+.Ar debugmode:
+.Bl -tag -width exercise
+.It Cm options
+Prints information about the negotiation of
+.Tn TELNET
+options.
+.It Cm report
+Prints the 
+.Cm options
+information, plus some additional information
+about what processing is going on.
+.It Cm netdata
+Displays the data stream received by
+.Nm telnetd.
+.It Cm ptydata
+Displays data written to the pty.
+.It Cm exercise
+Has not been implemented yet.
+.El
+.It Fl debug
+Enables debugging on each socket created by
+.Nm telnetd
+(see
+.Dv SO_DEBUG
+in
+.Xr socket 2 ) .
+.It Fl edebug
+If
+.Nm telnetd
+has been compiled with support for data encryption, then the
+.Fl edebug
+option may be used to enable encryption debugging code.
+.It Fl h
+Disables the printing of host-specific information before
+login has been completed.
+.It Fl I Ar initid
+This option is only applicable to
+.Tn UNICOS
+systems prior to 7.0.
+It specifies the
+.Dv ID
+from
+.Pa /etc/inittab
+to use when init starts login sessions.  The default
+.Dv ID
+is
+.Dv fe.
+.It Fl k
+This option is only useful if
+.Nm telnetd
+has been compiled with both linemode and kludge linemode
+support.  If the
+.Fl k
+option is specified, then if the remote client does not
+support the
+.Dv LINEMODE
+option, then
+.Nm telnetd
+will operate in character at a time mode.
+It will still support kludge linemode, but will only
+go into kludge linemode if the remote client requests
+it.
+(This is done by by the client sending
+.Dv DONT SUPPRESS-GO-AHEAD
+and
+.Dv DONT ECHO . )
+The
+.Fl k
+option is most useful when there are remote clients
+that do not support kludge linemode, but pass the heuristic
+(if they respond with
+.Dv WILL TIMING-MARK
+in response to a
+.Dv DO TIMING-MARK)
+for kludge linemode support.
+.It Fl l
+Specifies line mode.  Tries to force clients to use line-
+at-a-time mode.
+If the
+.Dv LINEMODE
+option is not supported, it will go
+into kludge linemode.
+.It Fl n
+Disable
+.Dv TCP
+keep-alives.  Normally
+.Nm telnetd
+enables the
+.Tn TCP
+keep-alive mechanism to probe connections that
+have been idle for some period of time to determine
+if the client is still there, so that idle connections
+from machines that have crashed or can no longer
+be reached may be cleaned up.
+.It Fl r Ar lowpty-highpty
+This option is only enabled when
+.Nm telnetd
+is compiled for
+.Dv UNICOS.
+It specifies an inclusive range of pseudo-terminal devices to
+use.  If the system has sysconf variable
+.Dv _SC_CRAY_NPTY
+configured, the default pty search range is 0 to
+.Dv _SC_CRAY_NPTY;
+otherwise, the default range is 0 to 128.  Either
+.Ar lowpty
+or
+.Ar highpty
+may be omitted to allow changing
+either end of the search range.  If
+.Ar lowpty
+is omitted, the - character is still required so that
+.Nm telnetd
+can differentiate
+.Ar highpty
+from
+.Ar lowpty .
+.It Fl s
+This option is only enabled if
+.Nm telnetd
+is compiled with support for
+.Tn SecurID
+cards.
+It causes the
+.Fl s
+option to be passed on to
+.Xr login 1 ,
+and thus is only useful if
+.Xr login 1
+supports the
+.Fl s
+flag to indicate that only
+.Tn SecurID
+validated logins are allowed, and is
+usually useful for controlling remote logins
+from outside of a firewall.
+.It Fl S Ar tos
+.It Fl u Ar len
+This option is used to specify the size of the field
+in the
+.Dv utmp
+structure that holds the remote host name.
+If the resolved host name is longer than
+.Ar len ,
+the dotted decimal value will be used instead.
+This allows hosts with very long host names that
+overflow this field to still be uniquely identified.
+Specifying
+.Fl u0
+indicates that only dotted decimal addresses
+should be put into the
+.Pa utmp
+file.
+.ne 1i
+.It Fl U
+This option causes
+.Nm telnetd
+to refuse connections from addresses that
+cannot be mapped back into a symbolic name
+via the
+.Xr gethostbyaddr 3
+routine.
+.It Fl X Ar authtype
+This option is only valid if
+.Nm telnetd
+has been built with support for the authentication option.
+It disables the use of
+.Ar authtype
+authentication, and
+can be used to temporarily disable
+a specific authentication type without having to recompile
+.Nm telnetd .
+.El
+.Pp
+.Nm Telnetd
+operates by allocating a pseudo-terminal device (see
+.Xr pty 4 )
+for a client, then creating a login process which has
+the slave side of the pseudo-terminal as 
+.Dv stdin ,
+.Dv stdout
+and
+.Dv stderr .
+.Nm Telnetd
+manipulates the master side of the pseudo-terminal,
+implementing the
+.Tn TELNET
+protocol and passing characters
+between the remote client and the login process.
+.Pp
+When a
+.Tn TELNET
+session is started up, 
+.Nm telnetd
+sends
+.Tn TELNET
+options to the client side indicating
+a willingness to do the
+following
+.Tn TELNET
+options, which are described in more detail below:
+.Bd -literal -offset indent
+DO AUTHENTICATION
+WILL ENCRYPT
+DO TERMINAL TYPE
+DO TSPEED
+DO XDISPLOC
+DO NEW-ENVIRON
+DO ENVIRON
+WILL SUPPRESS GO AHEAD
+DO ECHO
+DO LINEMODE
+DO NAWS
+WILL STATUS
+DO LFLOW
+DO TIMING-MARK
+.Ed
+.Pp
+The pseudo-terminal allocated to the client is configured
+to operate in \*(lqcooked\*(rq mode, and with
+.Dv XTABS and
+.Dv CRMOD
+enabled (see
+.Xr tty 4 ) .
+.Pp
+.Nm Telnetd
+has support for enabling locally the following
+.Tn TELNET
+options:
+.Bl -tag -width "DO AUTHENTICATION"
+.It "WILL ECHO"
+When the
+.Dv LINEMODE
+option is enabled, a
+.Dv WILL ECHO
+or
+.Dv WONT ECHO
+will be sent to the client to indicate the
+current state of terminal echoing.
+When terminal echo is not desired, a
+.Dv WILL ECHO
+is sent to indicate that
+.Tn telnetd
+will take care of echoing any data that needs to be
+echoed to the terminal, and then nothing is echoed.
+When terminal echo is desired, a
+.Dv WONT ECHO
+is sent to indicate that
+.Tn telnetd
+will not be doing any terminal echoing, so the
+client should do any terminal echoing that is needed.
+.It "WILL BINARY"
+Indicates that the client is willing to send a
+8 bits of data, rather than the normal 7 bits
+of the Network Virtual Terminal.
+.It "WILL SGA"
+Indicates that it will not be sending
+.Dv IAC GA,
+go ahead, commands.
+.It "WILL STATUS"
+Indicates a willingness to send the client, upon
+request, of the current status of all
+.Tn TELNET
+options.
+.It "WILL TIMING-MARK"
+Whenever a
+.Dv DO TIMING-MARK
+command is received, it is always responded
+to with a
+.Dv WILL TIMING-MARK
+.ne 1i
+.It "WILL LOGOUT"
+When a
+.Dv DO LOGOUT
+is received, a
+.Dv WILL LOGOUT
+is sent in response, and the
+.Tn TELNET
+session is shut down.
+.It "WILL ENCRYPT"
+Only sent if
+.Nm telnetd
+is compiled with support for data encryption, and
+indicates a willingness to decrypt
+the data stream.
+.El
+.Pp
+.Nm Telnetd
+has support for enabling remotely the following
+.Tn TELNET
+options:
+.Bl -tag -width "DO AUTHENTICATION"
+.It "DO BINARY"
+Sent to indicate that
+.Tn telnetd
+is willing to receive an 8 bit data stream.
+.It "DO LFLOW"
+Requests that the client handle flow control
+characters remotely.
+.It "DO ECHO"
+This is not really supported, but is sent to identify a 4.2BSD
+.Xr telnet 1
+client, which will improperly respond with
+.Dv WILL ECHO.
+If a
+.Dv WILL ECHO
+is received, a
+.Dv DONT ECHO
+will be sent in response.
+.It "DO TERMINAL-TYPE"
+Indicates a desire to be able to request the
+name of the type of terminal that is attached
+to the client side of the connection.
+.It "DO SGA"
+Indicates that it does not need to receive
+.Dv IAC GA,
+the go ahead command.
+.It "DO NAWS"
+Requests that the client inform the server when
+the window (display) size changes.
+.It "DO TERMINAL-SPEED"
+Indicates a desire to be able to request information
+about the speed of the serial line to which
+the client is attached.
+.It "DO XDISPLOC"
+Indicates a desire to be able to request the name
+of the X windows display that is associated with
+the telnet client.
+.It "DO NEW-ENVIRON"
+Indicates a desire to be able to request environment
+variable information, as described in RFC 1572.
+.It "DO ENVIRON"
+Indicates a desire to be able to request environment
+variable information, as described in RFC 1408.
+.It "DO LINEMODE"
+Only sent if
+.Nm telnetd
+is compiled with support for linemode, and
+requests that the client do line by line processing.
+.It "DO TIMING-MARK"
+Only sent if
+.Nm telnetd
+is compiled with support for both linemode and
+kludge linemode, and the client responded with
+.Dv WONT LINEMODE.
+If the client responds with
+.Dv WILL TM,
+the it is assumed that the client supports
+kludge linemode.
+Note that the
+.Op Fl k
+option can be used to disable this.
+.It "DO AUTHENTICATION"
+Only sent if
+.Nm telnetd
+is compiled with support for authentication, and
+indicates a willingness to receive authentication
+information for automatic login.
+.It "DO ENCRYPT"
+Only sent if
+.Nm telnetd
+is compiled with support for data encryption, and
+indicates a willingness to decrypt
+the data stream.
+.Sh ENVIRONMENT
+.Sh FILES
+.Pa /etc/services
+.br
+.Pa /etc/inittab
+(UNICOS systems only)
+.br
+.Pa /etc/iptos
+(if supported)
+.br
+.Pa /usr/ucb/bftp
+(if supported)
+.Sh "SEE ALSO"
+.Xr telnet 1 ,
+.Xr login 1 ,
+.Xr bftp 1
+(if supported)
+.Sh STANDARDS
+.Bl -tag -compact -width RFC-1572
+.It Cm RFC-854
+.Tn TELNET
+PROTOCOL SPECIFICATION
+.It Cm RFC-855
+TELNET OPTION SPECIFICATIONS
+.It Cm RFC-856
+TELNET BINARY TRANSMISSION
+.It Cm RFC-857
+TELNET ECHO OPTION
+.It Cm RFC-858
+TELNET SUPPRESS GO AHEAD OPTION
+.It Cm RFC-859
+TELNET STATUS OPTION
+.It Cm RFC-860
+TELNET TIMING MARK OPTION
+.It Cm RFC-861
+TELNET EXTENDED OPTIONS - LIST OPTION
+.It Cm RFC-885
+TELNET END OF RECORD OPTION
+.It Cm RFC-1073
+Telnet Window Size Option
+.It Cm RFC-1079
+Telnet Terminal Speed Option
+.It Cm RFC-1091
+Telnet Terminal-Type Option
+.It Cm RFC-1096
+Telnet X Display Location Option
+.It Cm RFC-1123
+Requirements for Internet Hosts -- Application and Support
+.It Cm RFC-1184
+Telnet Linemode Option
+.It Cm RFC-1372
+Telnet Remote Flow Control Option
+.It Cm RFC-1416
+Telnet Authentication Option
+.It Cm RFC-1411
+Telnet Authentication: Kerberos Version 4
+.It Cm RFC-1412
+Telnet Authentication: SPX
+.It Cm RFC-1571
+Telnet Environment Option Interoperability Issues
+.It Cm RFC-1572
+Telnet Environment Option
+.Sh BUGS
+Some
+.Tn TELNET
+commands are only partially implemented.
+.Pp
+Because of bugs in the original 4.2 BSD
+.Xr telnet 1 ,
+.Nm telnetd
+performs some dubious protocol exchanges to try to discover if the remote
+client is, in fact, a 4.2 BSD
+.Xr telnet 1 .
+.Pp
+Binary mode
+has no common interpretation except between similar operating systems
+(Unix in this case).
+.Pp
+The terminal type name received from the remote client is converted to
+lower case.
+.Pp
+.Nm Telnetd
+never sends
+.Tn TELNET
+.Dv IAC GA
+(go ahead) commands.
diff --git a/telnetd.tproj/telnetd.c b/telnetd.tproj/telnetd.c
new file mode 100644
index 0000000..01943a4
--- /dev/null
+++ b/telnetd.tproj/telnetd.c
@@ -0,0 +1,1640 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)telnetd.c	8.4 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#include "telnetd.h"
+#include "pathnames.h"
+
+#if	defined(_SC_CRAY_SECURE_SYS) && !defined(SCM_SECURITY)
+/*
+ * UNICOS 6.0/6.1 do not have SCM_SECURITY defined, so we can
+ * use it to tell us to turn off all the socket security code,
+ * since that is only used in UNICOS 7.0 and later.
+ */
+# undef _SC_CRAY_SECURE_SYS
+#endif
+
+#if	defined(_SC_CRAY_SECURE_SYS)
+#include <sys/sysv.h>
+#include <sys/secdev.h>
+# ifdef SO_SEC_MULTI		/* 8.0 code */
+#include <sys/secparm.h>
+#include <sys/usrv.h>
+# endif /* SO_SEC_MULTI */
+int	secflag;
+char	tty_dev[16];
+struct	secdev dv;
+struct	sysv sysv;
+# ifdef SO_SEC_MULTI		/* 8.0 code */
+struct	socksec ss;
+# else /* SO_SEC_MULTI */	/* 7.0 code */
+struct	socket_security ss;
+# endif /* SO_SEC_MULTI */
+#endif	/* _SC_CRAY_SECURE_SYS */
+
+#if	defined(AUTHENTICATION)
+#include <libtelnet/auth.h>
+int	auth_level = 0;
+#endif
+#if	defined(SecurID)
+int	require_SecurID = 0;
+#endif
+
+extern	int utmp_len;
+int	registerd_host_only = 0;
+
+#ifdef	STREAMSPTY
+# include <stropts.h>
+# include <termio.h>
+/* make sure we don't get the bsd version */
+# include "/usr/include/sys/tty.h"
+# include <sys/ptyvar.h>
+
+/*
+ * Because of the way ptyibuf is used with streams messages, we need
+ * ptyibuf+1 to be on a full-word boundary.  The following wierdness
+ * is simply to make that happen.
+ */
+long	ptyibufbuf[BUFSIZ/sizeof(long)+1];
+char	*ptyibuf = ((char *)&ptyibufbuf[1])-1;
+char	*ptyip = ((char *)&ptyibufbuf[1])-1;
+char	ptyibuf2[BUFSIZ];
+unsigned char ctlbuf[BUFSIZ];
+struct	strbuf strbufc, strbufd;
+
+int readstream();
+
+#else	/* ! STREAMPTY */
+
+/*
+ * I/O data buffers,
+ * pointers, and counters.
+ */
+char	ptyibuf[BUFSIZ], *ptyip = ptyibuf;
+char	ptyibuf2[BUFSIZ];
+
+#endif /* ! STREAMPTY */
+
+int	hostinfo = 1;			/* do we print login banner? */
+
+#ifdef	CRAY
+extern int      newmap; /* nonzero if \n maps to ^M^J */
+int	lowpty = 0, highpty;	/* low, high pty numbers */
+#endif /* CRAY */
+
+int debug = 0;
+int keepalive = 1;
+char *progname;
+
+extern void usage P((void));
+void doit(struct sockaddr_in *);
+int terminaltypeok(char *);
+void startslave(char *, int, char *);
+
+
+/*
+ * The string to pass to getopt().  We do it this way so
+ * that only the actual options that we support will be
+ * passed off to getopt().
+ */
+char valid_opts[] = {
+	'd', ':', 'h', 'k', 'n', 'S', ':', 'u', ':', 'U',
+#ifdef	AUTHENTICATION
+	'a', ':', 'X', ':',
+#endif
+#ifdef BFTPDAEMON
+	'B',
+#endif
+#ifdef DIAGNOSTICS
+	'D', ':',
+#endif
+#ifdef	ENCRYPTION
+	'e', ':',
+#endif
+#if	defined(CRAY) && defined(NEWINIT)
+	'I', ':',
+#endif
+#ifdef	LINEMODE
+	'l',
+#endif
+#ifdef CRAY
+	'r', ':',
+#endif
+#ifdef	SecurID
+	's',
+#endif
+	'\0'
+};
+
+int
+main(argc, argv)
+	char *argv[];
+{
+	struct sockaddr_in from;
+	int on = 1, fromlen;
+	register int ch;
+	extern char *optarg;
+	extern int optind;
+#if	defined(IPPROTO_IP) && defined(IP_TOS)
+	int tos = -1;
+#endif
+
+	pfrontp = pbackp = ptyobuf;
+	netip = netibuf;
+	nfrontp = nbackp = netobuf;
+#ifdef	ENCRYPTION
+	nclearto = 0;
+#endif	/* ENCRYPTION */
+
+	progname = *argv;
+
+#ifdef CRAY
+	/*
+	 * Get number of pty's before trying to process options,
+	 * which may include changing pty range.
+	 */
+	highpty = getnpty();
+#endif /* CRAY */
+
+	while ((ch = getopt(argc, argv, valid_opts)) != EOF) {
+		switch(ch) {
+
+#ifdef	AUTHENTICATION
+		case 'a':
+			/*
+			 * Check for required authentication level
+			 */
+			if (strcmp(optarg, "debug") == 0) {
+				extern int auth_debug_mode;
+				auth_debug_mode = 1;
+			} else if (strcasecmp(optarg, "none") == 0) {
+				auth_level = 0;
+			} else if (strcasecmp(optarg, "other") == 0) {
+				auth_level = AUTH_OTHER;
+			} else if (strcasecmp(optarg, "user") == 0) {
+				auth_level = AUTH_USER;
+			} else if (strcasecmp(optarg, "valid") == 0) {
+				auth_level = AUTH_VALID;
+			} else if (strcasecmp(optarg, "off") == 0) {
+				/*
+				 * This hack turns off authentication
+				 */
+				auth_level = -1;
+			} else {
+				fprintf(stderr,
+			    "telnetd: unknown authorization level for -a\n");
+			}
+			break;
+#endif	/* AUTHENTICATION */
+
+#ifdef BFTPDAEMON
+		case 'B':
+			bftpd++;
+			break;
+#endif /* BFTPDAEMON */
+
+		case 'd':
+			if (strcmp(optarg, "ebug") == 0) {
+				debug++;
+				break;
+			}
+			usage();
+			/* NOTREACHED */
+			break;
+
+#ifdef DIAGNOSTICS
+		case 'D':
+			/*
+			 * Check for desired diagnostics capabilities.
+			 */
+			if (!strcmp(optarg, "report")) {
+				diagnostic |= TD_REPORT|TD_OPTIONS;
+			} else if (!strcmp(optarg, "exercise")) {
+				diagnostic |= TD_EXERCISE;
+			} else if (!strcmp(optarg, "netdata")) {
+				diagnostic |= TD_NETDATA;
+			} else if (!strcmp(optarg, "ptydata")) {
+				diagnostic |= TD_PTYDATA;
+			} else if (!strcmp(optarg, "options")) {
+				diagnostic |= TD_OPTIONS;
+			} else {
+				usage();
+				/* NOT REACHED */
+			}
+			break;
+#endif /* DIAGNOSTICS */
+
+#ifdef	ENCRYPTION
+		case 'e':
+			if (strcmp(optarg, "debug") == 0) {
+				extern int encrypt_debug_mode;
+				encrypt_debug_mode = 1;
+				break;
+			}
+			usage();
+			/* NOTREACHED */
+			break;
+#endif	/* ENCRYPTION */
+
+		case 'h':
+			hostinfo = 0;
+			break;
+
+#if	defined(CRAY) && defined(NEWINIT)
+		case 'I':
+		    {
+			extern char *gen_id;
+			gen_id = optarg;
+			break;
+		    }
+#endif	/* defined(CRAY) && defined(NEWINIT) */
+
+#ifdef	LINEMODE
+		case 'l':
+			alwayslinemode = 1;
+			break;
+#endif	/* LINEMODE */
+
+		case 'k':
+#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
+			lmodetype = NO_AUTOKLUDGE;
+#else
+			/* ignore -k option if built without kludge linemode */
+#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
+			break;
+
+		case 'n':
+			keepalive = 0;
+			break;
+
+#ifdef CRAY
+		case 'r':
+		    {
+			char *strchr();
+			char *c;
+
+			/*
+			 * Allow the specification of alterations
+			 * to the pty search range.  It is legal to
+			 * specify only one, and not change the
+			 * other from its default.
+			 */
+			c = strchr(optarg, '-');
+			if (c) {
+				*c++ = '\0';
+				highpty = atoi(c);
+			}
+			if (*optarg != '\0')
+				lowpty = atoi(optarg);
+			if ((lowpty > highpty) || (lowpty < 0) ||
+							(highpty > 32767)) {
+				usage();
+				/* NOT REACHED */
+			}
+			break;
+		    }
+#endif	/* CRAY */
+
+#ifdef	SecurID
+		case 's':
+			/* SecurID required */
+			require_SecurID = 1;
+			break;
+#endif	/* SecurID */
+		case 'S':
+#ifdef	HAS_GETTOS
+			if ((tos = parsetos(optarg, "tcp")) < 0)
+				fprintf(stderr, "%s%s%s\n",
+					"telnetd: Bad TOS argument '", optarg,
+					"'; will try to use default TOS");
+#else
+			fprintf(stderr, "%s%s\n", "TOS option unavailable; ",
+						"-S flag not supported\n");
+#endif
+			break;
+
+		case 'u':
+			utmp_len = atoi(optarg);
+			break;
+
+		case 'U':
+			registerd_host_only = 1;
+			break;
+
+#ifdef	AUTHENTICATION
+		case 'X':
+			/*
+			 * Check for invalid authentication types
+			 */
+			auth_disable_name(optarg);
+			break;
+#endif	/* AUTHENTICATION */
+
+		default:
+			fprintf(stderr, "telnetd: %c: unknown option\n", ch);
+			/* FALLTHROUGH */
+		case '?':
+			usage();
+			/* NOTREACHED */
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (debug) {
+	    int s, ns, foo;
+	    struct servent *sp;
+	    static struct sockaddr_in sin = { AF_INET };
+
+	    if (argc > 1) {
+		usage();
+		/* NOT REACHED */
+	    } else if (argc == 1) {
+		    if (sp = getservbyname(*argv, "tcp")) {
+			sin.sin_port = sp->s_port;
+		    } else {
+			sin.sin_port = atoi(*argv);
+			if ((int)sin.sin_port <= 0) {
+			    fprintf(stderr, "telnetd: %s: bad port #\n", *argv);
+			    usage();
+			    /* NOT REACHED */
+			}
+			sin.sin_port = htons((u_short)sin.sin_port);
+		   }
+	    } else {
+		sp = getservbyname("telnet", "tcp");
+		if (sp == 0) {
+		    fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");
+		    exit(1);
+		}
+		sin.sin_port = sp->s_port;
+	    }
+
+	    s = socket(AF_INET, SOCK_STREAM, 0);
+	    if (s < 0) {
+		    perror("telnetd: socket");;
+		    exit(1);
+	    }
+	    (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+				(char *)&on, sizeof(on));
+	    if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) {
+		perror("bind");
+		exit(1);
+	    }
+	    if (listen(s, 1) < 0) {
+		perror("listen");
+		exit(1);
+	    }
+	    foo = sizeof sin;
+	    ns = accept(s, (struct sockaddr *)&sin, &foo);
+	    if (ns < 0) {
+		perror("accept");
+		exit(1);
+	    }
+	    (void) dup2(ns, 0);
+	    (void) close(ns);
+	    (void) close(s);
+#ifdef convex
+	} else if (argc == 1) {
+		; /* VOID*/		/* Just ignore the host/port name */
+#endif
+	} else if (argc > 0) {
+		usage();
+		/* NOT REACHED */
+	}
+
+#if	defined(_SC_CRAY_SECURE_SYS)
+	secflag = sysconf(_SC_CRAY_SECURE_SYS);
+
+	/*
+	 *	Get socket's security label
+	 */
+	if (secflag)  {
+		int szss = sizeof(ss);
+#ifdef SO_SEC_MULTI			/* 8.0 code */
+		int sock_multi;
+		int szi = sizeof(int);
+#endif /* SO_SEC_MULTI */
+
+		memset((char *)&dv, 0, sizeof(dv));
+
+		if (getsysv(&sysv, sizeof(struct sysv)) != 0) {
+			perror("getsysv");
+			exit(1);
+		}
+
+		/*
+		 *	Get socket security label and set device values
+		 *	   {security label to be set on ttyp device}
+		 */
+#ifdef SO_SEC_MULTI			/* 8.0 code */
+		if ((getsockopt(0, SOL_SOCKET, SO_SECURITY,
+			       (char *)&ss, &szss) < 0) ||
+		    (getsockopt(0, SOL_SOCKET, SO_SEC_MULTI,
+				(char *)&sock_multi, &szi) < 0)) {
+			perror("getsockopt");
+			exit(1);
+		} else {
+			dv.dv_actlvl = ss.ss_actlabel.lt_level;
+			dv.dv_actcmp = ss.ss_actlabel.lt_compart;
+			if (!sock_multi) {
+				dv.dv_minlvl = dv.dv_maxlvl = dv.dv_actlvl;
+				dv.dv_valcmp = dv.dv_actcmp;
+			} else {
+				dv.dv_minlvl = ss.ss_minlabel.lt_level;
+				dv.dv_maxlvl = ss.ss_maxlabel.lt_level;
+				dv.dv_valcmp = ss.ss_maxlabel.lt_compart;
+			}
+			dv.dv_devflg = 0;
+		}
+#else /* SO_SEC_MULTI */		/* 7.0 code */
+		if (getsockopt(0, SOL_SOCKET, SO_SECURITY,
+				(char *)&ss, &szss) >= 0) {
+			dv.dv_actlvl = ss.ss_slevel;
+			dv.dv_actcmp = ss.ss_compart;
+			dv.dv_minlvl = ss.ss_minlvl;
+			dv.dv_maxlvl = ss.ss_maxlvl;
+			dv.dv_valcmp = ss.ss_maxcmp;
+		}
+#endif /* SO_SEC_MULTI */
+	}
+#endif	/* _SC_CRAY_SECURE_SYS */
+
+	openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
+	fromlen = sizeof (from);
+	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
+		fprintf(stderr, "%s: ", progname);
+		perror("getpeername");
+		_exit(1);
+	}
+	if (keepalive &&
+	    setsockopt(0, SOL_SOCKET, SO_KEEPALIVE,
+			(char *)&on, sizeof (on)) < 0) {
+		syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
+	}
+
+#if	defined(IPPROTO_IP) && defined(IP_TOS)
+	{
+# if	defined(HAS_GETTOS)
+		struct tosent *tp;
+		if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
+			tos = tp->t_tos;
+# endif
+		if (tos < 0)
+			tos = 020;	/* Low Delay bit */
+		if (tos
+		   && (setsockopt(0, IPPROTO_IP, IP_TOS,
+				  (char *)&tos, sizeof(tos)) < 0)
+		   && (errno != ENOPROTOOPT) )
+			syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
+	}
+#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */
+	net = 0;
+	doit(&from);
+	/* NOTREACHED */
+	exit(0);
+}  /* end of main */
+
+	void
+usage()
+{
+	fprintf(stderr, "Usage: telnetd");
+#ifdef	AUTHENTICATION
+	fprintf(stderr, " [-a (debug|other|user|valid|off|none)]\n\t");
+#endif
+#ifdef BFTPDAEMON
+	fprintf(stderr, " [-B]");
+#endif
+	fprintf(stderr, " [-debug]");
+#ifdef DIAGNOSTICS
+	fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t");
+#endif
+#ifdef	AUTHENTICATION
+	fprintf(stderr, " [-edebug]");
+#endif
+	fprintf(stderr, " [-h]");
+#if	defined(CRAY) && defined(NEWINIT)
+	fprintf(stderr, " [-Iinitid]");
+#endif
+#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
+	fprintf(stderr, " [-k]");
+#endif
+#ifdef LINEMODE
+	fprintf(stderr, " [-l]");
+#endif
+	fprintf(stderr, " [-n]");
+#ifdef	CRAY
+	fprintf(stderr, " [-r[lowpty]-[highpty]]");
+#endif
+	fprintf(stderr, "\n\t");
+#ifdef	SecurID
+	fprintf(stderr, " [-s]");
+#endif
+#ifdef	HAS_GETTOS
+	fprintf(stderr, " [-S tos]");
+#endif
+#ifdef	AUTHENTICATION
+	fprintf(stderr, " [-X auth-type]");
+#endif
+	fprintf(stderr, " [-u utmp_hostname_length] [-U]");
+	fprintf(stderr, " [port]\n");
+	exit(1);
+}
+
+/*
+ * getterminaltype
+ *
+ *	Ask the other end to send along its terminal type and speed.
+ * Output is the variable terminaltype filled in.
+ */
+static unsigned char ttytype_sbbuf[] = {
+	IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE
+};
+
+    int
+getterminaltype(name)
+    char *name;
+{
+    int retval = -1;
+    void _gettermname();
+
+    settimer(baseline);
+#if	defined(AUTHENTICATION)
+    /*
+     * Handle the Authentication option before we do anything else.
+     */
+    send_do(TELOPT_AUTHENTICATION, 1);
+    while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
+	ttloop();
+    if (his_state_is_will(TELOPT_AUTHENTICATION)) {
+	retval = auth_wait(name);
+    }
+#endif
+
+#ifdef	ENCRYPTION
+    send_will(TELOPT_ENCRYPT, 1);
+#endif	/* ENCRYPTION */
+    send_do(TELOPT_TTYPE, 1);
+    send_do(TELOPT_TSPEED, 1);
+    send_do(TELOPT_XDISPLOC, 1);
+    send_do(TELOPT_NEW_ENVIRON, 1);
+    send_do(TELOPT_OLD_ENVIRON, 1);
+    while (
+#ifdef	ENCRYPTION
+	   his_do_dont_is_changing(TELOPT_ENCRYPT) ||
+#endif	/* ENCRYPTION */
+	   his_will_wont_is_changing(TELOPT_TTYPE) ||
+	   his_will_wont_is_changing(TELOPT_TSPEED) ||
+	   his_will_wont_is_changing(TELOPT_XDISPLOC) ||
+	   his_will_wont_is_changing(TELOPT_NEW_ENVIRON) ||
+	   his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) {
+	ttloop();
+    }
+#ifdef	ENCRYPTION
+    /*
+     * Wait for the negotiation of what type of encryption we can
+     * send with.  If autoencrypt is not set, this will just return.
+     */
+    if (his_state_is_will(TELOPT_ENCRYPT)) {
+	encrypt_wait();
+    }
+#endif	/* ENCRYPTION */
+    if (his_state_is_will(TELOPT_TSPEED)) {
+	static unsigned char sb[] =
+			{ IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
+
+	memmove(nfrontp, sb, sizeof sb);
+	nfrontp += sizeof sb;
+	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
+    }
+    if (his_state_is_will(TELOPT_XDISPLOC)) {
+	static unsigned char sb[] =
+			{ IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
+
+	memmove(nfrontp, sb, sizeof sb);
+	nfrontp += sizeof sb;
+	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
+    }
+    if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
+	static unsigned char sb[] =
+			{ IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE };
+
+	memmove(nfrontp, sb, sizeof sb);
+	nfrontp += sizeof sb;
+	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
+    }
+    else if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
+	static unsigned char sb[] =
+			{ IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE };
+
+	memmove(nfrontp, sb, sizeof sb);
+	nfrontp += sizeof sb;
+	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
+    }
+    if (his_state_is_will(TELOPT_TTYPE)) {
+
+	memmove(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf);
+	nfrontp += sizeof ttytype_sbbuf;
+	DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
+					sizeof ttytype_sbbuf - 2););
+    }
+    if (his_state_is_will(TELOPT_TSPEED)) {
+	while (sequenceIs(tspeedsubopt, baseline))
+	    ttloop();
+    }
+    if (his_state_is_will(TELOPT_XDISPLOC)) {
+	while (sequenceIs(xdisplocsubopt, baseline))
+	    ttloop();
+    }
+    if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
+	while (sequenceIs(environsubopt, baseline))
+	    ttloop();
+    }
+    if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
+	while (sequenceIs(oenvironsubopt, baseline))
+	    ttloop();
+    }
+    if (his_state_is_will(TELOPT_TTYPE)) {
+	char first[256], last[256];
+
+	while (sequenceIs(ttypesubopt, baseline))
+	    ttloop();
+
+	/*
+	 * If the other side has already disabled the option, then
+	 * we have to just go with what we (might) have already gotten.
+	 */
+	if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) {
+	    (void) strncpy(first, terminaltype, sizeof(first));
+	    for(;;) {
+		/*
+		 * Save the unknown name, and request the next name.
+		 */
+		(void) strncpy(last, terminaltype, sizeof(last));
+		_gettermname();
+		if (terminaltypeok(terminaltype))
+		    break;
+		if ((strncmp(last, terminaltype, sizeof(last)) == 0) ||
+		    his_state_is_wont(TELOPT_TTYPE)) {
+		    /*
+		     * We've hit the end.  If this is the same as
+		     * the first name, just go with it.
+		     */
+		    if (strncmp(first, terminaltype, sizeof(first)) == 0)
+			break;
+		    /*
+		     * Get the terminal name one more time, so that
+		     * RFC1091 compliant telnets will cycle back to
+		     * the start of the list.
+		     */
+		     _gettermname();
+		    if (strncmp(first, terminaltype, sizeof(first)) != 0)
+			(void) strncpy(terminaltype, first, sizeof(first));
+		    break;
+		}
+	    }
+	}
+    }
+    return(retval);
+}  /* end of getterminaltype */
+
+    void
+_gettermname()
+{
+    /*
+     * If the client turned off the option,
+     * we can't send another request, so we
+     * just return.
+     */
+    if (his_state_is_wont(TELOPT_TTYPE))
+	return;
+    settimer(baseline);
+    memmove(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf);
+    nfrontp += sizeof ttytype_sbbuf;
+    DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
+					sizeof ttytype_sbbuf - 2););
+    while (sequenceIs(ttypesubopt, baseline))
+	ttloop();
+}
+
+    int
+terminaltypeok(s)
+    char *s;
+{
+    char buf[1024];
+
+    if (terminaltype == NULL)
+	return(1);
+
+    /*
+     * tgetent() will return 1 if the type is known, and
+     * 0 if it is not known.  If it returns -1, it couldn't
+     * open the database.  But if we can't open the database,
+     * it won't help to say we failed, because we won't be
+     * able to verify anything else.  So, we treat -1 like 1.
+     */
+    if (tgetent(buf, s) == 0)
+	return(0);
+    return(1);
+}
+
+#ifndef	MAXHOSTNAMELEN
+#define	MAXHOSTNAMELEN 64
+#endif	/* MAXHOSTNAMELEN */
+
+char *hostname;
+char host_name[MAXHOSTNAMELEN];
+char remote_host_name[MAXHOSTNAMELEN];
+
+#ifndef	convex
+extern void telnet P((int, int));
+#else
+extern void telnet P((int, int, char *));
+#endif
+
+/*
+ * Get a pty, scan input lines.
+ */
+void
+doit(who)
+	struct sockaddr_in *who;
+{
+	char *host = NULL, *inet_ntoa();
+	struct hostent *hp;
+	int level;
+	int ptynum;
+	char user_name[256];
+
+	/*
+	 * Find an available pty to use.
+	 */
+#ifndef	convex
+	pty = getpty(&ptynum);
+	if (pty < 0)
+		fatal(net, "All network ports in use");
+#else
+	for (;;) {
+		char *lp;
+		extern char *line, *getpty();
+
+		if ((lp = getpty()) == NULL)
+			fatal(net, "Out of ptys");
+
+		if ((pty = open(lp, O_RDWR)) >= 0) {
+			strncpy(line,lp, sizeof(line)-1);
+			line[sizeof(line)-1] = '\0';
+			line[5] = 't';
+			break;
+		}
+	}
+#endif
+
+#if	defined(_SC_CRAY_SECURE_SYS)
+	/*
+	 *	set ttyp line security label
+	 */
+	if (secflag) {
+		char slave_dev[16];
+
+		sprintf(tty_dev, "/dev/pty/%03d", ptynum);
+		if (setdevs(tty_dev, &dv) < 0)
+		 	fatal(net, "cannot set pty security");
+		sprintf(slave_dev, "/dev/ttyp%03d", ptynum);
+		if (setdevs(slave_dev, &dv) < 0)
+		 	fatal(net, "cannot set tty security");
+	}
+#endif	/* _SC_CRAY_SECURE_SYS */
+
+	/* get name of connected client */
+	hp = gethostbyaddr((char *)&who->sin_addr, sizeof (struct in_addr),
+		who->sin_family);
+
+	if (hp == NULL && registerd_host_only) {
+		fatal(net, "Couldn't resolve your address into a host name.\r\n\
+	 Please contact your net administrator");
+	} else if (hp &&
+	    (strlen(hp->h_name) <= (unsigned int)((utmp_len < 0) ? -utmp_len
+								 : utmp_len))) {
+		host = hp->h_name;
+	} else {
+		host = inet_ntoa(who->sin_addr);
+	}
+	/*
+	 * We must make a copy because Kerberos is probably going
+	 * to also do a gethost* and overwrite the static data...
+	 */
+	strncpy(remote_host_name, host, sizeof(remote_host_name)-1);
+	remote_host_name[sizeof(remote_host_name)-1] = 0;
+	host = remote_host_name;
+
+	(void) gethostname(host_name, sizeof (host_name));
+	hostname = host_name;
+
+#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
+	auth_encrypt_init(hostname, host, "TELNETD", 1);
+#endif
+
+	init_env();
+	/*
+	 * get terminal type.
+	 */
+	*user_name = 0;
+	level = getterminaltype(user_name);
+	setenv("TERM", terminaltype ? terminaltype : "network", 1);
+
+	/*
+	 * Start up the login process on the slave side of the terminal
+	 */
+#ifndef	convex
+	startslave(host, level, user_name);
+
+#if	defined(_SC_CRAY_SECURE_SYS)
+	if (secflag) {
+		if (setulvl(dv.dv_actlvl) < 0)
+			fatal(net,"cannot setulvl()");
+		if (setucmp(dv.dv_actcmp) < 0)
+			fatal(net, "cannot setucmp()");
+	}
+#endif	/* _SC_CRAY_SECURE_SYS */
+
+	telnet(net, pty);  /* begin server processing */
+#else
+	telnet(net, pty, host);
+#endif
+	/*NOTREACHED*/
+}  /* end of doit */
+
+#if	defined(CRAY2) && defined(UNICOS5) && defined(UNICOS50)
+	int
+Xterm_output(ibufp, obuf, icountp, ocount)
+	char **ibufp, *obuf;
+	int *icountp, ocount;
+{
+	int ret;
+	ret = term_output(*ibufp, obuf, *icountp, ocount);
+	*ibufp += *icountp;
+	*icountp = 0;
+	return(ret);
+}
+#define	term_output	Xterm_output
+#endif	/* defined(CRAY2) && defined(UNICOS5) && defined(UNICOS50) */
+
+/*
+ * Main loop.  Select from pty and network, and
+ * hand data to telnet receiver finite state machine.
+ */
+	void
+#ifndef	convex
+telnet(f, p)
+#else
+telnet(f, p, host)
+#endif
+	int f, p;
+#ifdef convex
+	char *host;
+#endif
+{
+	int on = 1;
+#define	TABBUFSIZ	512
+	char	defent[TABBUFSIZ];
+	char	defstrs[TABBUFSIZ];
+#undef	TABBUFSIZ
+	char *HE;
+	char *HN;
+	char *IM;
+	void netflush();
+	int nfd;
+
+	/*
+	 * Initialize the slc mapping table.
+	 */
+	get_slc_defaults();
+
+	/*
+	 * Do some tests where it is desireable to wait for a response.
+	 * Rather than doing them slowly, one at a time, do them all
+	 * at once.
+	 */
+	if (my_state_is_wont(TELOPT_SGA))
+		send_will(TELOPT_SGA, 1);
+	/*
+	 * Is the client side a 4.2 (NOT 4.3) system?  We need to know this
+	 * because 4.2 clients are unable to deal with TCP urgent data.
+	 *
+	 * To find out, we send out a "DO ECHO".  If the remote system
+	 * answers "WILL ECHO" it is probably a 4.2 client, and we note
+	 * that fact ("WILL ECHO" ==> that the client will echo what
+	 * WE, the server, sends it; it does NOT mean that the client will
+	 * echo the terminal input).
+	 */
+	send_do(TELOPT_ECHO, 1);
+
+#ifdef	LINEMODE
+	if (his_state_is_wont(TELOPT_LINEMODE)) {
+		/* Query the peer for linemode support by trying to negotiate
+		 * the linemode option.
+		 */
+		linemode = 0;
+		editmode = 0;
+		send_do(TELOPT_LINEMODE, 1);  /* send do linemode */
+	}
+#endif	/* LINEMODE */
+
+	/*
+	 * Send along a couple of other options that we wish to negotiate.
+	 */
+	send_do(TELOPT_NAWS, 1);
+	send_will(TELOPT_STATUS, 1);
+	flowmode = 1;		/* default flow control state */
+	restartany = -1;	/* uninitialized... */
+	send_do(TELOPT_LFLOW, 1);
+
+	/*
+	 * Spin, waiting for a response from the DO ECHO.  However,
+	 * some REALLY DUMB telnets out there might not respond
+	 * to the DO ECHO.  So, we spin looking for NAWS, (most dumb
+	 * telnets so far seem to respond with WONT for a DO that
+	 * they don't understand...) because by the time we get the
+	 * response, it will already have processed the DO ECHO.
+	 * Kludge upon kludge.
+	 */
+	while (his_will_wont_is_changing(TELOPT_NAWS))
+		ttloop();
+
+	/*
+	 * But...
+	 * The client might have sent a WILL NAWS as part of its
+	 * startup code; if so, we'll be here before we get the
+	 * response to the DO ECHO.  We'll make the assumption
+	 * that any implementation that understands about NAWS
+	 * is a modern enough implementation that it will respond
+	 * to our DO ECHO request; hence we'll do another spin
+	 * waiting for the ECHO option to settle down, which is
+	 * what we wanted to do in the first place...
+	 */
+	if (his_want_state_is_will(TELOPT_ECHO) &&
+	    his_state_is_will(TELOPT_NAWS)) {
+		while (his_will_wont_is_changing(TELOPT_ECHO))
+			ttloop();
+	}
+	/*
+	 * On the off chance that the telnet client is broken and does not
+	 * respond to the DO ECHO we sent, (after all, we did send the
+	 * DO NAWS negotiation after the DO ECHO, and we won't get here
+	 * until a response to the DO NAWS comes back) simulate the
+	 * receipt of a will echo.  This will also send a WONT ECHO
+	 * to the client, since we assume that the client failed to
+	 * respond because it believes that it is already in DO ECHO
+	 * mode, which we do not want.
+	 */
+	if (his_want_state_is_will(TELOPT_ECHO)) {
+		DIAG(TD_OPTIONS,
+			{sprintf(nfrontp, "td: simulating recv\r\n");
+			 nfrontp += strlen(nfrontp);});
+		willoption(TELOPT_ECHO);
+	}
+
+	/*
+	 * Finally, to clean things up, we turn on our echo.  This
+	 * will break stupid 4.2 telnets out of local terminal echo.
+	 */
+
+	if (my_state_is_wont(TELOPT_ECHO))
+		send_will(TELOPT_ECHO, 1);
+
+#ifndef	STREAMSPTY
+	/*
+	 * Turn on packet mode
+	 */
+	(void) ioctl(p, TIOCPKT, (char *)&on);
+#endif
+
+#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
+	/*
+	 * Continuing line mode support.  If client does not support
+	 * real linemode, attempt to negotiate kludge linemode by sending
+	 * the do timing mark sequence.
+	 */
+	if (lmodetype < REAL_LINEMODE)
+		send_do(TELOPT_TM, 1);
+#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
+
+	/*
+	 * Call telrcv() once to pick up anything received during
+	 * terminal type negotiation, 4.2/4.3 determination, and
+	 * linemode negotiation.
+	 */
+	telrcv();
+
+	(void) ioctl(f, FIONBIO, (char *)&on);
+	(void) ioctl(p, FIONBIO, (char *)&on);
+#if	defined(CRAY2) && defined(UNICOS5)
+	init_termdriver(f, p, interrupt, sendbrk);
+#endif
+
+#if	defined(SO_OOBINLINE)
+	(void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE,
+				(char *)&on, sizeof on);
+#endif	/* defined(SO_OOBINLINE) */
+
+#ifdef	SIGTSTP
+	(void) signal(SIGTSTP, SIG_IGN);
+#endif
+#ifdef	SIGTTOU
+	/*
+	 * Ignoring SIGTTOU keeps the kernel from blocking us
+	 * in ttioct() in /sys/tty.c.
+	 */
+	(void) signal(SIGTTOU, SIG_IGN);
+#endif
+
+	(void) signal(SIGCHLD, cleanup);
+
+#if	defined(CRAY2) && defined(UNICOS5)
+	/*
+	 * Cray-2 will send a signal when pty modes are changed by slave
+	 * side.  Set up signal handler now.
+	 */
+	if ((int)signal(SIGUSR1, termstat) < 0)
+		perror("signal");
+	else if (ioctl(p, TCSIGME, (char *)SIGUSR1) < 0)
+		perror("ioctl:TCSIGME");
+	/*
+	 * Make processing loop check terminal characteristics early on.
+	 */
+	termstat();
+#endif
+
+#ifdef  TIOCNOTTY
+	{
+		register int t;
+		t = open(_PATH_TTY, O_RDWR);
+		if (t >= 0) {
+			(void) ioctl(t, TIOCNOTTY, (char *)0);
+			(void) close(t);
+		}
+	}
+#endif
+
+#if	defined(CRAY) && defined(NEWINIT) && defined(TIOCSCTTY)
+	(void) setsid();
+	ioctl(p, TIOCSCTTY, 0);
+#endif
+
+	/*
+	 * Show banner that getty never gave.
+	 *
+	 * We put the banner in the pty input buffer.  This way, it
+	 * gets carriage return null processing, etc., just like all
+	 * other pty --> client data.
+	 */
+
+#if	!defined(CRAY) || !defined(NEWINIT)
+	if (getenv("USER"))
+		hostinfo = 0;
+#endif
+
+	if (getent(defent, "default") == 1) {
+		char *Getstr();
+		char *cp=defstrs;
+
+		HE = Getstr("he", &cp);
+		HN = Getstr("hn", &cp);
+		IM = Getstr("im", &cp);
+		if (HN && *HN) {
+			(void) strncpy(host_name, HN, sizeof(host_name)-1);
+			hostname[sizeof(host_name)-1] = '\0';
+		}
+		if (IM == 0)
+			IM = "";
+	} else {
+		IM = DEFAULT_IM;
+		HE = 0;
+	}
+	edithost(HE, host_name);
+	if (hostinfo && *IM)
+		putf(IM, ptyibuf2);
+
+	if (pcc)
+		(void) strncat(ptyibuf2, ptyip, pcc+1);
+	ptyip = ptyibuf2;
+	pcc = strlen(ptyip);
+#ifdef	LINEMODE
+	/*
+	 * Last check to make sure all our states are correct.
+	 */
+	init_termbuf();
+	localstat();
+#endif	/* LINEMODE */
+
+	DIAG(TD_REPORT,
+		{sprintf(nfrontp, "td: Entering processing loop\r\n");
+		 nfrontp += strlen(nfrontp);});
+
+#ifdef	convex
+	startslave(host);
+#endif
+
+	nfd = ((f > p) ? f : p) + 1;
+	for (;;) {
+		fd_set ibits, obits, xbits;
+		register int c;
+
+		if (ncc < 0 && pcc < 0)
+			break;
+
+#if	defined(CRAY2) && defined(UNICOS5)
+		if (needtermstat)
+			_termstat();
+#endif	/* defined(CRAY2) && defined(UNICOS5) */
+		FD_ZERO(&ibits);
+		FD_ZERO(&obits);
+		FD_ZERO(&xbits);
+		/*
+		 * Never look for input if there's still
+		 * stuff in the corresponding output buffer
+		 */
+		if (nfrontp - nbackp || pcc > 0) {
+			FD_SET(f, &obits);
+		} else {
+			FD_SET(p, &ibits);
+		}
+		if (pfrontp - pbackp || ncc > 0) {
+			FD_SET(p, &obits);
+		} else {
+			FD_SET(f, &ibits);
+		}
+		if (!SYNCHing) {
+			FD_SET(f, &xbits);
+		}
+		if ((c = select(nfd, &ibits, &obits, &xbits,
+						(struct timeval *)0)) < 1) {
+			if (c == -1) {
+				if (errno == EINTR) {
+					continue;
+				}
+			}
+			sleep(5);
+			continue;
+		}
+
+		/*
+		 * Any urgent data?
+		 */
+		if (FD_ISSET(net, &xbits)) {
+		    SYNCHing = 1;
+		}
+
+		/*
+		 * Something to read from the network...
+		 */
+		if (FD_ISSET(net, &ibits)) {
+#if	!defined(SO_OOBINLINE)
+			/*
+			 * In 4.2 (and 4.3 beta) systems, the
+			 * OOB indication and data handling in the kernel
+			 * is such that if two separate TCP Urgent requests
+			 * come in, one byte of TCP data will be overlaid.
+			 * This is fatal for Telnet, but we try to live
+			 * with it.
+			 *
+			 * In addition, in 4.2 (and...), a special protocol
+			 * is needed to pick up the TCP Urgent data in
+			 * the correct sequence.
+			 *
+			 * What we do is:  if we think we are in urgent
+			 * mode, we look to see if we are "at the mark".
+			 * If we are, we do an OOB receive.  If we run
+			 * this twice, we will do the OOB receive twice,
+			 * but the second will fail, since the second
+			 * time we were "at the mark", but there wasn't
+			 * any data there (the kernel doesn't reset
+			 * "at the mark" until we do a normal read).
+			 * Once we've read the OOB data, we go ahead
+			 * and do normal reads.
+			 *
+			 * There is also another problem, which is that
+			 * since the OOB byte we read doesn't put us
+			 * out of OOB state, and since that byte is most
+			 * likely the TELNET DM (data mark), we would
+			 * stay in the TELNET SYNCH (SYNCHing) state.
+			 * So, clocks to the rescue.  If we've "just"
+			 * received a DM, then we test for the
+			 * presence of OOB data when the receive OOB
+			 * fails (and AFTER we did the normal mode read
+			 * to clear "at the mark").
+			 */
+		    if (SYNCHing) {
+			int atmark;
+
+			(void) ioctl(net, SIOCATMARK, (char *)&atmark);
+			if (atmark) {
+			    ncc = recv(net, netibuf, sizeof (netibuf), MSG_OOB);
+			    if ((ncc == -1) && (errno == EINVAL)) {
+				ncc = read(net, netibuf, sizeof (netibuf));
+				if (sequenceIs(didnetreceive, gotDM)) {
+				    SYNCHing = stilloob(net);
+				}
+			    }
+			} else {
+			    ncc = read(net, netibuf, sizeof (netibuf));
+			}
+		    } else {
+			ncc = read(net, netibuf, sizeof (netibuf));
+		    }
+		    settimer(didnetreceive);
+#else	/* !defined(SO_OOBINLINE)) */
+		    ncc = read(net, netibuf, sizeof (netibuf));
+#endif	/* !defined(SO_OOBINLINE)) */
+		    if (ncc < 0 && errno == EWOULDBLOCK)
+			ncc = 0;
+		    else {
+			if (ncc <= 0) {
+			    break;
+			}
+			netip = netibuf;
+		    }
+		    DIAG((TD_REPORT | TD_NETDATA),
+			    {sprintf(nfrontp, "td: netread %d chars\r\n", ncc);
+			     nfrontp += strlen(nfrontp);});
+		    DIAG(TD_NETDATA, printdata("nd", netip, ncc));
+		}
+
+		/*
+		 * Something to read from the pty...
+		 */
+		if (FD_ISSET(p, &ibits)) {
+#ifndef	STREAMSPTY
+			pcc = read(p, ptyibuf, BUFSIZ);
+#else
+			pcc = readstream(p, ptyibuf, BUFSIZ);
+#endif
+			/*
+			 * On some systems, if we try to read something
+			 * off the master side before the slave side is
+			 * opened, we get EIO.
+			 */
+			if (pcc < 0 && (errno == EWOULDBLOCK ||
+#ifdef	EAGAIN
+					errno == EAGAIN ||
+#endif
+					errno == EIO)) {
+				pcc = 0;
+			} else {
+				if (pcc <= 0)
+					break;
+#if	!defined(CRAY2) || !defined(UNICOS5)
+#ifdef	LINEMODE
+				/*
+				 * If ioctl from pty, pass it through net
+				 */
+				if (ptyibuf[0] & TIOCPKT_IOCTL) {
+					copy_termbuf(ptyibuf+1, pcc-1);
+					localstat();
+					pcc = 1;
+				}
+#endif	/* LINEMODE */
+				if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
+					netclear();	/* clear buffer back */
+#ifndef	NO_URGENT
+					/*
+					 * There are client telnets on some
+					 * operating systems get screwed up
+					 * royally if we send them urgent
+					 * mode data.
+					 */
+					*nfrontp++ = IAC;
+					*nfrontp++ = DM;
+					neturg = nfrontp-1; /* off by one XXX */
+					DIAG(TD_OPTIONS,
+					    printoption("td: send IAC", DM));
+
+#endif
+				}
+				if (his_state_is_will(TELOPT_LFLOW) &&
+				    (ptyibuf[0] &
+				     (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) {
+					int newflow =
+					    ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0;
+					if (newflow != flowmode) {
+						flowmode = newflow;
+						(void) sprintf(nfrontp,
+							"%c%c%c%c%c%c",
+							IAC, SB, TELOPT_LFLOW,
+							flowmode ? LFLOW_ON
+								 : LFLOW_OFF,
+							IAC, SE);
+						nfrontp += 6;
+						DIAG(TD_OPTIONS, printsub('>',
+						    (unsigned char *)nfrontp-4,
+						    4););
+					}
+				}
+				pcc--;
+				ptyip = ptyibuf+1;
+#else	/* defined(CRAY2) && defined(UNICOS5) */
+				if (!uselinemode) {
+					unpcc = pcc;
+					unptyip = ptyibuf;
+					pcc = term_output(&unptyip, ptyibuf2,
+								&unpcc, BUFSIZ);
+					ptyip = ptyibuf2;
+				} else
+					ptyip = ptyibuf;
+#endif	/* defined(CRAY2) && defined(UNICOS5) */
+			}
+		}
+
+		while (pcc > 0) {
+			if ((&netobuf[BUFSIZ] - nfrontp) < 2)
+				break;
+			c = *ptyip++ & 0377, pcc--;
+			if (c == IAC)
+				*nfrontp++ = c;
+#if	defined(CRAY2) && defined(UNICOS5)
+			else if (c == '\n' &&
+				     my_state_is_wont(TELOPT_BINARY) && newmap)
+				*nfrontp++ = '\r';
+#endif	/* defined(CRAY2) && defined(UNICOS5) */
+			*nfrontp++ = c;
+			if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) {
+				if (pcc > 0 && ((*ptyip & 0377) == '\n')) {
+					*nfrontp++ = *ptyip++ & 0377;
+					pcc--;
+				} else
+					*nfrontp++ = '\0';
+			}
+		}
+#if	defined(CRAY2) && defined(UNICOS5)
+		/*
+		 * If chars were left over from the terminal driver,
+		 * note their existence.
+		 */
+		if (!uselinemode && unpcc) {
+			pcc = unpcc;
+			unpcc = 0;
+			ptyip = unptyip;
+		}
+#endif	/* defined(CRAY2) && defined(UNICOS5) */
+
+		if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0)
+			netflush();
+		if (ncc > 0)
+			telrcv();
+		if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0)
+			ptyflush();
+	}
+	cleanup(0);
+}  /* end of telnet */
+
+#ifndef	TCSIG
+# ifdef	TIOCSIG
+#  define TCSIG TIOCSIG
+# endif
+#endif
+
+#ifdef	STREAMSPTY
+
+int flowison = -1;  /* current state of flow: -1 is unknown */
+
+int readstream(p, ibuf, bufsize)
+	int p;
+	char *ibuf;
+	int bufsize;
+{
+	int flags = 0;
+	int ret = 0;
+	struct termios *tsp;
+	struct termio *tp;
+	struct iocblk *ip;
+	char vstop, vstart;
+	int ixon;
+	int newflow;
+
+	strbufc.maxlen = BUFSIZ;
+	strbufc.buf = (char *)ctlbuf;
+	strbufd.maxlen = bufsize-1;
+	strbufd.len = 0;
+	strbufd.buf = ibuf+1;
+	ibuf[0] = 0;
+
+	ret = getmsg(p, &strbufc, &strbufd, &flags);
+	if (ret < 0)  /* error of some sort -- probably EAGAIN */
+		return(-1);
+
+	if (strbufc.len <= 0 || ctlbuf[0] == M_DATA) {
+		/* data message */
+		if (strbufd.len > 0) {			/* real data */
+			return(strbufd.len + 1);	/* count header char */
+		} else {
+			/* nothing there */
+			errno = EAGAIN;
+			return(-1);
+		}
+	}
+
+	/*
+	 * It's a control message.  Return 1, to look at the flag we set
+	 */
+
+	switch (ctlbuf[0]) {
+	case M_FLUSH:
+		if (ibuf[1] & FLUSHW)
+			ibuf[0] = TIOCPKT_FLUSHWRITE;
+		return(1);
+
+	case M_IOCTL:
+		ip = (struct iocblk *) (ibuf+1);
+
+		switch (ip->ioc_cmd) {
+		case TCSETS:
+		case TCSETSW:
+		case TCSETSF:
+			tsp = (struct termios *)
+					(ibuf+1 + sizeof(struct iocblk));
+			vstop = tsp->c_cc[VSTOP];
+			vstart = tsp->c_cc[VSTART];
+			ixon = tsp->c_iflag & IXON;
+			break;
+		case TCSETA:
+		case TCSETAW:
+		case TCSETAF:
+			tp = (struct termio *) (ibuf+1 + sizeof(struct iocblk));
+			vstop = tp->c_cc[VSTOP];
+			vstart = tp->c_cc[VSTART];
+			ixon = tp->c_iflag & IXON;
+			break;
+		default:
+			errno = EAGAIN;
+			return(-1);
+		}
+
+		newflow =  (ixon && (vstart == 021) && (vstop == 023)) ? 1 : 0;
+		if (newflow != flowison) {  /* it's a change */
+			flowison = newflow;
+			ibuf[0] = newflow ? TIOCPKT_DOSTOP : TIOCPKT_NOSTOP;
+			return(1);
+		}
+	}
+
+	/* nothing worth doing anything about */
+	errno = EAGAIN;
+	return(-1);
+}
+#endif /* STREAMSPTY */
+
+/*
+ * Send interrupt to process on other side of pty.
+ * If it is in raw mode, just write NULL;
+ * otherwise, write intr char.
+ */
+	void
+interrupt()
+{
+	ptyflush();	/* half-hearted */
+
+#if defined(STREAMSPTY) && defined(TIOCSIGNAL)
+	/* Streams PTY style ioctl to post a signal */
+	{
+		int sig = SIGINT;
+		(void) ioctl(pty, TIOCSIGNAL, &sig);
+		(void) ioctl(pty, I_FLUSH, FLUSHR);
+	}
+#else
+#ifdef	TCSIG
+	(void) ioctl(pty, TCSIG, (char *)SIGINT);
+#else	/* TCSIG */
+	init_termbuf();
+	*pfrontp++ = slctab[SLC_IP].sptr ?
+			(unsigned char)*slctab[SLC_IP].sptr : '\177';
+#endif	/* TCSIG */
+#endif
+}
+
+/*
+ * Send quit to process on other side of pty.
+ * If it is in raw mode, just write NULL;
+ * otherwise, write quit char.
+ */
+	void
+sendbrk()
+{
+	ptyflush();	/* half-hearted */
+#ifdef	TCSIG
+	(void) ioctl(pty, TCSIG, (char *)SIGQUIT);
+#else	/* TCSIG */
+	init_termbuf();
+	*pfrontp++ = slctab[SLC_ABORT].sptr ?
+			(unsigned char)*slctab[SLC_ABORT].sptr : '\034';
+#endif	/* TCSIG */
+}
+
+	void
+sendsusp()
+{
+#ifdef	SIGTSTP
+	ptyflush();	/* half-hearted */
+# ifdef	TCSIG
+	(void) ioctl(pty, TCSIG, (char *)SIGTSTP);
+# else	/* TCSIG */
+	*pfrontp++ = slctab[SLC_SUSP].sptr ?
+			(unsigned char)*slctab[SLC_SUSP].sptr : '\032';
+# endif	/* TCSIG */
+#endif	/* SIGTSTP */
+}
+
+/*
+ * When we get an AYT, if ^T is enabled, use that.  Otherwise,
+ * just send back "[Yes]".
+ */
+	void
+recv_ayt()
+{
+#if	defined(SIGINFO) && defined(TCSIG)
+	if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) {
+		(void) ioctl(pty, TCSIG, (char *)SIGINFO);
+		return;
+	}
+#endif
+	(void) strcpy(nfrontp, "\r\n[Yes]\r\n");
+	nfrontp += 9;
+}
+
+	void
+doeof()
+{
+	init_termbuf();
+
+#if	defined(LINEMODE) && defined(USE_TERMIO) && (VEOF == VMIN)
+	if (!tty_isediting()) {
+		extern char oldeofc;
+		*pfrontp++ = oldeofc;
+		return;
+	}
+#endif
+	*pfrontp++ = slctab[SLC_EOF].sptr ?
+			(unsigned char)*slctab[SLC_EOF].sptr : '\004';
+}
diff --git a/telnetd.tproj/telnetd.h b/telnetd.tproj/telnetd.h
new file mode 100644
index 0000000..56ccdcd
--- /dev/null
+++ b/telnetd.tproj/telnetd.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)telnetd.h	8.1 (Berkeley) 6/4/93
+ */
+
+
+#include "defs.h"
+#include "ext.h"
+#include <syslog.h>
+
+#ifdef	DIAGNOSTICS
+#define	DIAG(a,b)	if (diagnostic & (a)) b
+#else
+#define	DIAG(a,b)
+#endif
+
+/* other external variables */
+extern	char **environ;
+extern	int errno;
+
diff --git a/telnetd.tproj/termstat.c b/telnetd.tproj/termstat.c
new file mode 100644
index 0000000..0705dec
--- /dev/null
+++ b/telnetd.tproj/termstat.c
@@ -0,0 +1,683 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)termstat.c	8.2 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#include "telnetd.h"
+
+/*
+ * local variables
+ */
+int def_tspeed = -1, def_rspeed = -1;
+#ifdef	TIOCSWINSZ
+int def_row = 0, def_col = 0;
+#endif
+#ifdef	LINEMODE
+static int _terminit = 0;
+#endif	/* LINEMODE */
+
+#if	defined(CRAY2) && defined(UNICOS5)
+int	newmap = 1;	/* nonzero if \n maps to ^M^J */
+#endif
+
+#ifdef	LINEMODE
+/*
+ * localstat
+ *
+ * This function handles all management of linemode.
+ *
+ * Linemode allows the client to do the local editing of data
+ * and send only complete lines to the server.  Linemode state is
+ * based on the state of the pty driver.  If the pty is set for
+ * external processing, then we can use linemode.  Further, if we
+ * can use real linemode, then we can look at the edit control bits
+ * in the pty to determine what editing the client should do.
+ *
+ * Linemode support uses the following state flags to keep track of
+ * current and desired linemode state.
+ *	alwayslinemode : true if -l was specified on the telnetd
+ * 	command line.  It means to have linemode on as much as
+ *	possible.
+ *
+ * 	lmodetype: signifies whether the client can
+ *	handle real linemode, or if use of kludgeomatic linemode
+ *	is preferred.  It will be set to one of the following:
+ *		REAL_LINEMODE : use linemode option
+ *		NO_KLUDGE : don't initiate kludge linemode.
+ *		KLUDGE_LINEMODE : use kludge linemode
+ *		NO_LINEMODE : client is ignorant of linemode
+ *
+ *	linemode, uselinemode : linemode is true if linemode
+ *	is currently on, uselinemode is the state that we wish
+ *	to be in.  If another function wishes to turn linemode
+ *	on or off, it sets or clears uselinemode.
+ *
+ *	editmode, useeditmode : like linemode/uselinemode, but
+ *	these contain the edit mode states (edit and trapsig).
+ *
+ * The state variables correspond to some of the state information
+ * in the pty.
+ *	linemode:
+ *		In real linemode, this corresponds to whether the pty
+ *		expects external processing of incoming data.
+ *		In kludge linemode, this more closely corresponds to the
+ *		whether normal processing is on or not.  (ICANON in
+ *		system V, or COOKED mode in BSD.)
+ *		If the -l option was specified (alwayslinemode), then
+ *		an attempt is made to force external processing on at
+ *		all times.
+ *
+ * The following heuristics are applied to determine linemode
+ * handling within the server.
+ *	1) Early on in starting up the server, an attempt is made
+ *	   to negotiate the linemode option.  If this succeeds
+ *	   then lmodetype is set to REAL_LINEMODE and all linemode
+ *	   processing occurs in the context of the linemode option.
+ *	2) If the attempt to negotiate the linemode option failed,
+ *	   and the "-k" (don't initiate kludge linemode) isn't set,
+ *	   then we try to use kludge linemode.  We test for this
+ *	   capability by sending "do Timing Mark".  If a positive
+ *	   response comes back, then we assume that the client
+ *	   understands kludge linemode (ech!) and the
+ *	   lmodetype flag is set to KLUDGE_LINEMODE.
+ *	3) Otherwise, linemode is not supported at all and
+ *	   lmodetype remains set to NO_LINEMODE (which happens
+ *	   to be 0 for convenience).
+ *	4) At any time a command arrives that implies a higher
+ *	   state of linemode support in the client, we move to that
+ *	   linemode support.
+ *
+ * A short explanation of kludge linemode is in order here.
+ *	1) The heuristic to determine support for kludge linemode
+ *	   is to send a do timing mark.  We assume that a client
+ *	   that supports timing marks also supports kludge linemode.
+ *	   A risky proposition at best.
+ *	2) Further negotiation of linemode is done by changing the
+ *	   the server's state regarding SGA.  If server will SGA,
+ *	   then linemode is off, if server won't SGA, then linemode
+ *	   is on.
+ */
+	void
+localstat()
+{
+	void netflush();
+	int need_will_echo = 0;
+
+#if	defined(CRAY2) && defined(UNICOS5)
+	/*
+	 * Keep track of that ol' CR/NL mapping while we're in the
+	 * neighborhood.
+	 */
+	newmap = tty_isnewmap();
+#endif	/* defined(CRAY2) && defined(UNICOS5) */
+
+	/*
+	 * Check for state of BINARY options.
+	 */
+	if (tty_isbinaryin()) {
+		if (his_want_state_is_wont(TELOPT_BINARY))
+			send_do(TELOPT_BINARY, 1);
+	} else {
+		if (his_want_state_is_will(TELOPT_BINARY))
+			send_dont(TELOPT_BINARY, 1);
+	}
+
+	if (tty_isbinaryout()) {
+		if (my_want_state_is_wont(TELOPT_BINARY))
+			send_will(TELOPT_BINARY, 1);
+	} else {
+		if (my_want_state_is_will(TELOPT_BINARY))
+			send_wont(TELOPT_BINARY, 1);
+	}
+
+	/*
+	 * Check for changes to flow control if client supports it.
+	 */
+	flowstat();
+
+	/*
+	 * Check linemode on/off state
+	 */
+	uselinemode = tty_linemode();
+
+	/*
+	 * If alwayslinemode is on, and pty is changing to turn it off, then
+	 * force linemode back on.
+	 */
+	if (alwayslinemode && linemode && !uselinemode) {
+		uselinemode = 1;
+		tty_setlinemode(uselinemode);
+	}
+
+#ifdef	ENCRYPTION
+	/*
+	 * If the terminal is not echoing, but editing is enabled,
+	 * something like password input is going to happen, so
+	 * if we the other side is not currently sending encrypted
+	 * data, ask the other side to start encrypting.
+	 */
+	if (his_state_is_will(TELOPT_ENCRYPT)) {
+		static int enc_passwd = 0;
+		if (uselinemode && !tty_isecho() && tty_isediting()
+		    && (enc_passwd == 0) && !decrypt_input) {
+			encrypt_send_request_start();
+			enc_passwd = 1;
+		} else if (enc_passwd) {
+			encrypt_send_request_end();
+			enc_passwd = 0;
+		}
+	}
+#endif	/* ENCRYPTION */
+
+	/*
+	 * Do echo mode handling as soon as we know what the
+	 * linemode is going to be.
+	 * If the pty has echo turned off, then tell the client that
+	 * the server will echo.  If echo is on, then the server
+	 * will echo if in character mode, but in linemode the
+	 * client should do local echoing.  The state machine will
+	 * not send anything if it is unnecessary, so don't worry
+	 * about that here.
+	 *
+	 * If we need to send the WILL ECHO (because echo is off),
+	 * then delay that until after we have changed the MODE.
+	 * This way, when the user is turning off both editing
+	 * and echo, the client will get editing turned off first.
+	 * This keeps the client from going into encryption mode
+	 * and then right back out if it is doing auto-encryption
+	 * when passwords are being typed.
+	 */
+	if (uselinemode) {
+		if (tty_isecho())
+			send_wont(TELOPT_ECHO, 1);
+		else
+			need_will_echo = 1;
+#ifdef	KLUDGELINEMODE
+		if (lmodetype == KLUDGE_OK)
+			lmodetype = KLUDGE_LINEMODE;
+#endif
+	}
+
+	/*
+	 * If linemode is being turned off, send appropriate
+	 * command and then we're all done.
+	 */
+	 if (!uselinemode && linemode) {
+# ifdef	KLUDGELINEMODE
+		if (lmodetype == REAL_LINEMODE) {
+# endif	/* KLUDGELINEMODE */
+			send_dont(TELOPT_LINEMODE, 1);
+# ifdef	KLUDGELINEMODE
+		} else if (lmodetype == KLUDGE_LINEMODE)
+			send_will(TELOPT_SGA, 1);
+# endif	/* KLUDGELINEMODE */
+		send_will(TELOPT_ECHO, 1);
+		linemode = uselinemode;
+		goto done;
+	}
+
+# ifdef	KLUDGELINEMODE
+	/*
+	 * If using real linemode check edit modes for possible later use.
+	 * If we are in kludge linemode, do the SGA negotiation.
+	 */
+	if (lmodetype == REAL_LINEMODE) {
+# endif	/* KLUDGELINEMODE */
+		useeditmode = 0;
+		if (tty_isediting())
+			useeditmode |= MODE_EDIT;
+		if (tty_istrapsig())
+			useeditmode |= MODE_TRAPSIG;
+		if (tty_issofttab())
+			useeditmode |= MODE_SOFT_TAB;
+		if (tty_islitecho())
+			useeditmode |= MODE_LIT_ECHO;
+# ifdef	KLUDGELINEMODE
+	} else if (lmodetype == KLUDGE_LINEMODE) {
+		if (tty_isediting() && uselinemode)
+			send_wont(TELOPT_SGA, 1);
+		else
+			send_will(TELOPT_SGA, 1);
+	}
+# endif	/* KLUDGELINEMODE */
+
+	/*
+	 * Negotiate linemode on if pty state has changed to turn it on.
+	 * Send appropriate command and send along edit mode, then all done.
+	 */
+	if (uselinemode && !linemode) {
+# ifdef	KLUDGELINEMODE
+		if (lmodetype == KLUDGE_LINEMODE) {
+			send_wont(TELOPT_SGA, 1);
+		} else if (lmodetype == REAL_LINEMODE) {
+# endif	/* KLUDGELINEMODE */
+			send_do(TELOPT_LINEMODE, 1);
+			/* send along edit modes */
+			(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB,
+				TELOPT_LINEMODE, LM_MODE, useeditmode,
+				IAC, SE);
+			nfrontp += 7;
+			editmode = useeditmode;
+# ifdef	KLUDGELINEMODE
+		}
+# endif	/* KLUDGELINEMODE */
+		linemode = uselinemode;
+		goto done;
+	}
+
+# ifdef	KLUDGELINEMODE
+	/*
+	 * None of what follows is of any value if not using
+	 * real linemode.
+	 */
+	if (lmodetype < REAL_LINEMODE)
+		goto done;
+# endif	/* KLUDGELINEMODE */
+
+	if (linemode && his_state_is_will(TELOPT_LINEMODE)) {
+		/*
+		 * If edit mode changed, send edit mode.
+		 */
+		 if (useeditmode != editmode) {
+			/*
+			 * Send along appropriate edit mode mask.
+			 */
+			(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB,
+				TELOPT_LINEMODE, LM_MODE, useeditmode,
+				IAC, SE);
+			nfrontp += 7;
+			editmode = useeditmode;
+		}
+
+
+		/*
+		 * Check for changes to special characters in use.
+		 */
+		start_slc(0);
+		check_slc();
+		(void) end_slc(0);
+	}
+
+done:
+	if (need_will_echo)
+		send_will(TELOPT_ECHO, 1);
+	/*
+	 * Some things should be deferred until after the pty state has
+	 * been set by the local process.  Do those things that have been
+	 * deferred now.  This only happens once.
+	 */
+	if (_terminit == 0) {
+		_terminit = 1;
+		defer_terminit();
+	}
+
+	netflush();
+	set_termbuf();
+	return;
+
+}  /* end of localstat */
+#endif	/* LINEMODE */
+
+/*
+ * flowstat
+ *
+ * Check for changes to flow control
+ */
+	void
+flowstat()
+{
+	if (his_state_is_will(TELOPT_LFLOW)) {
+		if (tty_flowmode() != flowmode) {
+			flowmode = tty_flowmode();
+			(void) sprintf(nfrontp, "%c%c%c%c%c%c",
+					IAC, SB, TELOPT_LFLOW,
+					flowmode ? LFLOW_ON : LFLOW_OFF,
+					IAC, SE);
+			nfrontp += 6;
+		}
+		if (tty_restartany() != restartany) {
+			restartany = tty_restartany();
+			(void) sprintf(nfrontp, "%c%c%c%c%c%c",
+					IAC, SB, TELOPT_LFLOW,
+					restartany ? LFLOW_RESTART_ANY
+						   : LFLOW_RESTART_XON,
+					IAC, SE);
+			nfrontp += 6;
+		}
+	}
+}
+
+/*
+ * clientstat
+ *
+ * Process linemode related requests from the client.
+ * Client can request a change to only one of linemode, editmode or slc's
+ * at a time, and if using kludge linemode, then only linemode may be
+ * affected.
+ */
+	void
+clientstat(code, parm1, parm2)
+	register int code, parm1, parm2;
+{
+	void netflush();
+
+	/*
+	 * Get a copy of terminal characteristics.
+	 */
+	init_termbuf();
+
+	/*
+	 * Process request from client. code tells what it is.
+	 */
+	switch (code) {
+#ifdef	LINEMODE
+	case TELOPT_LINEMODE:
+		/*
+		 * Don't do anything unless client is asking us to change
+		 * modes.
+		 */
+		uselinemode = (parm1 == WILL);
+		if (uselinemode != linemode) {
+# ifdef	KLUDGELINEMODE
+			/*
+			 * If using kludge linemode, make sure that
+			 * we can do what the client asks.
+			 * We can not turn off linemode if alwayslinemode
+			 * and the ICANON bit is set.
+			 */
+			if (lmodetype == KLUDGE_LINEMODE) {
+				if (alwayslinemode && tty_isediting()) {
+					uselinemode = 1;
+				}
+			}
+
+			/*
+			 * Quit now if we can't do it.
+			 */
+			if (uselinemode == linemode)
+				return;
+
+			/*
+			 * If using real linemode and linemode is being
+			 * turned on, send along the edit mode mask.
+			 */
+			if (lmodetype == REAL_LINEMODE && uselinemode)
+# else	/* KLUDGELINEMODE */
+			if (uselinemode)
+# endif	/* KLUDGELINEMODE */
+			{
+				useeditmode = 0;
+				if (tty_isediting())
+					useeditmode |= MODE_EDIT;
+				if (tty_istrapsig)
+					useeditmode |= MODE_TRAPSIG;
+				if (tty_issofttab())
+					useeditmode |= MODE_SOFT_TAB;
+				if (tty_islitecho())
+					useeditmode |= MODE_LIT_ECHO;
+				(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC,
+					SB, TELOPT_LINEMODE, LM_MODE,
+							useeditmode, IAC, SE);
+				nfrontp += 7;
+				editmode = useeditmode;
+			}
+
+
+			tty_setlinemode(uselinemode);
+
+			linemode = uselinemode;
+
+			if (!linemode)
+				send_will(TELOPT_ECHO, 1);
+		}
+		break;
+
+	case LM_MODE:
+	    {
+		register int ack, changed;
+
+		/*
+		 * Client has sent along a mode mask.  If it agrees with
+		 * what we are currently doing, ignore it; if not, it could
+		 * be viewed as a request to change.  Note that the server
+		 * will change to the modes in an ack if it is different from
+		 * what we currently have, but we will not ack the ack.
+		 */
+		 useeditmode &= MODE_MASK;
+		 ack = (useeditmode & MODE_ACK);
+		 useeditmode &= ~MODE_ACK;
+
+		 if (changed = (useeditmode ^ editmode)) {
+			/*
+			 * This check is for a timing problem.  If the
+			 * state of the tty has changed (due to the user
+			 * application) we need to process that info
+			 * before we write in the state contained in the
+			 * ack!!!  This gets out the new MODE request,
+			 * and when the ack to that command comes back
+			 * we'll set it and be in the right mode.
+			 */
+			if (ack)
+				localstat();
+			if (changed & MODE_EDIT)
+				tty_setedit(useeditmode & MODE_EDIT);
+
+			if (changed & MODE_TRAPSIG)
+				tty_setsig(useeditmode & MODE_TRAPSIG);
+
+			if (changed & MODE_SOFT_TAB)
+				tty_setsofttab(useeditmode & MODE_SOFT_TAB);
+
+			if (changed & MODE_LIT_ECHO)
+				tty_setlitecho(useeditmode & MODE_LIT_ECHO);
+
+			set_termbuf();
+
+ 			if (!ack) {
+ 				(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC,
+					SB, TELOPT_LINEMODE, LM_MODE,
+ 					useeditmode|MODE_ACK,
+ 					IAC, SE);
+ 				nfrontp += 7;
+ 			}
+
+			editmode = useeditmode;
+		}
+
+		break;
+
+	    }  /* end of case LM_MODE */
+#endif	/* LINEMODE */
+
+	case TELOPT_NAWS:
+#ifdef	TIOCSWINSZ
+	    {
+		struct winsize ws;
+
+		def_col = parm1;
+		def_row = parm2;
+#ifdef	LINEMODE
+		/*
+		 * Defer changing window size until after terminal is
+		 * initialized.
+		 */
+		if (terminit() == 0)
+			return;
+#endif	/* LINEMODE */
+
+		/*
+		 * Change window size as requested by client.
+		 */
+
+		ws.ws_col = parm1;
+		ws.ws_row = parm2;
+		(void) ioctl(pty, TIOCSWINSZ, (char *)&ws);
+	    }
+#endif	/* TIOCSWINSZ */
+
+		break;
+
+	case TELOPT_TSPEED:
+	    {
+		def_tspeed = parm1;
+		def_rspeed = parm2;
+#ifdef	LINEMODE
+		/*
+		 * Defer changing the terminal speed.
+		 */
+		if (terminit() == 0)
+			return;
+#endif	/* LINEMODE */
+		/*
+		 * Change terminal speed as requested by client.
+		 * We set the receive speed first, so that if we can't
+		 * store seperate receive and transmit speeds, the transmit
+		 * speed will take precedence.
+		 */
+		tty_rspeed(parm2);
+		tty_tspeed(parm1);
+		set_termbuf();
+
+		break;
+
+	    }  /* end of case TELOPT_TSPEED */
+
+	default:
+		/* What? */
+		break;
+	}  /* end of switch */
+
+#if	defined(CRAY2) && defined(UNICOS5)
+	/*
+	 * Just in case of the likely event that we changed the pty state.
+	 */
+	rcv_ioctl();
+#endif	/* defined(CRAY2) && defined(UNICOS5) */
+
+	netflush();
+
+}  /* end of clientstat */
+
+#if	defined(CRAY2) && defined(UNICOS5)
+	void
+termstat()
+{
+	needtermstat = 1;
+}
+
+	void
+_termstat()
+{
+	needtermstat = 0;
+	init_termbuf();
+	localstat();
+	rcv_ioctl();
+}
+#endif	/* defined(CRAY2) && defined(UNICOS5) */
+
+#ifdef	LINEMODE
+/*
+ * defer_terminit
+ *
+ * Some things should not be done until after the login process has started
+ * and all the pty modes are set to what they are supposed to be.  This
+ * function is called when the pty state has been processed for the first time.
+ * It calls other functions that do things that were deferred in each module.
+ */
+	void
+defer_terminit()
+{
+
+	/*
+	 * local stuff that got deferred.
+	 */
+	if (def_tspeed != -1) {
+		clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed);
+		def_tspeed = def_rspeed = 0;
+	}
+
+#ifdef	TIOCSWINSZ
+	if (def_col || def_row) {
+		struct winsize ws;
+
+		memset((char *)&ws, 0, sizeof(ws));
+		ws.ws_col = def_col;
+		ws.ws_row = def_row;
+		(void) ioctl(pty, TIOCSWINSZ, (char *)&ws);
+	}
+#endif
+
+	/*
+	 * The only other module that currently defers anything.
+	 */
+	deferslc();
+
+}  /* end of defer_terminit */
+
+/*
+ * terminit
+ *
+ * Returns true if the pty state has been processed yet.
+ */
+	int
+terminit()
+{
+	return(_terminit);
+
+}  /* end of terminit */
+#endif	/* LINEMODE */
diff --git a/telnetd.tproj/utility.c b/telnetd.tproj/utility.c
new file mode 100644
index 0000000..9154811
--- /dev/null
+++ b/telnetd.tproj/utility.c
@@ -0,0 +1,1215 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)utility.c	8.4 (Berkeley) 5/30/95";
+#endif /* not lint */
+
+#define PRINTOPTIONS
+#include "telnetd.h"
+
+/*
+ * utility functions performing io related tasks
+ */
+
+/*
+ * ttloop
+ *
+ *	A small subroutine to flush the network output buffer, get some data
+ * from the network, and pass it through the telnet state machine.  We
+ * also flush the pty input buffer (by dropping its data) if it becomes
+ * too full.
+ */
+
+    void
+ttloop()
+{
+    void netflush();
+
+    DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop\r\n");
+		     nfrontp += strlen(nfrontp);});
+    if (nfrontp-nbackp) {
+	netflush();
+    }
+    ncc = read(net, netibuf, sizeof netibuf);
+    if (ncc < 0) {
+	syslog(LOG_INFO, "ttloop:  read: %m\n");
+	exit(1);
+    } else if (ncc == 0) {
+	syslog(LOG_INFO, "ttloop:  peer died: %m\n");
+	exit(1);
+    }
+    DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop read %d chars\r\n", ncc);
+		     nfrontp += strlen(nfrontp);});
+    netip = netibuf;
+    telrcv();			/* state machine */
+    if (ncc > 0) {
+	pfrontp = pbackp = ptyobuf;
+	telrcv();
+    }
+}  /* end of ttloop */
+
+/*
+ * Check a descriptor to see if out of band data exists on it.
+ */
+    int
+stilloob(s)
+    int	s;		/* socket number */
+{
+    static struct timeval timeout = { 0 };
+    fd_set	excepts;
+    int value;
+
+    do {
+	FD_ZERO(&excepts);
+	FD_SET(s, &excepts);
+	value = select(s+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
+    } while ((value == -1) && (errno == EINTR));
+
+    if (value < 0) {
+	fatalperror(pty, "select");
+    }
+    if (FD_ISSET(s, &excepts)) {
+	return 1;
+    } else {
+	return 0;
+    }
+}
+
+	void
+ptyflush()
+{
+	int n;
+
+	if ((n = pfrontp - pbackp) > 0) {
+		DIAG((TD_REPORT | TD_PTYDATA),
+			{ sprintf(nfrontp, "td: ptyflush %d chars\r\n", n);
+			  nfrontp += strlen(nfrontp); });
+		DIAG(TD_PTYDATA, printdata("pd", pbackp, n));
+		n = write(pty, pbackp, n);
+	}
+	if (n < 0) {
+		if (errno == EWOULDBLOCK || errno == EINTR)
+			return;
+		cleanup(0);
+	}
+	pbackp += n;
+	if (pbackp == pfrontp)
+		pbackp = pfrontp = ptyobuf;
+}
+
+/*
+ * nextitem()
+ *
+ *	Return the address of the next "item" in the TELNET data
+ * stream.  This will be the address of the next character if
+ * the current address is a user data character, or it will
+ * be the address of the character following the TELNET command
+ * if the current address is a TELNET IAC ("I Am a Command")
+ * character.
+ */
+    char *
+nextitem(current)
+    char	*current;
+{
+    if ((*current&0xff) != IAC) {
+	return current+1;
+    }
+    switch (*(current+1)&0xff) {
+    case DO:
+    case DONT:
+    case WILL:
+    case WONT:
+	return current+3;
+    case SB:		/* loop forever looking for the SE */
+	{
+	    register char *look = current+2;
+
+	    for (;;) {
+		if ((*look++&0xff) == IAC) {
+		    if ((*look++&0xff) == SE) {
+			return look;
+		    }
+		}
+	    }
+	}
+    default:
+	return current+2;
+    }
+}  /* end of nextitem */
+
+
+/*
+ * netclear()
+ *
+ *	We are about to do a TELNET SYNCH operation.  Clear
+ * the path to the network.
+ *
+ *	Things are a bit tricky since we may have sent the first
+ * byte or so of a previous TELNET command into the network.
+ * So, we have to scan the network buffer from the beginning
+ * until we are up to where we want to be.
+ *
+ *	A side effect of what we do, just to keep things
+ * simple, is to clear the urgent data pointer.  The principal
+ * caller should be setting the urgent data pointer AFTER calling
+ * us in any case.
+ */
+    void
+netclear()
+{
+    register char *thisitem, *next;
+    char *good;
+#define	wewant(p)	((nfrontp > p) && ((*p&0xff) == IAC) && \
+				((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
+
+#ifdef	ENCRYPTION
+    thisitem = nclearto > netobuf ? nclearto : netobuf;
+#else	/* ENCRYPTION */
+    thisitem = netobuf;
+#endif	/* ENCRYPTION */
+
+    while ((next = nextitem(thisitem)) <= nbackp) {
+	thisitem = next;
+    }
+
+    /* Now, thisitem is first before/at boundary. */
+
+#ifdef	ENCRYPTION
+    good = nclearto > netobuf ? nclearto : netobuf;
+#else	/* ENCRYPTION */
+    good = netobuf;	/* where the good bytes go */
+#endif	/* ENCRYPTION */
+
+    while (nfrontp > thisitem) {
+	if (wewant(thisitem)) {
+	    int length;
+
+	    next = thisitem;
+	    do {
+		next = nextitem(next);
+	    } while (wewant(next) && (nfrontp > next));
+	    length = next-thisitem;
+	    memmove(good, thisitem, length);
+	    good += length;
+	    thisitem = next;
+	} else {
+	    thisitem = nextitem(thisitem);
+	}
+    }
+
+    nbackp = netobuf;
+    nfrontp = good;		/* next byte to be sent */
+    neturg = 0;
+}  /* end of netclear */
+
+/*
+ *  netflush
+ *		Send as much data as possible to the network,
+ *	handling requests for urgent data.
+ */
+    void
+netflush()
+{
+    int n;
+    extern int not42;
+
+    if ((n = nfrontp - nbackp) > 0) {
+	DIAG(TD_REPORT,
+	    { sprintf(nfrontp, "td: netflush %d chars\r\n", n);
+	      n += strlen(nfrontp);  /* get count first */
+	      nfrontp += strlen(nfrontp);  /* then move pointer */
+	    });
+#ifdef	ENCRYPTION
+	if (encrypt_output) {
+		char *s = nclearto ? nclearto : nbackp;
+		if (nfrontp - s > 0) {
+			(*encrypt_output)((unsigned char *)s, nfrontp-s);
+			nclearto = nfrontp;
+		}
+	}
+#endif	/* ENCRYPTION */
+	/*
+	 * if no urgent data, or if the other side appears to be an
+	 * old 4.2 client (and thus unable to survive TCP urgent data),
+	 * write the entire buffer in non-OOB mode.
+	 */
+	if ((neturg == 0) || (not42 == 0)) {
+	    n = write(net, nbackp, n);	/* normal write */
+	} else {
+	    n = neturg - nbackp;
+	    /*
+	     * In 4.2 (and 4.3) systems, there is some question about
+	     * what byte in a sendOOB operation is the "OOB" data.
+	     * To make ourselves compatible, we only send ONE byte
+	     * out of band, the one WE THINK should be OOB (though
+	     * we really have more the TCP philosophy of urgent data
+	     * rather than the Unix philosophy of OOB data).
+	     */
+	    if (n > 1) {
+		n = send(net, nbackp, n-1, 0);	/* send URGENT all by itself */
+	    } else {
+		n = send(net, nbackp, n, MSG_OOB);	/* URGENT data */
+	    }
+	}
+    }
+    if (n < 0) {
+	if (errno == EWOULDBLOCK || errno == EINTR)
+		return;
+	cleanup(0);
+    }
+    nbackp += n;
+#ifdef	ENCRYPTION
+    if (nbackp > nclearto)
+	nclearto = 0;
+#endif	/* ENCRYPTION */
+    if (nbackp >= neturg) {
+	neturg = 0;
+    }
+    if (nbackp == nfrontp) {
+	nbackp = nfrontp = netobuf;
+#ifdef	ENCRYPTION
+	nclearto = 0;
+#endif	/* ENCRYPTION */
+    }
+    return;
+}  /* end of netflush */
+
+
+/*
+ * writenet
+ *
+ * Just a handy little function to write a bit of raw data to the net.
+ * It will force a transmit of the buffer if necessary
+ *
+ * arguments
+ *    ptr - A pointer to a character string to write
+ *    len - How many bytes to write
+ */
+	void
+writenet(ptr, len)
+	register unsigned char *ptr;
+	register int len;
+{
+	/* flush buffer if no room for new data) */
+	if ((&netobuf[BUFSIZ] - nfrontp) < len) {
+		/* if this fails, don't worry, buffer is a little big */
+		netflush();
+	}
+
+	memmove(nfrontp, ptr, len);
+	nfrontp += len;
+
+}  /* end of writenet */
+
+
+/*
+ * miscellaneous functions doing a variety of little jobs follow ...
+ */
+
+
+	void
+fatal(f, msg)
+	int f;
+	char *msg;
+{
+	char buf[BUFSIZ];
+
+	(void) sprintf(buf, "telnetd: %s.\r\n", msg);
+#ifdef	ENCRYPTION
+	if (encrypt_output) {
+		/*
+		 * Better turn off encryption first....
+		 * Hope it flushes...
+		 */
+		encrypt_send_end();
+		netflush();
+	}
+#endif	/* ENCRYPTION */
+	(void) write(f, buf, (int)strlen(buf));
+	sleep(1);	/*XXX*/
+	exit(1);
+}
+
+	void
+fatalperror(f, msg)
+	int f;
+	char *msg;
+{
+	char buf[BUFSIZ], *strerror();
+
+	(void) sprintf(buf, "%s: %s", msg, strerror(errno));
+	fatal(f, buf);
+}
+
+char editedhost[32];
+
+	void
+edithost(pat, host)
+	register char *pat;
+	register char *host;
+{
+	register char *res = editedhost;
+	char *strncpy();
+
+	if (!pat)
+		pat = "";
+	while (*pat) {
+		switch (*pat) {
+
+		case '#':
+			if (*host)
+				host++;
+			break;
+
+		case '@':
+			if (*host)
+				*res++ = *host++;
+			break;
+
+		default:
+			*res++ = *pat;
+			break;
+		}
+		if (res == &editedhost[sizeof editedhost - 1]) {
+			*res = '\0';
+			return;
+		}
+		pat++;
+	}
+	if (*host)
+		(void) strncpy(res, host,
+				sizeof editedhost - (res - editedhost) -1);
+	else
+		*res = '\0';
+	editedhost[sizeof editedhost - 1] = '\0';
+}
+
+static char *putlocation;
+
+	void
+putstr(s)
+	register char *s;
+{
+
+	while (*s)
+		putchr(*s++);
+}
+
+	void
+putchr(cc)
+	int cc;
+{
+	*putlocation++ = cc;
+}
+
+/*
+ * This is split on two lines so that SCCS will not see the M
+ * between two % signs and expand it...
+ */
+static char fmtstr[] = { "%l:%M\
+%P on %A, %d %B %Y" };
+
+	void
+putf(cp, where)
+	register char *cp;
+	char *where;
+{
+	char *slash;
+	time_t t;
+	char db[100];
+#ifdef	STREAMSPTY
+	extern char *strchr();
+#else
+	extern char *strrchr();
+#endif
+
+	putlocation = where;
+
+	while (*cp) {
+		if (*cp != '%') {
+			putchr(*cp++);
+			continue;
+		}
+		switch (*++cp) {
+
+		case 't':
+#ifdef	STREAMSPTY
+			/* names are like /dev/pts/2 -- we want pts/2 */
+			slash = strchr(line+1, '/');
+#else
+			slash = strrchr(line, '/');
+#endif
+			if (slash == (char *) 0)
+				putstr(line);
+			else
+				putstr(&slash[1]);
+			break;
+
+		case 'h':
+			putstr(editedhost);
+			break;
+
+		case 'd':
+			(void)time(&t);
+			(void)strftime(db, sizeof(db), fmtstr, localtime(&t));
+			putstr(db);
+			break;
+
+		case '%':
+			putchr('%');
+			break;
+		}
+		cp++;
+	}
+}
+
+#ifdef DIAGNOSTICS
+/*
+ * Print telnet options and commands in plain text, if possible.
+ */
+	void
+printoption(fmt, option)
+	register char *fmt;
+	register int option;
+{
+	if (TELOPT_OK(option))
+		sprintf(nfrontp, "%s %s\r\n", fmt, TELOPT(option));
+	else if (TELCMD_OK(option))
+		sprintf(nfrontp, "%s %s\r\n", fmt, TELCMD(option));
+	else
+		sprintf(nfrontp, "%s %d\r\n", fmt, option);
+	nfrontp += strlen(nfrontp);
+	return;
+}
+
+    void
+printsub(direction, pointer, length)
+    char		direction;	/* '<' or '>' */
+    unsigned char	*pointer;	/* where suboption data sits */
+    int			length;		/* length of suboption data */
+{
+    register int i;
+    char buf[512];
+
+	if (!(diagnostic & TD_OPTIONS))
+		return;
+
+	if (direction) {
+	    sprintf(nfrontp, "td: %s suboption ",
+					direction == '<' ? "recv" : "send");
+	    nfrontp += strlen(nfrontp);
+	    if (length >= 3) {
+		register int j;
+
+		i = pointer[length-2];
+		j = pointer[length-1];
+
+		if (i != IAC || j != SE) {
+		    sprintf(nfrontp, "(terminated by ");
+		    nfrontp += strlen(nfrontp);
+		    if (TELOPT_OK(i))
+			sprintf(nfrontp, "%s ", TELOPT(i));
+		    else if (TELCMD_OK(i))
+			sprintf(nfrontp, "%s ", TELCMD(i));
+		    else
+			sprintf(nfrontp, "%d ", i);
+		    nfrontp += strlen(nfrontp);
+		    if (TELOPT_OK(j))
+			sprintf(nfrontp, "%s", TELOPT(j));
+		    else if (TELCMD_OK(j))
+			sprintf(nfrontp, "%s", TELCMD(j));
+		    else
+			sprintf(nfrontp, "%d", j);
+		    nfrontp += strlen(nfrontp);
+		    sprintf(nfrontp, ", not IAC SE!) ");
+		    nfrontp += strlen(nfrontp);
+		}
+	    }
+	    length -= 2;
+	}
+	if (length < 1) {
+	    sprintf(nfrontp, "(Empty suboption??\?)");
+	    nfrontp += strlen(nfrontp);
+	    return;
+	}
+	switch (pointer[0]) {
+	case TELOPT_TTYPE:
+	    sprintf(nfrontp, "TERMINAL-TYPE ");
+	    nfrontp += strlen(nfrontp);
+	    switch (pointer[1]) {
+	    case TELQUAL_IS:
+		sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2);
+		break;
+	    case TELQUAL_SEND:
+		sprintf(nfrontp, "SEND");
+		break;
+	    default:
+		sprintf(nfrontp,
+				"- unknown qualifier %d (0x%x).",
+				pointer[1], pointer[1]);
+	    }
+	    nfrontp += strlen(nfrontp);
+	    break;
+	case TELOPT_TSPEED:
+	    sprintf(nfrontp, "TERMINAL-SPEED");
+	    nfrontp += strlen(nfrontp);
+	    if (length < 2) {
+		sprintf(nfrontp, " (empty suboption??\?)");
+		nfrontp += strlen(nfrontp);
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case TELQUAL_IS:
+		sprintf(nfrontp, " IS %.*s", length-2, (char *)pointer+2);
+		nfrontp += strlen(nfrontp);
+		break;
+	    default:
+		if (pointer[1] == 1)
+		    sprintf(nfrontp, " SEND");
+		else
+		    sprintf(nfrontp, " %d (unknown)", pointer[1]);
+		nfrontp += strlen(nfrontp);
+		for (i = 2; i < length; i++) {
+		    sprintf(nfrontp, " ?%d?", pointer[i]);
+		    nfrontp += strlen(nfrontp);
+		}
+		break;
+	    }
+	    break;
+
+	case TELOPT_LFLOW:
+	    sprintf(nfrontp, "TOGGLE-FLOW-CONTROL");
+	    nfrontp += strlen(nfrontp);
+	    if (length < 2) {
+		sprintf(nfrontp, " (empty suboption??\?)");
+		nfrontp += strlen(nfrontp);
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case LFLOW_OFF:
+		sprintf(nfrontp, " OFF"); break;
+	    case LFLOW_ON:
+		sprintf(nfrontp, " ON"); break;
+	    case LFLOW_RESTART_ANY:
+		sprintf(nfrontp, " RESTART-ANY"); break;
+	    case LFLOW_RESTART_XON:
+		sprintf(nfrontp, " RESTART-XON"); break;
+	    default:
+		sprintf(nfrontp, " %d (unknown)", pointer[1]);
+	    }
+	    nfrontp += strlen(nfrontp);
+	    for (i = 2; i < length; i++) {
+		sprintf(nfrontp, " ?%d?", pointer[i]);
+		nfrontp += strlen(nfrontp);
+	    }
+	    break;
+
+	case TELOPT_NAWS:
+	    sprintf(nfrontp, "NAWS");
+	    nfrontp += strlen(nfrontp);
+	    if (length < 2) {
+		sprintf(nfrontp, " (empty suboption??\?)");
+		nfrontp += strlen(nfrontp);
+		break;
+	    }
+	    if (length == 2) {
+		sprintf(nfrontp, " ?%d?", pointer[1]);
+		nfrontp += strlen(nfrontp);
+		break;
+	    }
+	    sprintf(nfrontp, " %d %d (%d)",
+		pointer[1], pointer[2],
+		(int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
+	    nfrontp += strlen(nfrontp);
+	    if (length == 4) {
+		sprintf(nfrontp, " ?%d?", pointer[3]);
+		nfrontp += strlen(nfrontp);
+		break;
+	    }
+	    sprintf(nfrontp, " %d %d (%d)",
+		pointer[3], pointer[4],
+		(int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
+	    nfrontp += strlen(nfrontp);
+	    for (i = 5; i < length; i++) {
+		sprintf(nfrontp, " ?%d?", pointer[i]);
+		nfrontp += strlen(nfrontp);
+	    }
+	    break;
+
+	case TELOPT_LINEMODE:
+	    sprintf(nfrontp, "LINEMODE ");
+	    nfrontp += strlen(nfrontp);
+	    if (length < 2) {
+		sprintf(nfrontp, " (empty suboption??\?)");
+		nfrontp += strlen(nfrontp);
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case WILL:
+		sprintf(nfrontp, "WILL ");
+		goto common;
+	    case WONT:
+		sprintf(nfrontp, "WONT ");
+		goto common;
+	    case DO:
+		sprintf(nfrontp, "DO ");
+		goto common;
+	    case DONT:
+		sprintf(nfrontp, "DONT ");
+	    common:
+		nfrontp += strlen(nfrontp);
+		if (length < 3) {
+		    sprintf(nfrontp, "(no option??\?)");
+		    nfrontp += strlen(nfrontp);
+		    break;
+		}
+		switch (pointer[2]) {
+		case LM_FORWARDMASK:
+		    sprintf(nfrontp, "Forward Mask");
+		    nfrontp += strlen(nfrontp);
+		    for (i = 3; i < length; i++) {
+			sprintf(nfrontp, " %x", pointer[i]);
+			nfrontp += strlen(nfrontp);
+		    }
+		    break;
+		default:
+		    sprintf(nfrontp, "%d (unknown)", pointer[2]);
+		    nfrontp += strlen(nfrontp);
+		    for (i = 3; i < length; i++) {
+			sprintf(nfrontp, " %d", pointer[i]);
+			nfrontp += strlen(nfrontp);
+		    }
+		    break;
+		}
+		break;
+
+	    case LM_SLC:
+		sprintf(nfrontp, "SLC");
+		nfrontp += strlen(nfrontp);
+		for (i = 2; i < length - 2; i += 3) {
+		    if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
+			sprintf(nfrontp, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
+		    else
+			sprintf(nfrontp, " %d", pointer[i+SLC_FUNC]);
+		    nfrontp += strlen(nfrontp);
+		    switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
+		    case SLC_NOSUPPORT:
+			sprintf(nfrontp, " NOSUPPORT"); break;
+		    case SLC_CANTCHANGE:
+			sprintf(nfrontp, " CANTCHANGE"); break;
+		    case SLC_VARIABLE:
+			sprintf(nfrontp, " VARIABLE"); break;
+		    case SLC_DEFAULT:
+			sprintf(nfrontp, " DEFAULT"); break;
+		    }
+		    nfrontp += strlen(nfrontp);
+		    sprintf(nfrontp, "%s%s%s",
+			pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
+			pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
+			pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
+		    nfrontp += strlen(nfrontp);
+		    if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
+						SLC_FLUSHOUT| SLC_LEVELBITS)) {
+			sprintf(nfrontp, "(0x%x)", pointer[i+SLC_FLAGS]);
+			nfrontp += strlen(nfrontp);
+		    }
+		    sprintf(nfrontp, " %d;", pointer[i+SLC_VALUE]);
+		    nfrontp += strlen(nfrontp);
+		    if ((pointer[i+SLC_VALUE] == IAC) &&
+			(pointer[i+SLC_VALUE+1] == IAC))
+				i++;
+		}
+		for (; i < length; i++) {
+		    sprintf(nfrontp, " ?%d?", pointer[i]);
+		    nfrontp += strlen(nfrontp);
+		}
+		break;
+
+	    case LM_MODE:
+		sprintf(nfrontp, "MODE ");
+		nfrontp += strlen(nfrontp);
+		if (length < 3) {
+		    sprintf(nfrontp, "(no mode??\?)");
+		    nfrontp += strlen(nfrontp);
+		    break;
+		}
+		{
+		    char tbuf[32];
+		    sprintf(tbuf, "%s%s%s%s%s",
+			pointer[2]&MODE_EDIT ? "|EDIT" : "",
+			pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
+			pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
+			pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
+			pointer[2]&MODE_ACK ? "|ACK" : "");
+		    sprintf(nfrontp, "%s", tbuf[1] ? &tbuf[1] : "0");
+		    nfrontp += strlen(nfrontp);
+		}
+		if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) {
+		    sprintf(nfrontp, " (0x%x)", pointer[2]);
+		    nfrontp += strlen(nfrontp);
+		}
+		for (i = 3; i < length; i++) {
+		    sprintf(nfrontp, " ?0x%x?", pointer[i]);
+		    nfrontp += strlen(nfrontp);
+		}
+		break;
+	    default:
+		sprintf(nfrontp, "%d (unknown)", pointer[1]);
+		nfrontp += strlen(nfrontp);
+		for (i = 2; i < length; i++) {
+		    sprintf(nfrontp, " %d", pointer[i]);
+		    nfrontp += strlen(nfrontp);
+		}
+	    }
+	    break;
+
+	case TELOPT_STATUS: {
+	    register char *cp;
+	    register int j, k;
+
+	    sprintf(nfrontp, "STATUS");
+	    nfrontp += strlen(nfrontp);
+
+	    switch (pointer[1]) {
+	    default:
+		if (pointer[1] == TELQUAL_SEND)
+		    sprintf(nfrontp, " SEND");
+		else
+		    sprintf(nfrontp, " %d (unknown)", pointer[1]);
+		nfrontp += strlen(nfrontp);
+		for (i = 2; i < length; i++) {
+		    sprintf(nfrontp, " ?%d?", pointer[i]);
+		    nfrontp += strlen(nfrontp);
+		}
+		break;
+	    case TELQUAL_IS:
+		sprintf(nfrontp, " IS\r\n");
+		nfrontp += strlen(nfrontp);
+
+		for (i = 2; i < length; i++) {
+		    switch(pointer[i]) {
+		    case DO:	cp = "DO"; goto common2;
+		    case DONT:	cp = "DONT"; goto common2;
+		    case WILL:	cp = "WILL"; goto common2;
+		    case WONT:	cp = "WONT"; goto common2;
+		    common2:
+			i++;
+			if (TELOPT_OK(pointer[i]))
+			    sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i]));
+			else
+			    sprintf(nfrontp, " %s %d", cp, pointer[i]);
+			nfrontp += strlen(nfrontp);
+
+			sprintf(nfrontp, "\r\n");
+			nfrontp += strlen(nfrontp);
+			break;
+
+		    case SB:
+			sprintf(nfrontp, " SB ");
+			nfrontp += strlen(nfrontp);
+			i++;
+			j = k = i;
+			while (j < length) {
+			    if (pointer[j] == SE) {
+				if (j+1 == length)
+				    break;
+				if (pointer[j+1] == SE)
+				    j++;
+				else
+				    break;
+			    }
+			    pointer[k++] = pointer[j++];
+			}
+			printsub(0, &pointer[i], k - i);
+			if (i < length) {
+			    sprintf(nfrontp, " SE");
+			    nfrontp += strlen(nfrontp);
+			    i = j;
+			} else
+			    i = j - 1;
+
+			sprintf(nfrontp, "\r\n");
+			nfrontp += strlen(nfrontp);
+
+			break;
+
+		    default:
+			sprintf(nfrontp, " %d", pointer[i]);
+			nfrontp += strlen(nfrontp);
+			break;
+		    }
+		}
+		break;
+	    }
+	    break;
+	  }
+
+	case TELOPT_XDISPLOC:
+	    sprintf(nfrontp, "X-DISPLAY-LOCATION ");
+	    nfrontp += strlen(nfrontp);
+	    switch (pointer[1]) {
+	    case TELQUAL_IS:
+		sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2);
+		break;
+	    case TELQUAL_SEND:
+		sprintf(nfrontp, "SEND");
+		break;
+	    default:
+		sprintf(nfrontp, "- unknown qualifier %d (0x%x).",
+				pointer[1], pointer[1]);
+	    }
+	    nfrontp += strlen(nfrontp);
+	    break;
+
+	case TELOPT_NEW_ENVIRON:
+	    sprintf(nfrontp, "NEW-ENVIRON ");
+	    goto env_common1;
+	case TELOPT_OLD_ENVIRON:
+	    sprintf(nfrontp, "OLD-ENVIRON");
+	env_common1:
+	    nfrontp += strlen(nfrontp);
+	    switch (pointer[1]) {
+	    case TELQUAL_IS:
+		sprintf(nfrontp, "IS ");
+		goto env_common;
+	    case TELQUAL_SEND:
+		sprintf(nfrontp, "SEND ");
+		goto env_common;
+	    case TELQUAL_INFO:
+		sprintf(nfrontp, "INFO ");
+	    env_common:
+		nfrontp += strlen(nfrontp);
+		{
+		    register int noquote = 2;
+		    for (i = 2; i < length; i++ ) {
+			switch (pointer[i]) {
+			case NEW_ENV_VAR:
+			    sprintf(nfrontp, "\" VAR " + noquote);
+			    nfrontp += strlen(nfrontp);
+			    noquote = 2;
+			    break;
+
+			case NEW_ENV_VALUE:
+			    sprintf(nfrontp, "\" VALUE " + noquote);
+			    nfrontp += strlen(nfrontp);
+			    noquote = 2;
+			    break;
+
+			case ENV_ESC:
+			    sprintf(nfrontp, "\" ESC " + noquote);
+			    nfrontp += strlen(nfrontp);
+			    noquote = 2;
+			    break;
+
+			case ENV_USERVAR:
+			    sprintf(nfrontp, "\" USERVAR " + noquote);
+			    nfrontp += strlen(nfrontp);
+			    noquote = 2;
+			    break;
+
+			default:
+			def_case:
+			    if (isprint(pointer[i]) && pointer[i] != '"') {
+				if (noquote) {
+				    *nfrontp++ = '"';
+				    noquote = 0;
+				}
+				*nfrontp++ = pointer[i];
+			    } else {
+				sprintf(nfrontp, "\" %03o " + noquote,
+							pointer[i]);
+				nfrontp += strlen(nfrontp);
+				noquote = 2;
+			    }
+			    break;
+			}
+		    }
+		    if (!noquote)
+			*nfrontp++ = '"';
+		    break;
+		}
+	    }
+	    break;
+
+#if	defined(AUTHENTICATION)
+	case TELOPT_AUTHENTICATION:
+	    sprintf(nfrontp, "AUTHENTICATION");
+	    nfrontp += strlen(nfrontp);
+
+	    if (length < 2) {
+		sprintf(nfrontp, " (empty suboption??\?)");
+		nfrontp += strlen(nfrontp);
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case TELQUAL_REPLY:
+	    case TELQUAL_IS:
+		sprintf(nfrontp, " %s ", (pointer[1] == TELQUAL_IS) ?
+							"IS" : "REPLY");
+		nfrontp += strlen(nfrontp);
+		if (AUTHTYPE_NAME_OK(pointer[2]))
+		    sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[2]));
+		else
+		    sprintf(nfrontp, "%d ", pointer[2]);
+		nfrontp += strlen(nfrontp);
+		if (length < 3) {
+		    sprintf(nfrontp, "(partial suboption??\?)");
+		    nfrontp += strlen(nfrontp);
+		    break;
+		}
+		sprintf(nfrontp, "%s|%s",
+			((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
+			"CLIENT" : "SERVER",
+			((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
+			"MUTUAL" : "ONE-WAY");
+		nfrontp += strlen(nfrontp);
+
+		auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
+		sprintf(nfrontp, "%s", buf);
+		nfrontp += strlen(nfrontp);
+		break;
+
+	    case TELQUAL_SEND:
+		i = 2;
+		sprintf(nfrontp, " SEND ");
+		nfrontp += strlen(nfrontp);
+		while (i < length) {
+		    if (AUTHTYPE_NAME_OK(pointer[i]))
+			sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[i]));
+		    else
+			sprintf(nfrontp, "%d ", pointer[i]);
+		    nfrontp += strlen(nfrontp);
+		    if (++i >= length) {
+			sprintf(nfrontp, "(partial suboption??\?)");
+			nfrontp += strlen(nfrontp);
+			break;
+		    }
+		    sprintf(nfrontp, "%s|%s ",
+			((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
+							"CLIENT" : "SERVER",
+			((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
+							"MUTUAL" : "ONE-WAY");
+		    nfrontp += strlen(nfrontp);
+		    ++i;
+		}
+		break;
+
+	    case TELQUAL_NAME:
+		i = 2;
+		sprintf(nfrontp, " NAME \"");
+		nfrontp += strlen(nfrontp);
+		while (i < length)
+		    *nfrontp += pointer[i++];
+		*nfrontp += '"';
+		break;
+
+	    default:
+		    for (i = 2; i < length; i++) {
+			sprintf(nfrontp, " ?%d?", pointer[i]);
+			nfrontp += strlen(nfrontp);
+		    }
+		    break;
+	    }
+	    break;
+#endif
+
+#ifdef	ENCRYPTION
+	case TELOPT_ENCRYPT:
+	    sprintf(nfrontp, "ENCRYPT");
+	    nfrontp += strlen(nfrontp);
+	    if (length < 2) {
+		sprintf(nfrontp, " (empty suboption??\?)");
+		nfrontp += strlen(nfrontp);
+		break;
+	    }
+	    switch (pointer[1]) {
+	    case ENCRYPT_START:
+		sprintf(nfrontp, " START");
+		nfrontp += strlen(nfrontp);
+		break;
+
+	    case ENCRYPT_END:
+		sprintf(nfrontp, " END");
+		nfrontp += strlen(nfrontp);
+		break;
+
+	    case ENCRYPT_REQSTART:
+		sprintf(nfrontp, " REQUEST-START");
+		nfrontp += strlen(nfrontp);
+		break;
+
+	    case ENCRYPT_REQEND:
+		sprintf(nfrontp, " REQUEST-END");
+		nfrontp += strlen(nfrontp);
+		break;
+
+	    case ENCRYPT_IS:
+	    case ENCRYPT_REPLY:
+		sprintf(nfrontp, " %s ", (pointer[1] == ENCRYPT_IS) ?
+							"IS" : "REPLY");
+		nfrontp += strlen(nfrontp);
+		if (length < 3) {
+		    sprintf(nfrontp, " (partial suboption??\?)");
+		    nfrontp += strlen(nfrontp);
+		    break;
+		}
+		if (ENCTYPE_NAME_OK(pointer[2]))
+		    sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[2]));
+		else
+		    sprintf(nfrontp, " %d (unknown)", pointer[2]);
+		nfrontp += strlen(nfrontp);
+
+		encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf));
+		sprintf(nfrontp, "%s", buf);
+		nfrontp += strlen(nfrontp);
+		break;
+
+	    case ENCRYPT_SUPPORT:
+		i = 2;
+		sprintf(nfrontp, " SUPPORT ");
+		nfrontp += strlen(nfrontp);
+		while (i < length) {
+		    if (ENCTYPE_NAME_OK(pointer[i]))
+			sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[i]));
+		    else
+			sprintf(nfrontp, "%d ", pointer[i]);
+		    nfrontp += strlen(nfrontp);
+		    i++;
+		}
+		break;
+
+	    case ENCRYPT_ENC_KEYID:
+		sprintf(nfrontp, " ENC_KEYID", pointer[1]);
+		nfrontp += strlen(nfrontp);
+		goto encommon;
+
+	    case ENCRYPT_DEC_KEYID:
+		sprintf(nfrontp, " DEC_KEYID", pointer[1]);
+		nfrontp += strlen(nfrontp);
+		goto encommon;
+
+	    default:
+		sprintf(nfrontp, " %d (unknown)", pointer[1]);
+		nfrontp += strlen(nfrontp);
+	    encommon:
+		for (i = 2; i < length; i++) {
+		    sprintf(nfrontp, " %d", pointer[i]);
+		    nfrontp += strlen(nfrontp);
+		}
+		break;
+	    }
+	    break;
+#endif	/* ENCRYPTION */
+
+	default:
+	    if (TELOPT_OK(pointer[0]))
+		sprintf(nfrontp, "%s (unknown)", TELOPT(pointer[0]));
+	    else
+		sprintf(nfrontp, "%d (unknown)", pointer[i]);
+	    nfrontp += strlen(nfrontp);
+	    for (i = 1; i < length; i++) {
+		sprintf(nfrontp, " %d", pointer[i]);
+		nfrontp += strlen(nfrontp);
+	    }
+	    break;
+	}
+	sprintf(nfrontp, "\r\n");
+	nfrontp += strlen(nfrontp);
+}
+
+/*
+ * Dump a data buffer in hex and ascii to the output data stream.
+ */
+	void
+printdata(tag, ptr, cnt)
+	register char *tag;
+	register char *ptr;
+	register int cnt;
+{
+	register int i;
+	char xbuf[30];
+
+	while (cnt) {
+		/* flush net output buffer if no room for new data) */
+		if ((&netobuf[BUFSIZ] - nfrontp) < 80) {
+			netflush();
+		}
+
+		/* add a line of output */
+		sprintf(nfrontp, "%s: ", tag);
+		nfrontp += strlen(nfrontp);
+		for (i = 0; i < 20 && cnt; i++) {
+			sprintf(nfrontp, "%02x", *ptr);
+			nfrontp += strlen(nfrontp);
+			if (isprint(*ptr)) {
+				xbuf[i] = *ptr;
+			} else {
+				xbuf[i] = '.';
+			}
+			if (i % 2) {
+				*nfrontp = ' ';
+				nfrontp++;
+			}
+			cnt--;
+			ptr++;
+		}
+		xbuf[i] = '\0';
+		sprintf(nfrontp, " %s\r\n", xbuf );
+		nfrontp += strlen(nfrontp);
+	}
+}
+#endif /* DIAGNOSTICS */
diff --git a/tftp.tproj/Makefile b/tftp.tproj/Makefile
new file mode 100644
index 0000000..e28658a
--- /dev/null
+++ b/tftp.tproj/Makefile
@@ -0,0 +1,52 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = tftp
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = extern.h tftpsubs.h
+
+CFILES = main.c tftp.c tftpsubs.c
+
+OTHERSRCS = Makefile.preamble Makefile tftp.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/tftp.tproj/Makefile.preamble b/tftp.tproj/Makefile.preamble
new file mode 100644
index 0000000..925a5c7
--- /dev/null
+++ b/tftp.tproj/Makefile.preamble
@@ -0,0 +1,3 @@
+CLEAN_ALL_SUBPROJECTS = YES
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/tftp.tproj/PB.project b/tftp.tproj/PB.project
new file mode 100644
index 0000000..83d2fde
--- /dev/null
+++ b/tftp.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (extern.h, tftpsubs.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (main.c, tftp.c, tftpsubs.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, tftp.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = tftp; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/tftp.tproj/extern.h b/tftp.tproj/extern.h
new file mode 100644
index 0000000..f41b4d4
--- /dev/null
+++ b/tftp.tproj/extern.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)extern.h	8.1 (Berkeley) 6/6/93
+ */
+
+void	recvfile __P((int, char *, char *));
+void	tftp_sendfile __P((int, char *, char *));
diff --git a/tftp.tproj/main.c b/tftp.tproj/main.c
new file mode 100644
index 0000000..7e110cc
--- /dev/null
+++ b/tftp.tproj/main.c
@@ -0,0 +1,753 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+/* Many bug fixes are from Jim Guyton <guyton@rand-unix> */
+
+/*
+ * TFTP User Program -- Command Interface.
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "extern.h"
+
+#define	TIMEOUT		5		/* secs between rexmt's */
+
+struct	sockaddr_in peeraddr;
+int	f;
+short   port;
+int	trace;
+int	verbose;
+int	connected;
+char	mode[32];
+char	line[BUFSIZ];
+int	margc;
+char	*margv[20];
+char	*prompt = "tftp";
+jmp_buf	toplevel;
+void	intr();
+struct	servent *sp;
+
+void	get __P((int, char **));
+void	help __P((int, char **));
+void	modecmd __P((int, char **));
+void	put __P((int, char **));
+void	quit __P((int, char **));
+void	setascii __P((int, char **));
+void	setbinary __P((int, char **));
+void	setpeer __P((int, char **));
+void	setrexmt __P((int, char **));
+void	settimeout __P((int, char **));
+void	settrace __P((int, char **));
+void	setverbose __P((int, char **));
+void	status __P((int, char **));
+
+static __dead void command __P((void));
+
+static void getusage __P((char *));
+static void makeargv __P((void));
+static void putusage __P((char *));
+static void settftpmode __P((char *));
+
+#define HELPINDENT (sizeof("connect"))
+
+struct cmd {
+	char	*name;
+	char	*help;
+	void	(*handler) __P((int, char **));
+};
+
+char	vhelp[] = "toggle verbose mode";
+char	thelp[] = "toggle packet tracing";
+char	chelp[] = "connect to remote tftp";
+char	qhelp[] = "exit tftp";
+char	hhelp[] = "print help information";
+char	shelp[] = "send file";
+char	rhelp[] = "receive file";
+char	mhelp[] = "set file transfer mode";
+char	sthelp[] = "show current status";
+char	xhelp[] = "set per-packet retransmission timeout";
+char	ihelp[] = "set total retransmission timeout";
+char    ashelp[] = "set mode to netascii";
+char    bnhelp[] = "set mode to octet";
+
+struct cmd cmdtab[] = {
+	{ "connect",	chelp,		setpeer },
+	{ "mode",       mhelp,          modecmd },
+	{ "put",	shelp,		put },
+	{ "get",	rhelp,		get },
+	{ "quit",	qhelp,		quit },
+	{ "verbose",	vhelp,		setverbose },
+	{ "trace",	thelp,		settrace },
+	{ "status",	sthelp,		status },
+	{ "binary",     bnhelp,         setbinary },
+	{ "ascii",      ashelp,         setascii },
+	{ "rexmt",	xhelp,		setrexmt },
+	{ "timeout",	ihelp,		settimeout },
+	{ "?",		hhelp,		help },
+	{ 0 }
+};
+
+struct	cmd *getcmd();
+char	*tail();
+char	*index();
+char	*rindex();
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct sockaddr_in sin;
+
+	sp = getservbyname("tftp", "udp");
+	if (sp == 0) {
+		fprintf(stderr, "tftp: udp/tftp: unknown service\n");
+		exit(1);
+	}
+	f = socket(AF_INET, SOCK_DGRAM, 0);
+	if (f < 0) {
+		perror("tftp: socket");
+		exit(3);
+	}
+	bzero((char *)&sin, sizeof(sin));
+	sin.sin_family = AF_INET;
+	if (bind(f, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+		perror("tftp: bind");
+		exit(1);
+	}
+	strcpy(mode, "netascii");
+	signal(SIGINT, intr);
+	if (argc > 1) {
+		if (setjmp(toplevel) != 0)
+			exit(0);
+		setpeer(argc, argv);
+	}
+	if (setjmp(toplevel) != 0)
+		(void)putchar('\n');
+	command();
+}
+
+char    hostname[100];
+
+void
+setpeer(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct hostent *host;
+
+	if (argc < 2) {
+		strcpy(line, "Connect ");
+		printf("(to) ");
+		fgets(&line[strlen(line)], BUFSIZ-strlen(line)-1, stdin);
+		makeargv();
+		argc = margc;
+		argv = margv;
+	}
+	if (argc > 3) {
+		printf("usage: %s host-name [port]\n", argv[0]);
+		return;
+	}
+	host = gethostbyname(argv[1]);
+	if (host) {
+		peeraddr.sin_family = host->h_addrtype;
+		bcopy(host->h_addr, &peeraddr.sin_addr, host->h_length);
+		strcpy(hostname, host->h_name);
+	} else {
+		peeraddr.sin_family = AF_INET;
+		peeraddr.sin_addr.s_addr = inet_addr(argv[1]);
+		if (peeraddr.sin_addr.s_addr == -1) {
+			connected = 0;
+			printf("%s: unknown host\n", argv[1]);
+			return;
+		}
+		strcpy(hostname, argv[1]);
+	}
+	port = sp->s_port;
+	if (argc == 3) {
+		port = atoi(argv[2]);
+		if (port < 0) {
+			printf("%s: bad port number\n", argv[2]);
+			connected = 0;
+			return;
+		}
+		port = htons(port);
+	}
+	connected = 1;
+}
+
+struct	modes {
+	char *m_name;
+	char *m_mode;
+} modes[] = {
+	{ "ascii",	"netascii" },
+	{ "netascii",   "netascii" },
+	{ "binary",     "octet" },
+	{ "image",      "octet" },
+	{ "octet",     "octet" },
+/*      { "mail",       "mail" },       */
+	{ 0,		0 }
+};
+
+void
+modecmd(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register struct modes *p;
+	char *sep;
+
+	if (argc < 2) {
+		printf("Using %s mode to transfer files.\n", mode);
+		return;
+	}
+	if (argc == 2) {
+		for (p = modes; p->m_name; p++)
+			if (strcmp(argv[1], p->m_name) == 0)
+				break;
+		if (p->m_name) {
+			settftpmode(p->m_mode);
+			return;
+		}
+		printf("%s: unknown mode\n", argv[1]);
+		/* drop through and print usage message */
+	}
+
+	printf("usage: %s [", argv[0]);
+	sep = " ";
+	for (p = modes; p->m_name; p++) {
+		printf("%s%s", sep, p->m_name);
+		if (*sep == ' ')
+			sep = " | ";
+	}
+	printf(" ]\n");
+	return;
+}
+
+void
+setbinary(argc, argv)
+	int argc;
+	char *argv[];
+{      
+
+	settftpmode("octet");
+}
+
+void
+setascii(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	settftpmode("netascii");
+}
+
+static void
+settftpmode(newmode)
+	char *newmode;
+{
+	strcpy(mode, newmode);
+	if (verbose)
+		printf("mode set to %s\n", mode);
+}
+
+
+/*
+ * Send file(s).
+ */
+void
+put(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int fd;
+	register int n;
+	register char *cp, *targ;
+
+	if (argc < 2) {
+		strcpy(line, "send ");
+		printf("(file) ");
+		fgets(&line[strlen(line)], BUFSIZ-strlen(line)-1, stdin);
+		makeargv();
+		argc = margc;
+		argv = margv;
+	}
+	if (argc < 2) {
+		putusage(argv[0]);
+		return;
+	}
+	targ = argv[argc - 1];
+	if (index(argv[argc - 1], ':')) {
+		char *cp;
+		struct hostent *hp;
+
+		for (n = 1; n < argc - 1; n++)
+			if (index(argv[n], ':')) {
+				putusage(argv[0]);
+				return;
+			}
+		cp = argv[argc - 1];
+		targ = index(cp, ':');
+		*targ++ = 0;
+		hp = gethostbyname(cp);
+		if (hp == NULL) {
+			fprintf(stderr, "tftp: %s: ", cp);
+			herror((char *)NULL);
+			return;
+		}
+		bcopy(hp->h_addr, (caddr_t)&peeraddr.sin_addr, hp->h_length);
+		peeraddr.sin_family = hp->h_addrtype;
+		connected = 1;
+		strcpy(hostname, hp->h_name);
+	}
+	if (!connected) {
+		printf("No target machine specified.\n");
+		return;
+	}
+	if (argc < 4) {
+		cp = argc == 2 ? tail(targ) : argv[1];
+		fd = open(cp, O_RDONLY);
+		if (fd < 0) {
+			fprintf(stderr, "tftp: "); perror(cp);
+			return;
+		}
+		if (verbose)
+			printf("putting %s to %s:%s [%s]\n",
+				cp, hostname, targ, mode);
+		peeraddr.sin_port = port;
+		tftp_sendfile(fd, targ, mode);
+		return;
+	}
+				/* this assumes the target is a directory */
+				/* on a remote unix system.  hmmmm.  */
+	cp = index(targ, '\0'); 
+	*cp++ = '/';
+	for (n = 1; n < argc - 1; n++) {
+		strcpy(cp, tail(argv[n]));
+		fd = open(argv[n], O_RDONLY);
+		if (fd < 0) {
+			fprintf(stderr, "tftp: "); perror(argv[n]);
+			continue;
+		}
+		if (verbose)
+			printf("putting %s to %s:%s [%s]\n",
+				argv[n], hostname, targ, mode);
+		peeraddr.sin_port = port;
+		tftp_sendfile(fd, targ, mode);
+	}
+}
+
+static void
+putusage(s)
+	char *s;
+{
+	printf("usage: %s file ... host:target, or\n", s);
+	printf("       %s file ... target (when already connected)\n", s);
+}
+
+/*
+ * Receive file(s).
+ */
+void
+get(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int fd;
+	register int n;
+	register char *cp;
+	char *src;
+
+	if (argc < 2) {
+		strcpy(line, "get ");
+		printf("(files) ");
+		fgets(&line[strlen(line)], BUFSIZ-strlen(line)-1, stdin);
+		makeargv();
+		argc = margc;
+		argv = margv;
+	}
+	if (argc < 2) {
+		getusage(argv[0]);
+		return;
+	}
+	if (!connected) {
+		for (n = 1; n < argc ; n++)
+			if (index(argv[n], ':') == 0) {
+				getusage(argv[0]);
+				return;
+			}
+	}
+	for (n = 1; n < argc ; n++) {
+		src = index(argv[n], ':');
+		if (src == NULL)
+			src = argv[n];
+		else {
+			struct hostent *hp;
+
+			*src++ = 0;
+			hp = gethostbyname(argv[n]);
+			if (hp == NULL) {
+				fprintf(stderr, "tftp: %s: ", argv[n]);
+				herror((char *)NULL);
+				continue;
+			}
+			bcopy(hp->h_addr, (caddr_t)&peeraddr.sin_addr,
+			    hp->h_length);
+			peeraddr.sin_family = hp->h_addrtype;
+			connected = 1;
+			strcpy(hostname, hp->h_name);
+		}
+		if (argc < 4) {
+			cp = argc == 3 ? argv[2] : tail(src);
+			fd = creat(cp, 0644);
+			if (fd < 0) {
+				fprintf(stderr, "tftp: "); perror(cp);
+				return;
+			}
+			if (verbose)
+				printf("getting from %s:%s to %s [%s]\n",
+					hostname, src, cp, mode);
+			peeraddr.sin_port = port;
+			recvfile(fd, src, mode);
+			break;
+		}
+		cp = tail(src);         /* new .. jdg */
+		fd = creat(cp, 0644);
+		if (fd < 0) {
+			fprintf(stderr, "tftp: "); perror(cp);
+			continue;
+		}
+		if (verbose)
+			printf("getting from %s:%s to %s [%s]\n",
+				hostname, src, cp, mode);
+		peeraddr.sin_port = port;
+		recvfile(fd, src, mode);
+	}
+}
+
+static void
+getusage(s)
+	char *s;
+{
+	printf("usage: %s host:file host:file ... file, or\n", s);
+	printf("       %s file file ... file if connected\n", s);
+}
+
+int	rexmtval = TIMEOUT;
+
+void
+setrexmt(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int t;
+
+	if (argc < 2) {
+		strcpy(line, "Rexmt-timeout ");
+		printf("(value) ");
+		fgets(&line[strlen(line)], BUFSIZ-strlen(line)-1, stdin);
+		makeargv();
+		argc = margc;
+		argv = margv;
+	}
+	if (argc != 2) {
+		printf("usage: %s value\n", argv[0]);
+		return;
+	}
+	t = atoi(argv[1]);
+	if (t < 0)
+		printf("%s: bad value\n", argv[1]);
+	else
+		rexmtval = t;
+}
+
+int	maxtimeout = 5 * TIMEOUT;
+
+void
+settimeout(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int t;
+
+	if (argc < 2) {
+		strcpy(line, "Maximum-timeout ");
+		printf("(value) ");
+		fgets(&line[strlen(line)], BUFSIZ-strlen(line)-1, stdin);
+		makeargv();
+		argc = margc;
+		argv = margv;
+	}
+	if (argc != 2) {
+		printf("usage: %s value\n", argv[0]);
+		return;
+	}
+	t = atoi(argv[1]);
+	if (t < 0)
+		printf("%s: bad value\n", argv[1]);
+	else
+		maxtimeout = t;
+}
+
+void
+status(argc, argv)
+	int argc;
+	char *argv[];
+{
+	if (connected)
+		printf("Connected to %s.\n", hostname);
+	else
+		printf("Not connected.\n");
+	printf("Mode: %s Verbose: %s Tracing: %s\n", mode,
+		verbose ? "on" : "off", trace ? "on" : "off");
+	printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n",
+		rexmtval, maxtimeout);
+}
+
+void
+intr()
+{
+
+	signal(SIGALRM, SIG_IGN);
+	alarm(0);
+	longjmp(toplevel, -1);
+}
+
+char *
+tail(filename)
+	char *filename;
+{
+	register char *s;
+	
+	while (*filename) {
+		s = rindex(filename, '/');
+		if (s == NULL)
+			break;
+		if (s[1])
+			return (s + 1);
+		*s = '\0';
+	}
+	return (filename);
+}
+
+/*
+ * Command parser.
+ */
+static __dead void
+command()
+{
+	register struct cmd *c;
+
+	for (;;) {
+		printf("%s> ", prompt);
+		if (fgets(line, BUFSIZ-1, stdin) == 0) {
+			if (feof(stdin)) {
+				exit(0);
+			} else {
+				continue;
+			}
+		}
+		if (line[0] == 0)
+			continue;
+		makeargv();
+		if (margc == 0)
+			continue;
+		c = getcmd(margv[0]);
+		if (c == (struct cmd *)-1) {
+			printf("?Ambiguous command\n");
+			continue;
+		}
+		if (c == 0) {
+			printf("?Invalid command\n");
+			continue;
+		}
+		(*c->handler)(margc, margv);
+	}
+}
+
+struct cmd *
+getcmd(name)
+	register char *name;
+{
+	register char *p, *q;
+	register struct cmd *c, *found;
+	register int nmatches, longest;
+
+	longest = 0;
+	nmatches = 0;
+	found = 0;
+	for (c = cmdtab; (p = c->name) != NULL; c++) {
+		for (q = name; *q == *p++; q++)
+			if (*q == 0)		/* exact match? */
+				return (c);
+		if (!*q) {			/* the name was a prefix */
+			if (q - name > longest) {
+				longest = q - name;
+				nmatches = 1;
+				found = c;
+			} else if (q - name == longest)
+				nmatches++;
+		}
+	}
+	if (nmatches > 1)
+		return ((struct cmd *)-1);
+	return (found);
+}
+
+/*
+ * Slice a string up into argc/argv.
+ */
+static void
+makeargv()
+{
+	register char *cp;
+	register char **argp = margv;
+
+	margc = 0;
+	for (cp = line; *cp;) {
+		while (isspace(*cp))
+			cp++;
+		if (*cp == '\0')
+			break;
+		*argp++ = cp;
+		margc += 1;
+		while (*cp != '\0' && !isspace(*cp))
+			cp++;
+		if (*cp == '\0')
+			break;
+		*cp++ = '\0';
+	}
+	*argp++ = 0;
+}
+
+void
+quit(argc, argv)
+	int argc;
+	char *argv[];
+{
+
+	exit(0);
+}
+
+/*
+ * Help command.
+ */
+void
+help(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register struct cmd *c;
+
+	if (argc == 1) {
+		printf("Commands may be abbreviated.  Commands are:\n\n");
+		for (c = cmdtab; c->name; c++)
+			printf("%-*s\t%s\n", (int)HELPINDENT, c->name, c->help);
+		return;
+	}
+	while (--argc > 0) {
+		register char *arg;
+		arg = *++argv;
+		c = getcmd(arg);
+		if (c == (struct cmd *)-1)
+			printf("?Ambiguous help command %s\n", arg);
+		else if (c == (struct cmd *)0)
+			printf("?Invalid help command %s\n", arg);
+		else
+			printf("%s\n", c->help);
+	}
+}
+
+void
+settrace(argc, argv)
+	int argc;
+	char **argv;
+{
+	trace = !trace;
+	printf("Packet tracing %s.\n", trace ? "on" : "off");
+}
+
+void
+setverbose(argc, argv)
+	int argc;
+	char **argv;
+{
+	verbose = !verbose;
+	printf("Verbose mode %s.\n", verbose ? "on" : "off");
+}
diff --git a/tftp.tproj/tftp.1 b/tftp.tproj/tftp.1
new file mode 100644
index 0000000..b2c5a16
--- /dev/null
+++ b/tftp.tproj/tftp.1
@@ -0,0 +1,173 @@
+.\" Copyright (c) 1990, 1993, 1994
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)tftp.1	8.2 (Berkeley) 4/18/94
+.\"
+.Dd April 18, 1994
+.Dt TFTP 1
+.Os BSD 4.3
+.Sh NAME
+.Nm tftp
+.Nd trivial file transfer program
+.Sh SYNOPSIS
+.Nm tftp
+.Op Ar host
+.Sh DESCRIPTION
+.Nm Tftp
+is the user interface to the Internet
+.Tn TFTP
+(Trivial File Transfer Protocol),
+which allows users to transfer files to and from a remote machine.
+The remote
+.Ar host
+may be specified on the command line, in which case
+.Nm tftp
+uses
+.Ar host
+as the default host for future transfers (see the
+.Cm connect
+command below).
+.Sh COMMANDS
+Once
+.Nm tftp
+is running, it issues the prompt
+.LI tftp>
+and recognizes the following commands:
+.Pp
+.Bl -tag -width verbose -compact
+.It Cm \&? Ar command-name ...
+Print help information.
+.Pp
+.It Cm ascii
+Shorthand for "mode ascii"
+.Pp
+.It Cm binary
+Shorthand for "mode binary"
+.Pp
+.It Cm connect Ar host-name Op Ar port
+Set the
+.Ar host
+(and optionally
+.Ar port )
+for transfers.
+Note that the
+.Tn TFTP
+protocol, unlike the
+.Tn FTP
+protocol,
+does not maintain connections between transfers; thus, the
+.Cm connect
+command does not actually create a connection,
+but merely remembers what host is to be used for transfers.
+You do not have to use the 
+.Cm connect
+command; the remote host can be specified as part of the
+.Cm get
+or
+.Cm put
+commands.
+.Pp
+.It Cm get Ar filename
+.It Cm get Ar remotename localname
+.It Cm get Ar file1 file2 ...  fileN
+Get a file or set of files from the specified
+.Ar sources .
+.Ar Source
+can be in one of two forms:
+a filename on the remote host, if the host has already been specified,
+or a string of the form
+.Ar hosts:filename
+to specify both a host and filename at the same time.
+If the latter form is used,
+the last hostname specified becomes the default for future transfers.
+.Pp
+.It Cm mode Ar transfer-mode
+Set the mode for transfers; 
+.Ar transfer-mode
+may be one of
+.Em ascii
+or
+.Em binary .
+The default is
+.Em ascii .
+.Pp
+.It Cm put Ar file
+.It Cm put Ar localfile remotefile
+.It Cm put Ar file1 file2 ... fileN remote-directory
+Put a file or set of files to the specified
+remote file or directory.
+The destination
+can be in one of two forms:
+a filename on the remote host, if the host has already been specified,
+or a string of the form
+.Ar hosts:filename
+to specify both a host and filename at the same time.
+If the latter form is used,
+the hostname specified becomes the default for future transfers.
+If the remote-directory form is used, the remote host is
+assumed to be a
+.Tn UNIX
+machine.
+.Pp
+.It Cm quit
+Exit
+.Nm tftp .
+An end of file also exits.
+.Pp
+.It Cm rexmt Ar retransmission-timeout
+Set the per-packet retransmission timeout, in seconds.
+.Pp
+.It Cm status
+Show current status.
+.Pp
+.It Cm timeout Ar total-transmission-timeout
+Set the total transmission timeout, in seconds.
+.Pp
+.It Cm trace
+Toggle packet tracing.
+.Pp
+.It Cm verbose
+Toggle verbose mode.
+.El
+.Sh BUGS
+.Pp
+Because there is no user-login or validation within
+the
+.Tn TFTP
+protocol, the remote site will probably have some
+sort of file-access restrictions in place.  The
+exact methods are specific to each site and therefore
+difficult to document here.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 .
diff --git a/tftp.tproj/tftp.c b/tftp.tproj/tftp.c
new file mode 100644
index 0000000..bec2978
--- /dev/null
+++ b/tftp.tproj/tftp.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/* Many bug fixes are from Jim Guyton <guyton@rand-unix> */
+
+/*
+ * TFTP User Program -- Protocol Machines
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <arpa/tftp.h>
+
+#include <errno.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "extern.h"
+#include "tftpsubs.h"
+
+extern	int errno;
+
+extern  struct sockaddr_in peeraddr;	/* filled in by main */
+extern  int     f;			/* the opened socket */
+extern  int     trace;
+extern  int     verbose;
+extern  int     rexmtval;
+extern  int     maxtimeout;
+
+extern jmp_buf	toplevel;	/* filled in by main */
+
+#define PKTSIZE    SEGSIZE+4
+char    ackbuf[PKTSIZE];
+int	timeout;
+jmp_buf	timeoutbuf;
+
+static void nak __P((int));
+static int makerequest __P((int, const char *, struct tftphdr *, const char *));
+static void printstats __P((const char *, unsigned long));
+static void startclock __P((void));
+static void stopclock __P((void));
+static void timer __P((int));
+static void tpacket __P((const char *, struct tftphdr *, int));
+
+/*
+ * Send the requested file.
+ */
+void
+tftp_sendfile(fd, name, mode)
+	int fd;
+	char *name;
+	char *mode;
+{
+	register struct tftphdr *ap;	   /* data and ack packets */
+	struct tftphdr *r_init(), *dp;
+	register int n;
+	volatile int block, size, convert;
+	volatile unsigned long amount;
+	struct sockaddr_in from;
+	int fromlen;
+	FILE *file;
+
+	startclock();		/* start stat's clock */
+	dp = r_init();		/* reset fillbuf/read-ahead code */
+	ap = (struct tftphdr *)ackbuf;
+	file = fdopen(fd, "r");
+	convert = !strcmp(mode, "netascii");
+	block = 0;
+	amount = 0;
+
+	signal(SIGALRM, timer);
+	do {
+		if (block == 0)
+			size = makerequest(WRQ, name, dp, mode) - 4;
+		else {
+		/*	size = read(fd, dp->th_data, SEGSIZE);	 */
+			size = readit(file, &dp, convert);
+			if (size < 0) {
+				nak(errno + 100);
+				break;
+			}
+			dp->th_opcode = htons((u_short)DATA);
+			dp->th_block = htons((u_short)block);
+		}
+		timeout = 0;
+		(void) setjmp(timeoutbuf);
+send_data:
+		if (trace)
+			tpacket("sent", dp, size + 4);
+		n = sendto(f, dp, size + 4, 0,
+		    (struct sockaddr *)&peeraddr, sizeof(peeraddr));
+		if (n != size + 4) {
+			perror("tftp: sendto");
+			goto abort;
+		}
+		read_ahead(file, convert);
+		for ( ; ; ) {
+			alarm(rexmtval);
+			do {
+				fromlen = sizeof(from);
+				n = recvfrom(f, ackbuf, sizeof(ackbuf), 0,
+				    (struct sockaddr *)&from, &fromlen);
+			} while (n <= 0);
+			alarm(0);
+			if (n < 0) {
+				perror("tftp: recvfrom");
+				goto abort;
+			}
+			peeraddr.sin_port = from.sin_port;	/* added */
+			if (trace)
+				tpacket("received", ap, n);
+			/* should verify packet came from server */
+			ap->th_opcode = ntohs(ap->th_opcode);
+			ap->th_block = ntohs(ap->th_block);
+			if (ap->th_opcode == ERROR) {
+				printf("Error code %d: %s\n", ap->th_code,
+					ap->th_msg);
+				goto abort;
+			}
+			if (ap->th_opcode == ACK) {
+				int j;
+
+				if (ap->th_block == block) {
+					break;
+				}
+				/* On an error, try to synchronize
+				 * both sides.
+				 */
+				j = synchnet(f);
+				if (j && trace) {
+					printf("discarded %d packets\n",
+							j);
+				}
+				if (ap->th_block == (block-1)) {
+					goto send_data;
+				}
+			}
+		}
+		if (block > 0)
+			amount += size;
+		block++;
+	} while (size == SEGSIZE || block == 1);
+abort:
+	fclose(file);
+	stopclock();
+	if (amount > 0)
+		printstats("Sent", amount);
+}
+
+/*
+ * Receive a file.
+ */
+void
+recvfile(fd, name, mode)
+	int fd;
+	char *name;
+	char *mode;
+{
+	register struct tftphdr *ap;
+	struct tftphdr *dp, *w_init();
+	register int n;
+	volatile int block, size, firsttrip;
+	volatile unsigned long amount;
+	struct sockaddr_in from;
+	int fromlen;
+	FILE *file;
+	volatile int convert;		/* true if converting crlf -> lf */
+
+	startclock();
+	dp = w_init();
+	ap = (struct tftphdr *)ackbuf;
+	file = fdopen(fd, "w");
+	convert = !strcmp(mode, "netascii");
+	block = 1;
+	firsttrip = 1;
+	amount = 0;
+
+	signal(SIGALRM, timer);
+	do {
+		if (firsttrip) {
+			size = makerequest(RRQ, name, ap, mode);
+			firsttrip = 0;
+		} else {
+			ap->th_opcode = htons((u_short)ACK);
+			ap->th_block = htons((u_short)(block));
+			size = 4;
+			block++;
+		}
+		timeout = 0;
+		(void) setjmp(timeoutbuf);
+send_ack:
+		if (trace)
+			tpacket("sent", ap, size);
+		if (sendto(f, ackbuf, size, 0, (struct sockaddr *)&peeraddr,
+		    sizeof(peeraddr)) != size) {
+			alarm(0);
+			perror("tftp: sendto");
+			goto abort;
+		}
+		write_behind(file, convert);
+		for ( ; ; ) {
+			alarm(rexmtval);
+			do  {
+				fromlen = sizeof(from);
+				n = recvfrom(f, dp, PKTSIZE, 0,
+				    (struct sockaddr *)&from, &fromlen);
+			} while (n <= 0);
+			alarm(0);
+			if (n < 0) {
+				perror("tftp: recvfrom");
+				goto abort;
+			}
+			peeraddr.sin_port = from.sin_port;	/* added */
+			if (trace)
+				tpacket("received", dp, n);
+			/* should verify client address */
+			dp->th_opcode = ntohs(dp->th_opcode);
+			dp->th_block = ntohs(dp->th_block);
+			if (dp->th_opcode == ERROR) {
+				printf("Error code %d: %s\n", dp->th_code,
+					dp->th_msg);
+				goto abort;
+			}
+			if (dp->th_opcode == DATA) {
+				int j;
+
+				if (dp->th_block == block) {
+					break;		/* have next packet */
+				}
+				/* On an error, try to synchronize
+				 * both sides.
+				 */
+				j = synchnet(f);
+				if (j && trace) {
+					printf("discarded %d packets\n", j);
+				}
+				if (dp->th_block == (block-1)) {
+					goto send_ack;	/* resend ack */
+				}
+			}
+		}
+	/*	size = write(fd, dp->th_data, n - 4); */
+		size = writeit(file, &dp, n - 4, convert);
+		if (size < 0) {
+			nak(errno + 100);
+			break;
+		}
+		amount += size;
+	} while (size == SEGSIZE);
+abort:						/* ok to ack, since user */
+	ap->th_opcode = htons((u_short)ACK);	/* has seen err msg */
+	ap->th_block = htons((u_short)block);
+	(void) sendto(f, ackbuf, 4, 0, (struct sockaddr *)&peeraddr,
+	    sizeof(peeraddr));
+	write_behind(file, convert);		/* flush last buffer */
+	fclose(file);
+	stopclock();
+	if (amount > 0)
+		printstats("Received", amount);
+}
+
+static int
+makerequest(request, name, tp, mode)
+	int request;
+	const char *name;
+	struct tftphdr *tp;
+	const char *mode;
+{
+	register char *cp;
+
+	tp->th_opcode = htons((u_short)request);
+	cp = tp->th_stuff;
+	strcpy(cp, name);
+	cp += strlen(name);
+	*cp++ = '\0';
+	strcpy(cp, mode);
+	cp += strlen(mode);
+	*cp++ = '\0';
+	return (cp - (char *)tp);
+}
+
+struct errmsg {
+	int	e_code;
+	char	*e_msg;
+} errmsgs[] = {
+	{ EUNDEF,	"Undefined error code" },
+	{ ENOTFOUND,	"File not found" },
+	{ EACCESS,	"Access violation" },
+	{ ENOSPACE,	"Disk full or allocation exceeded" },
+	{ EBADOP,	"Illegal TFTP operation" },
+	{ EBADID,	"Unknown transfer ID" },
+	{ EEXISTS,	"File already exists" },
+	{ ENOUSER,	"No such user" },
+	{ -1,		0 }
+};
+
+/*
+ * Send a nak packet (error message).
+ * Error code passed in is one of the
+ * standard TFTP codes, or a UNIX errno
+ * offset by 100.
+ */
+static void
+nak(error)
+	int error;
+{
+	register struct errmsg *pe;
+	register struct tftphdr *tp;
+	int length;
+	char *strerror();
+
+	tp = (struct tftphdr *)ackbuf;
+	tp->th_opcode = htons((u_short)ERROR);
+	tp->th_code = htons((u_short)error);
+	for (pe = errmsgs; pe->e_code >= 0; pe++)
+		if (pe->e_code == error)
+			break;
+	if (pe->e_code < 0) {
+		pe->e_msg = strerror(error - 100);
+		tp->th_code = EUNDEF;
+	}
+	strcpy(tp->th_msg, pe->e_msg);
+	length = strlen(pe->e_msg) + 4;
+	if (trace)
+		tpacket("sent", tp, length);
+	if (sendto(f, ackbuf, length, 0, (struct sockaddr *)&peeraddr,
+	    sizeof(peeraddr)) != length)
+		perror("nak");
+}
+
+static void
+tpacket(s, tp, n)
+	const char *s;
+	struct tftphdr *tp;
+	int n;
+{
+	static char *opcodes[] =
+	   { "#0", "RRQ", "WRQ", "DATA", "ACK", "ERROR" };
+	register char *cp, *file;
+	u_short op = ntohs(tp->th_opcode);
+	char *index();
+
+	if (op < RRQ || op > ERROR)
+		printf("%s opcode=%x ", s, op);
+	else
+		printf("%s %s ", s, opcodes[op]);
+	switch (op) {
+
+	case RRQ:
+	case WRQ:
+		n -= 2;
+		file = cp = tp->th_stuff;
+		cp = index(cp, '\0');
+		printf("<file=%s, mode=%s>\n", file, cp + 1);
+		break;
+
+	case DATA:
+		printf("<block=%d, %d bytes>\n", ntohs(tp->th_block), n - 4);
+		break;
+
+	case ACK:
+		printf("<block=%d>\n", ntohs(tp->th_block));
+		break;
+
+	case ERROR:
+		printf("<code=%d, msg=%s>\n", ntohs(tp->th_code), tp->th_msg);
+		break;
+	}
+}
+
+struct timeval tstart;
+struct timeval tstop;
+
+static void
+startclock()
+{
+
+	(void)gettimeofday(&tstart, NULL);
+}
+
+static void
+stopclock()
+{
+
+	(void)gettimeofday(&tstop, NULL);
+}
+
+static void
+printstats(direction, amount)
+	const char *direction;
+	unsigned long amount;
+{
+	double delta;
+			/* compute delta in 1/10's second units */
+	delta = ((tstop.tv_sec*10.)+(tstop.tv_usec/100000)) -
+		((tstart.tv_sec*10.)+(tstart.tv_usec/100000));
+	delta = delta/10.;      /* back to seconds */
+	printf("%s %d bytes in %.1f seconds", direction, amount, delta);
+	if (verbose)
+		printf(" [%.0f bits/sec]", (amount*8.)/delta);
+	putchar('\n');
+}
+
+static void
+timer(sig)
+	int sig;
+{
+
+	timeout += rexmtval;
+	if (timeout >= maxtimeout) {
+		printf("Transfer timed out.\n");
+		longjmp(toplevel, -1);
+	}
+	longjmp(timeoutbuf, 1);
+}
diff --git a/tftp.tproj/tftpsubs.c b/tftp.tproj/tftpsubs.c
new file mode 100644
index 0000000..f63504a
--- /dev/null
+++ b/tftp.tproj/tftpsubs.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/* Simple minded read-ahead/write-behind subroutines for tftp user and
+   server.  Written originally with multiple buffers in mind, but current
+   implementation has two buffer logic wired in.
+
+   Todo:  add some sort of final error check so when the write-buffer
+   is finally flushed, the caller can detect if the disk filled up
+   (or had an i/o error) and return a nak to the other side.
+
+			Jim Guyton 10/85
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/tftp.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "tftpsubs.h"
+
+#define PKTSIZE SEGSIZE+4       /* should be moved to tftp.h */
+
+struct bf {
+	int counter;            /* size of data in buffer, or flag */
+	char buf[PKTSIZE];      /* room for data packet */
+} bfs[2];
+
+				/* Values for bf.counter  */
+#define BF_ALLOC -3             /* alloc'd but not yet filled */
+#define BF_FREE  -2             /* free */
+/* [-1 .. SEGSIZE] = size of data in the data buffer */
+
+static int nextone;		/* index of next buffer to use */
+static int current;		/* index of buffer in use */
+
+				/* control flags for crlf conversions */
+int newline = 0;		/* fillbuf: in middle of newline expansion */
+int prevchar = -1;		/* putbuf: previous char (cr check) */
+
+static struct tftphdr *rw_init();
+
+struct tftphdr *w_init() { return rw_init(0); }         /* write-behind */
+struct tftphdr *r_init() { return rw_init(1); }         /* read-ahead */
+
+static struct tftphdr *
+rw_init(x)			/* init for either read-ahead or write-behind */
+	int x;			/* zero for write-behind, one for read-head */
+{
+	newline = 0;		/* init crlf flag */
+	prevchar = -1;
+	bfs[0].counter =  BF_ALLOC;     /* pass out the first buffer */
+	current = 0;
+	bfs[1].counter = BF_FREE;
+	nextone = x;                    /* ahead or behind? */
+	return (struct tftphdr *)bfs[0].buf;
+}
+
+
+/* Have emptied current buffer by sending to net and getting ack.
+   Free it and return next buffer filled with data.
+ */
+int
+readit(file, dpp, convert)
+	FILE *file;                     /* file opened for read */
+	struct tftphdr **dpp;
+	int convert;                    /* if true, convert to ascii */
+{
+	struct bf *b;
+
+	bfs[current].counter = BF_FREE; /* free old one */
+	current = !current;             /* "incr" current */
+
+	b = &bfs[current];              /* look at new buffer */
+	if (b->counter == BF_FREE)      /* if it's empty */
+		read_ahead(file, convert);      /* fill it */
+/*      assert(b->counter != BF_FREE);*//* check */
+	*dpp = (struct tftphdr *)b->buf;        /* set caller's ptr */
+	return b->counter;
+}
+
+/*
+ * fill the input buffer, doing ascii conversions if requested
+ * conversions are  lf -> cr,lf  and cr -> cr, nul
+ */
+void
+read_ahead(file, convert)
+	FILE *file;                     /* file opened for read */
+	int convert;                    /* if true, convert to ascii */
+{
+	register int i;
+	register char *p;
+	register int c;
+	struct bf *b;
+	struct tftphdr *dp;
+
+	b = &bfs[nextone];              /* look at "next" buffer */
+	if (b->counter != BF_FREE)      /* nop if not free */
+		return;
+	nextone = !nextone;             /* "incr" next buffer ptr */
+
+	dp = (struct tftphdr *)b->buf;
+
+	if (convert == 0) {
+		b->counter = read(fileno(file), dp->th_data, SEGSIZE);
+		return;
+	}
+
+	p = dp->th_data;
+	for (i = 0 ; i < SEGSIZE; i++) {
+		if (newline) {
+			if (prevchar == '\n')
+				c = '\n';       /* lf to cr,lf */
+			else    c = '\0';       /* cr to cr,nul */
+			newline = 0;
+		}
+		else {
+			c = getc(file);
+			if (c == EOF) break;
+			if (c == '\n' || c == '\r') {
+				prevchar = c;
+				c = '\r';
+				newline = 1;
+			}
+		}
+	       *p++ = c;
+	}
+	b->counter = (int)(p - dp->th_data);
+}
+
+/* Update count associated with the buffer, get new buffer
+   from the queue.  Calls write_behind only if next buffer not
+   available.
+ */
+int
+writeit(file, dpp, ct, convert)
+	FILE *file;
+	struct tftphdr **dpp;
+	int ct, convert;
+{
+	bfs[current].counter = ct;      /* set size of data to write */
+	current = !current;             /* switch to other buffer */
+	if (bfs[current].counter != BF_FREE)     /* if not free */
+		(void)write_behind(file, convert); /* flush it */
+	bfs[current].counter = BF_ALLOC;        /* mark as alloc'd */
+	*dpp =  (struct tftphdr *)bfs[current].buf;
+	return ct;                      /* this is a lie of course */
+}
+
+/*
+ * Output a buffer to a file, converting from netascii if requested.
+ * CR,NUL -> CR  and CR,LF => LF.
+ * Note spec is undefined if we get CR as last byte of file or a
+ * CR followed by anything else.  In this case we leave it alone.
+ */
+int
+write_behind(file, convert)
+	FILE *file;
+	int convert;
+{
+	char *buf;
+	int count;
+	register int ct;
+	register char *p;
+	register int c;                 /* current character */
+	struct bf *b;
+	struct tftphdr *dp;
+
+	b = &bfs[nextone];
+	if (b->counter < -1)            /* anything to flush? */
+		return 0;               /* just nop if nothing to do */
+
+	count = b->counter;             /* remember byte count */
+	b->counter = BF_FREE;           /* reset flag */
+	dp = (struct tftphdr *)b->buf;
+	nextone = !nextone;             /* incr for next time */
+	buf = dp->th_data;
+
+	if (count <= 0) return -1;      /* nak logic? */
+
+	if (convert == 0)
+		return write(fileno(file), buf, count);
+
+	p = buf;
+	ct = count;
+	while (ct--) {                  /* loop over the buffer */
+	    c = *p++;                   /* pick up a character */
+	    if (prevchar == '\r') {     /* if prev char was cr */
+		if (c == '\n')          /* if have cr,lf then just */
+		   fseek(file, -1, 1);  /* smash lf on top of the cr */
+		else
+		   if (c == '\0')       /* if have cr,nul then */
+			goto skipit;    /* just skip over the putc */
+		/* else just fall through and allow it */
+	    }
+	    putc(c, file);
+skipit:
+	    prevchar = c;
+	}
+	return count;
+}
+
+
+/* When an error has occurred, it is possible that the two sides
+ * are out of synch.  Ie: that what I think is the other side's
+ * response to packet N is really their response to packet N-1.
+ *
+ * So, to try to prevent that, we flush all the input queued up
+ * for us on the network connection on our host.
+ *
+ * We return the number of packets we flushed (mostly for reporting
+ * when trace is active).
+ */
+
+int
+synchnet(f)
+	int	f;		/* socket to flush */
+{
+	int i, j = 0;
+	char rbuf[PKTSIZE];
+	struct sockaddr_in from;
+	int fromlen;
+
+	while (1) {
+		(void) ioctl(f, FIONREAD, &i);
+		if (i) {
+			j++;
+			fromlen = sizeof from;
+			(void) recvfrom(f, rbuf, sizeof (rbuf), 0,
+				(struct sockaddr *)&from, &fromlen);
+		} else {
+			return(j);
+		}
+	}
+}
diff --git a/tftp.tproj/tftpsubs.h b/tftp.tproj/tftpsubs.h
new file mode 100644
index 0000000..9ecb2d2
--- /dev/null
+++ b/tftp.tproj/tftpsubs.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)tftpsubs.h	8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Prototypes for read-ahead/write-behind subroutines for tftp user and
+ * server.
+ */
+struct tftphdr *r_init __P((void));
+void	read_ahead __P((FILE *, int));
+int	readit __P((FILE *, struct tftphdr **, int));
+
+int	synchnet __P((int));
+
+struct tftphdr *w_init __P((void));
+int	write_behind __P((FILE *, int));
+int	writeit __P((FILE *, struct tftphdr **, int, int));
diff --git a/tftpd.tproj/Makefile b/tftpd.tproj/Makefile
new file mode 100644
index 0000000..8ce74c9
--- /dev/null
+++ b/tftpd.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = tftpd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = tftpd.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble tftpd.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+HEADER_PATHS = -I../tftp.tproj
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/tftpd.tproj/Makefile.postamble b/tftpd.tproj/Makefile.postamble
new file mode 100644
index 0000000..382a280
--- /dev/null
+++ b/tftpd.tproj/Makefile.postamble
@@ -0,0 +1,112 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
+VPATH += :../tftp.tproj
diff --git a/tftpd.tproj/Makefile.preamble b/tftpd.tproj/Makefile.preamble
new file mode 100644
index 0000000..8a2e16a
--- /dev/null
+++ b/tftpd.tproj/Makefile.preamble
@@ -0,0 +1,121 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS = 
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR = 
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+OTHER_OFILES = tftpsubs.o
+
+-include ../Makefile.include
diff --git a/tftpd.tproj/PB.project b/tftpd.tproj/PB.project
new file mode 100644
index 0000000..39cfa7e
--- /dev/null
+++ b/tftpd.tproj/PB.project
@@ -0,0 +1,41 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        HEADERSEARCH = (../tftp.tproj); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (tftpd.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, tftpd.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_DOCUMENTEXTENSIONS = (); 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = tftpd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/tftpd.tproj/tftpd.8 b/tftpd.tproj/tftpd.8
new file mode 100644
index 0000000..430c1c4
--- /dev/null
+++ b/tftpd.tproj/tftpd.8
@@ -0,0 +1,106 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)tftpd.8	8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt TFTPD 8
+.Os BSD 4.2
+.Sh NAME
+.Nm tftpd
+.Nd
+Internet Trivial File Transfer Protocol server
+.Sh SYNOPSIS
+.Nm tftpd
+.Op Fl l
+.Op Fl n
+.Op Ar directory ...
+.Sh DESCRIPTION
+.Nm Tftpd
+is a server which supports the
+Internet Trivial File Transfer
+Protocol (\c
+.Tn RFC 783).
+The
+.Tn TFTP
+server operates
+at the port indicated in the
+.Ql tftp
+service description;
+see
+.Xr services 5 .
+The server is normally started by
+.Xr inetd 8 .
+.Pp
+The use of
+.Xr tftp 1
+does not require an account or password on the remote system.
+Due to the lack of authentication information, 
+.Nm tftpd
+will allow only publicly readable files to be
+accessed.
+Files containing the string ``/\|\fB.\|.\fP\|/'' are not allowed.
+Files may be written only if they already exist and are publicly writable.
+Note that this extends the concept of
+.Dq public
+to include
+all users on all hosts that can be reached through the network;
+this may not be appropriate on all systems, and its implications
+should be considered before enabling tftp service.
+The server should have the user ID with the lowest possible privilege.
+.Pp
+Access to files may be restricted by invoking
+.Nm tftpd
+with a list of directories by including up to 20 pathnames
+as server program arguments in
+.Pa /etc/inetd.conf .
+In this case access is restricted to files whose
+names are prefixed by the one of the given directories.
+The given directories are also treated as a search path for 
+relative filename requests.
+.Pp
+The options are:
+.Bl -tag -width Ds
+.It Fl l
+Logs all requests using
+.Xr syslog 3 .
+.It Fl n
+Suppresses negative acknowledgement of requests for nonexistent
+relative filenames.
+.El
+.Sh SEE ALSO
+.Xr tftp 1 ,
+.Xr inetd 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/tftpd.tproj/tftpd.c b/tftpd.tproj/tftpd.c
new file mode 100644
index 0000000..f73cb56
--- /dev/null
+++ b/tftpd.tproj/tftpd.c
@@ -0,0 +1,673 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)tftpd.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * Trivial file transfer protocol server.
+ *
+ * This version includes many modifications by Jim Guyton
+ * <guyton@rand-unix>.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/tftp.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "tftpsubs.h"
+
+#define	TIMEOUT		5
+
+int	peer;
+int	rexmtval = TIMEOUT;
+int	maxtimeout = 5*TIMEOUT;
+
+#define	PKTSIZE	SEGSIZE+4
+char	buf[PKTSIZE];
+char	ackbuf[PKTSIZE];
+struct	sockaddr_in from;
+int	fromlen;
+
+void	tftp __P((struct tftphdr *, int));
+
+/*
+ * Null-terminated directory prefix list for absolute pathname requests and
+ * search list for relative pathname requests.
+ *
+ * MAXDIRS should be at least as large as the number of arguments that
+ * inetd allows (currently 20).
+ */
+#define MAXDIRS	20
+static struct dirlist {
+	char	*name;
+	int	len;
+} dirs[MAXDIRS+1];
+static int	suppress_naks;
+static int	logging;
+
+static char *errtomsg __P((int));
+static void  nak __P((int));
+static char *verifyhost __P((struct sockaddr_in *));
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register struct tftphdr *tp;
+	register int n;
+	int ch, on;
+	struct sockaddr_in sin;
+
+	openlog("tftpd", LOG_PID, LOG_FTP);
+	while ((ch = getopt(argc, argv, "ln")) != EOF) {
+		switch (ch) {
+		case 'l':
+			logging = 1;
+			break;
+		case 'n':
+			suppress_naks = 1;
+			break;
+		default:
+			syslog(LOG_WARNING, "ignoring unknown option -%c", ch);
+		}
+	}
+	if (optind < argc) {
+		struct dirlist *dirp;
+
+		/* Get list of directory prefixes. Skip relative pathnames. */
+		for (dirp = dirs; optind < argc && dirp < &dirs[MAXDIRS];
+		     optind++) {
+			if (argv[optind][0] == '/') {
+				dirp->name = argv[optind];
+				dirp->len  = strlen(dirp->name);
+				dirp++;
+			}
+		}
+	}
+
+	on = 1;
+	if (ioctl(0, FIONBIO, &on) < 0) {
+		syslog(LOG_ERR, "ioctl(FIONBIO): %m\n");
+		exit(1);
+	}
+	fromlen = sizeof (from);
+	n = recvfrom(0, buf, sizeof (buf), 0,
+	    (struct sockaddr *)&from, &fromlen);
+	if (n < 0) {
+		syslog(LOG_ERR, "recvfrom: %m\n");
+		exit(1);
+	}
+	/*
+	 * Now that we have read the message out of the UDP
+	 * socket, we fork and exit.  Thus, inetd will go back
+	 * to listening to the tftp port, and the next request
+	 * to come in will start up a new instance of tftpd.
+	 *
+	 * We do this so that inetd can run tftpd in "wait" mode.
+	 * The problem with tftpd running in "nowait" mode is that
+	 * inetd may get one or more successful "selects" on the
+	 * tftp port before we do our receive, so more than one
+	 * instance of tftpd may be started up.  Worse, if tftpd
+	 * break before doing the above "recvfrom", inetd would
+	 * spawn endless instances, clogging the system.
+	 */
+	{
+		int pid;
+		int i, j;
+
+		for (i = 1; i < 20; i++) {
+		    pid = fork();
+		    if (pid < 0) {
+				sleep(i);
+				/*
+				 * flush out to most recently sent request.
+				 *
+				 * This may drop some request, but those
+				 * will be resent by the clients when
+				 * they timeout.  The positive effect of
+				 * this flush is to (try to) prevent more
+				 * than one tftpd being started up to service
+				 * a single request from a single client.
+				 */
+				j = sizeof from;
+				i = recvfrom(0, buf, sizeof (buf), 0,
+				    (struct sockaddr *)&from, &j);
+				if (i > 0) {
+					n = i;
+					fromlen = j;
+				}
+		    } else {
+				break;
+		    }
+		}
+		if (pid < 0) {
+			syslog(LOG_ERR, "fork: %m\n");
+			exit(1);
+		} else if (pid != 0) {
+			exit(0);
+		}
+	}
+	from.sin_family = AF_INET;
+	alarm(0);
+	close(0);
+	close(1);
+	peer = socket(AF_INET, SOCK_DGRAM, 0);
+	if (peer < 0) {
+		syslog(LOG_ERR, "socket: %m\n");
+		exit(1);
+	}
+	memset(&sin, 0, sizeof(sin));
+	sin.sin_family = AF_INET;
+	if (bind(peer, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
+		syslog(LOG_ERR, "bind: %m\n");
+		exit(1);
+	}
+	if (connect(peer, (struct sockaddr *)&from, sizeof(from)) < 0) {
+		syslog(LOG_ERR, "connect: %m\n");
+		exit(1);
+	}
+	tp = (struct tftphdr *)buf;
+	tp->th_opcode = ntohs(tp->th_opcode);
+	if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
+		tftp(tp, n);
+	exit(1);
+}
+
+struct formats;
+int	validate_access __P((char **, int));
+void	tftp_sendfile __P((struct formats *));
+void	recvfile __P((struct formats *));
+
+struct formats {
+	char	*f_mode;
+	int	(*f_validate) __P((char **, int));
+	void	(*f_send) __P((struct formats *));
+	void	(*f_recv) __P((struct formats *));
+	int	f_convert;
+} formats[] = {
+	{ "netascii",	validate_access,	tftp_sendfile,	recvfile, 1 },
+	{ "octet",	validate_access,	tftp_sendfile,	recvfile, 0 },
+#ifdef notdef
+	{ "mail",	validate_user,		sendmail,	recvmail, 1 },
+#endif
+	{ 0 }
+};
+
+/*
+ * Handle initial connection protocol.
+ */
+void
+tftp(tp, size)
+	struct tftphdr *tp;
+	int size;
+{
+	register char *cp;
+	int first = 1, ecode;
+	register struct formats *pf;
+	char *filename, *mode;
+
+	filename = cp = tp->th_stuff;
+again:
+	while (cp < buf + size) {
+		if (*cp == '\0')
+			break;
+		cp++;
+	}
+	if (*cp != '\0') {
+		nak(EBADOP);
+		exit(1);
+	}
+	if (first) {
+		mode = ++cp;
+		first = 0;
+		goto again;
+	}
+	for (cp = mode; *cp; cp++)
+		if (isupper(*cp))
+			*cp = tolower(*cp);
+	for (pf = formats; pf->f_mode; pf++)
+		if (strcmp(pf->f_mode, mode) == 0)
+			break;
+	if (pf->f_mode == 0) {
+		nak(EBADOP);
+		exit(1);
+	}
+	ecode = (*pf->f_validate)(&filename, tp->th_opcode);
+	if (logging) {
+		syslog(LOG_INFO, "%s: %s request for %s: %s",
+			verifyhost(&from),
+			tp->th_opcode == WRQ ? "write" : "read",
+			filename, errtomsg(ecode));
+	}
+	if (ecode) {
+		/*
+		 * Avoid storms of naks to a RRQ broadcast for a relative
+		 * bootfile pathname from a diskless Sun.
+		 */
+		if (suppress_naks && *filename != '/' && ecode == ENOTFOUND)
+			exit(0);
+		nak(ecode);
+		exit(1);
+	}
+	if (tp->th_opcode == WRQ)
+		(*pf->f_recv)(pf);
+	else
+		(*pf->f_send)(pf);
+	exit(0);
+}
+
+
+FILE *file;
+
+/*
+ * Validate file access.  Since we
+ * have no uid or gid, for now require
+ * file to exist and be publicly
+ * readable/writable.
+ * If we were invoked with arguments
+ * from inetd then the file must also be
+ * in one of the given directory prefixes.
+ * Note also, full path name must be
+ * given as we have no login directory.
+ */
+int
+validate_access(filep, mode)
+	char **filep;
+	int mode;
+{
+	struct stat stbuf;
+	int	fd;
+	struct dirlist *dirp;
+	static char pathname[MAXPATHLEN];
+	char *filename = *filep;
+
+	/*
+	 * Prevent tricksters from getting around the directory restrictions
+	 */
+	if (strstr(filename, "/../"))
+		return (EACCESS);
+
+	if (*filename == '/') {
+		/*
+		 * Allow the request if it's in one of the approved locations.
+		 * Special case: check the null prefix ("/") by looking
+		 * for length = 1 and relying on the arg. processing that
+		 * it's a /.
+		 */
+		for (dirp = dirs; dirp->name != NULL; dirp++) {
+			if (dirp->len == 1 ||
+			    (!strncmp(filename, dirp->name, dirp->len) &&
+			     filename[dirp->len] == '/'))
+				    break;
+		}
+		/* If directory list is empty, allow access to any file */
+		if (dirp->name == NULL && dirp != dirs)
+			return (EACCESS);
+		if (stat(filename, &stbuf) < 0)
+			return (errno == ENOENT ? ENOTFOUND : EACCESS);
+		if ((stbuf.st_mode & S_IFMT) != S_IFREG)
+			return (ENOTFOUND);
+		if (mode == RRQ) {
+			if ((stbuf.st_mode & S_IROTH) == 0)
+				return (EACCESS);
+		} else {
+			if ((stbuf.st_mode & S_IWOTH) == 0)
+				return (EACCESS);
+		}
+	} else {
+		int err;
+
+		/*
+		 * Relative file name: search the approved locations for it.
+		 * Don't allow write requests or ones that avoid directory
+		 * restrictions.
+		 */
+
+		if (mode != RRQ || !strncmp(filename, "../", 3))
+			return (EACCESS);
+
+		/*
+		 * If the file exists in one of the directories and isn't
+		 * readable, continue looking. However, change the error code
+		 * to give an indication that the file exists.
+		 */
+		err = ENOTFOUND;
+		for (dirp = dirs; dirp->name != NULL; dirp++) {
+			sprintf(pathname, "%s/%s", dirp->name, filename);
+			if (stat(pathname, &stbuf) == 0 &&
+			    (stbuf.st_mode & S_IFMT) == S_IFREG) {
+				if ((stbuf.st_mode & S_IROTH) != 0) {
+					break;
+				}
+				err = EACCESS;
+			}
+		}
+		if (dirp->name == NULL)
+			return (err);
+		*filep = filename = pathname;
+	}
+	fd = open(filename, mode == RRQ ? 0 : 1);
+	if (fd < 0)
+		return (errno + 100);
+	file = fdopen(fd, (mode == RRQ)? "r":"w");
+	if (file == NULL) {
+		return errno+100;
+	}
+	return (0);
+}
+
+int	timeout;
+jmp_buf	timeoutbuf;
+
+void
+timer()
+{
+
+	timeout += rexmtval;
+	if (timeout >= maxtimeout)
+		exit(1);
+	longjmp(timeoutbuf, 1);
+}
+
+/*
+ * Send the requested file.
+ */
+void
+tftp_sendfile(pf)
+	struct formats *pf;
+{
+	struct tftphdr *dp, *r_init();
+	register struct tftphdr *ap;    /* ack packet */
+	register int size, n;
+	volatile int block;
+
+	signal(SIGALRM, timer);
+	dp = r_init();
+	ap = (struct tftphdr *)ackbuf;
+	block = 1;
+	do {
+		size = readit(file, &dp, pf->f_convert);
+		if (size < 0) {
+			nak(errno + 100);
+			goto abort;
+		}
+		dp->th_opcode = htons((u_short)DATA);
+		dp->th_block = htons((u_short)block);
+		timeout = 0;
+		(void)setjmp(timeoutbuf);
+
+send_data:
+		if (send(peer, dp, size + 4, 0) != size + 4) {
+			syslog(LOG_ERR, "tftpd: write: %m\n");
+			goto abort;
+		}
+		read_ahead(file, pf->f_convert);
+		for ( ; ; ) {
+			alarm(rexmtval);        /* read the ack */
+			n = recv(peer, ackbuf, sizeof (ackbuf), 0);
+			alarm(0);
+			if (n < 0) {
+				syslog(LOG_ERR, "tftpd: read: %m\n");
+				goto abort;
+			}
+			ap->th_opcode = ntohs((u_short)ap->th_opcode);
+			ap->th_block = ntohs((u_short)ap->th_block);
+
+			if (ap->th_opcode == ERROR)
+				goto abort;
+
+			if (ap->th_opcode == ACK) {
+				if (ap->th_block == block)
+					break;
+				/* Re-synchronize with the other side */
+				(void) synchnet(peer);
+				if (ap->th_block == (block -1))
+					goto send_data;
+			}
+
+		}
+		block++;
+	} while (size == SEGSIZE);
+abort:
+	(void) fclose(file);
+}
+
+void
+justquit()
+{
+	exit(0);
+}
+
+
+/*
+ * Receive a file.
+ */
+void
+recvfile(pf)
+	struct formats *pf;
+{
+	struct tftphdr *dp, *w_init();
+	register struct tftphdr *ap;    /* ack buffer */
+	register int n, size;
+	volatile int block;
+
+	signal(SIGALRM, timer);
+	dp = w_init();
+	ap = (struct tftphdr *)ackbuf;
+	block = 0;
+	do {
+		timeout = 0;
+		ap->th_opcode = htons((u_short)ACK);
+		ap->th_block = htons((u_short)block);
+		block++;
+		(void) setjmp(timeoutbuf);
+send_ack:
+		if (send(peer, ackbuf, 4, 0) != 4) {
+			syslog(LOG_ERR, "tftpd: write: %m\n");
+			goto abort;
+		}
+		write_behind(file, pf->f_convert);
+		for ( ; ; ) {
+			alarm(rexmtval);
+			n = recv(peer, dp, PKTSIZE, 0);
+			alarm(0);
+			if (n < 0) {            /* really? */
+				syslog(LOG_ERR, "tftpd: read: %m\n");
+				goto abort;
+			}
+			dp->th_opcode = ntohs((u_short)dp->th_opcode);
+			dp->th_block = ntohs((u_short)dp->th_block);
+			if (dp->th_opcode == ERROR)
+				goto abort;
+			if (dp->th_opcode == DATA) {
+				if (dp->th_block == block) {
+					break;   /* normal */
+				}
+				/* Re-synchronize with the other side */
+				(void) synchnet(peer);
+				if (dp->th_block == (block-1))
+					goto send_ack;          /* rexmit */
+			}
+		}
+		/*  size = write(file, dp->th_data, n - 4); */
+		size = writeit(file, &dp, n - 4, pf->f_convert);
+		if (size != (n-4)) {                    /* ahem */
+			if (size < 0) nak(errno + 100);
+			else nak(ENOSPACE);
+			goto abort;
+		}
+	} while (size == SEGSIZE);
+	write_behind(file, pf->f_convert);
+	(void) fclose(file);            /* close data file */
+
+	ap->th_opcode = htons((u_short)ACK);    /* send the "final" ack */
+	ap->th_block = htons((u_short)(block));
+	(void) send(peer, ackbuf, 4, 0);
+
+	signal(SIGALRM, justquit);      /* just quit on timeout */
+	alarm(rexmtval);
+	n = recv(peer, buf, sizeof (buf), 0); /* normally times out and quits */
+	alarm(0);
+	if (n >= 4 &&                   /* if read some data */
+	    dp->th_opcode == DATA &&    /* and got a data block */
+	    block == dp->th_block) {	/* then my last ack was lost */
+		(void) send(peer, ackbuf, 4, 0);     /* resend final ack */
+	}
+abort:
+	return;
+}
+
+struct errmsg {
+	int	e_code;
+	char	*e_msg;
+} errmsgs[] = {
+	{ EUNDEF,	"Undefined error code" },
+	{ ENOTFOUND,	"File not found" },
+	{ EACCESS,	"Access violation" },
+	{ ENOSPACE,	"Disk full or allocation exceeded" },
+	{ EBADOP,	"Illegal TFTP operation" },
+	{ EBADID,	"Unknown transfer ID" },
+	{ EEXISTS,	"File already exists" },
+	{ ENOUSER,	"No such user" },
+	{ -1,		0 }
+};
+
+static char *
+errtomsg(error)
+	int error;
+{
+	static char buf[20];
+	register struct errmsg *pe;
+	if (error == 0)
+		return "success";
+	for (pe = errmsgs; pe->e_code >= 0; pe++)
+		if (pe->e_code == error)
+			return pe->e_msg;
+	sprintf(buf, "error %d", error);
+	return buf;
+}
+
+/*
+ * Send a nak packet (error message).
+ * Error code passed in is one of the
+ * standard TFTP codes, or a UNIX errno
+ * offset by 100.
+ */
+static void
+nak(error)
+	int error;
+{
+	register struct tftphdr *tp;
+	int length;
+	register struct errmsg *pe;
+
+	tp = (struct tftphdr *)buf;
+	tp->th_opcode = htons((u_short)ERROR);
+	tp->th_code = htons((u_short)error);
+	for (pe = errmsgs; pe->e_code >= 0; pe++)
+		if (pe->e_code == error)
+			break;
+	if (pe->e_code < 0) {
+		pe->e_msg = strerror(error - 100);
+		tp->th_code = EUNDEF;   /* set 'undef' errorcode */
+	}
+	strcpy(tp->th_msg, pe->e_msg);
+	length = strlen(pe->e_msg);
+	tp->th_msg[length] = '\0';
+	length += 5;
+	if (send(peer, buf, length, 0) != length)
+		syslog(LOG_ERR, "nak: %m\n");
+}
+
+static char *
+verifyhost(fromp)
+	struct sockaddr_in *fromp;
+{
+	struct hostent *hp;
+
+	hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof (fromp->sin_addr),
+			    fromp->sin_family);
+	if (hp)
+		return hp->h_name;
+	else
+		return inet_ntoa(fromp->sin_addr);
+}
diff --git a/timed.tproj/Makefile b/timed.tproj/Makefile
new file mode 100644
index 0000000..fc8a78d
--- /dev/null
+++ b/timed.tproj/Makefile
@@ -0,0 +1,44 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = timed
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Aggregate
+
+TOOLS = timed.tproj timedc.tproj
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = aggregate.make
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/timed.tproj/Makefile.postamble b/timed.tproj/Makefile.postamble
new file mode 100644
index 0000000..18167b9
--- /dev/null
+++ b/timed.tproj/Makefile.postamble
@@ -0,0 +1,109 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
diff --git a/timed.tproj/Makefile.preamble b/timed.tproj/Makefile.preamble
new file mode 100644
index 0000000..cc5c371
--- /dev/null
+++ b/timed.tproj/Makefile.preamble
@@ -0,0 +1,121 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR = 
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libs to link against
+OTHER_LIBS = 
+# Additional libs to link against when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+-include ../Makefile.include
diff --git a/timed.tproj/PB.project b/timed.tproj/PB.project
new file mode 100644
index 0000000..624995d
--- /dev/null
+++ b/timed.tproj/PB.project
@@ -0,0 +1,21 @@
+{
+    FILESTABLE = {
+        H_FILES = (); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        SUBPROJECTS = (timed.tproj, timedc.tproj); 
+        TOOLS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_DOCUMENTEXTENSIONS = (); 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = timed; 
+    PROJECTTYPE = Aggregate; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/timed.tproj/timed.tproj/Makefile b/timed.tproj/timed.tproj/Makefile
new file mode 100644
index 0000000..8636bc9
--- /dev/null
+++ b/timed.tproj/timed.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = timed
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = extern.h globals.h pathnames.h
+
+CFILES = acksend.c byteorder.c candidate.c cksum.c correct.c master.c\
+         measure.c networkdelta.c readmsg.c slave.c timed.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble timed.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/timed.tproj/timed.tproj/Makefile.postamble b/timed.tproj/timed.tproj/Makefile.postamble
new file mode 100644
index 0000000..36381d4
--- /dev/null
+++ b/timed.tproj/timed.tproj/Makefile.postamble
@@ -0,0 +1,122 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
diff --git a/timed.tproj/timed.tproj/Makefile.preamble b/timed.tproj/timed.tproj/Makefile.preamble
new file mode 100644
index 0000000..74ce95a
--- /dev/null
+++ b/timed.tproj/timed.tproj/Makefile.preamble
@@ -0,0 +1,130 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES =
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
diff --git a/timed.tproj/timed.tproj/PB.project b/timed.tproj/timed.tproj/PB.project
new file mode 100644
index 0000000..e3accbc
--- /dev/null
+++ b/timed.tproj/timed.tproj/PB.project
@@ -0,0 +1,38 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (extern.h, globals.h, pathnames.h); 
+        OTHER_LINKED = (
+            acksend.c, 
+            byteorder.c, 
+            candidate.c, 
+            cksum.c, 
+            correct.c, 
+            master.c, 
+            measure.c, 
+            networkdelta.c, 
+            readmsg.c, 
+            slave.c, 
+            timed.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, timed.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = timed; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/timed.tproj/timed.tproj/acksend.c b/timed.tproj/timed.tproj/acksend.c
new file mode 100644
index 0000000..af1aea0
--- /dev/null
+++ b/timed.tproj/timed.tproj/acksend.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)acksend.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "globals.h"
+
+struct tsp *answer;
+
+extern u_short sequence;
+
+void
+xmit(type, seq, addr)
+	int type;
+	u_int seq;
+	struct sockaddr_in *addr;
+{
+	static struct tsp msg;
+
+	msg.tsp_type = type;
+	msg.tsp_seq = seq;
+	msg.tsp_vers = TSPVERSION;
+	(void)strcpy(msg.tsp_name, hostname);
+	bytenetorder(&msg);
+	if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0,
+		   (struct sockaddr*)addr, sizeof(struct sockaddr)) < 0) {
+		trace_sendto_err(addr->sin_addr);
+	}
+}
+
+
+/*
+ * Acksend implements reliable datagram transmission by using sequence
+ * numbers and retransmission when necessary.
+ * If `name' is ANYADDR, this routine implements reliable broadcast.
+ *
+ * Because this function calls readmsg(), none of its args may be in
+ *	a message provided by readmsg().
+ */
+struct tsp *
+acksend(message, addr, name, ack, net, bad)
+	struct tsp *message;			/* this message */
+	struct sockaddr_in *addr;		/* to here */
+	char *name;
+	int ack;				/* look for this ack */
+	struct netinfo *net;			/* receive from this network */
+	int bad;				/* 1=losing patience */
+{
+	struct timeval twait;
+	int count;
+	long msec;
+
+	message->tsp_vers = TSPVERSION;
+	message->tsp_seq = sequence;
+	if (trace) {
+		fprintf(fd, "acksend: to %s: ",
+			(name == ANYADDR ? "broadcast" : name));
+		print(message, addr);
+	}
+	bytenetorder(message);
+
+	msec = 200;
+	count = bad ? 1 : 5;	/* 5 packets in 6.4 seconds */
+	answer = 0;
+	do {
+		if (!answer) {
+			/* do not go crazy transmitting just because the
+			 * other guy cannot keep our sequence numbers
+			 * straight.
+			 */
+			if (sendto(sock, (char *)message, sizeof(struct tsp),
+				   0, (struct sockaddr*)addr,
+				   sizeof(struct sockaddr)) < 0) {
+				trace_sendto_err(addr->sin_addr);
+				break;
+			}
+		}
+
+		mstotvround(&twait, msec);
+		answer  = readmsg(ack, name, &twait, net);
+		if (answer != 0) {
+			if (answer->tsp_seq != sequence) {
+				if (trace)
+					fprintf(fd,"acksend: seq # %u!=%u\n",
+						answer->tsp_seq, sequence);
+				continue;
+			}
+			break;
+		}
+
+		msec *= 2;
+	} while (--count > 0);
+	sequence++;
+
+	return(answer);
+}
diff --git a/timed.tproj/timed.tproj/byteorder.c b/timed.tproj/timed.tproj/byteorder.c
new file mode 100644
index 0000000..97bb911
--- /dev/null
+++ b/timed.tproj/timed.tproj/byteorder.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)byteorder.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "globals.h"
+
+/*
+ * Two routines to do the necessary byte swapping for timed protocol
+ * messages. Protocol is defined in /usr/include/protocols/timed.h
+ */
+void
+bytenetorder(ptr)
+	struct tsp *ptr;
+{
+	ptr->tsp_seq = htons((u_short)ptr->tsp_seq);
+	switch (ptr->tsp_type) {
+
+	case TSP_SETTIME:
+	case TSP_ADJTIME:
+	case TSP_SETDATE:
+	case TSP_SETDATEREQ:
+		ptr->tsp_time.tv_sec = htonl((u_long)ptr->tsp_time.tv_sec);
+		ptr->tsp_time.tv_usec = htonl((u_long)ptr->tsp_time.tv_usec);
+		break;
+	
+	default:
+		break;		/* nothing more needed */
+	}
+}
+
+void
+bytehostorder(ptr)
+	struct tsp *ptr;
+{
+	ptr->tsp_seq = ntohs((u_short)ptr->tsp_seq);
+	switch (ptr->tsp_type) {
+
+	case TSP_SETTIME:
+	case TSP_ADJTIME:
+	case TSP_SETDATE:
+	case TSP_SETDATEREQ:
+		ptr->tsp_time.tv_sec = ntohl((u_long)ptr->tsp_time.tv_sec);
+		ptr->tsp_time.tv_usec = ntohl((u_long)ptr->tsp_time.tv_usec);
+		break;
+	
+	default:
+		break;		/* nothing more needed */
+	}
+}
diff --git a/timed.tproj/timed.tproj/candidate.c b/timed.tproj/timed.tproj/candidate.c
new file mode 100644
index 0000000..a271db5
--- /dev/null
+++ b/timed.tproj/timed.tproj/candidate.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)candidate.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "globals.h"
+
+/*
+ * `election' candidates a host as master: it is called by a slave
+ * which runs with the -M option set when its election timeout expires.
+ * Note the conservative approach: if a new timed comes up, or another
+ * candidate sends an election request, the candidature is withdrawn.
+ */
+int
+election(net)
+	struct netinfo *net;
+{
+	struct tsp *resp, msg;
+	struct timeval then, wait;
+	struct tsp *answer;
+	struct hosttbl *htp;
+	char loop_lim = 0;
+
+/* This code can get totally confused if it gets slightly behind.  For
+ *	example, if readmsg() has some QUIT messages waiting from the last
+ *	round, we would send an ELECTION message, get the stale QUIT,
+ *	and give up.  This results in network storms when several machines
+ *	do it at once.
+ */
+	wait.tv_sec = 0;
+	wait.tv_usec = 0;
+	while (0 != readmsg(TSP_REFUSE, ANYADDR, &wait, net)) {
+		if (trace)
+			fprintf(fd, "election: discarded stale REFUSE\n");
+	}
+	while (0 != readmsg(TSP_QUIT, ANYADDR, &wait, net)) {
+		if (trace)
+			fprintf(fd, "election: discarded stale QUIT\n");
+	}
+
+again:
+	syslog(LOG_INFO, "This machine is a candidate time master");
+	if (trace)
+		fprintf(fd, "This machine is a candidate time master\n");
+	msg.tsp_type = TSP_ELECTION;
+	msg.tsp_vers = TSPVERSION;
+	(void)strcpy(msg.tsp_name, hostname);
+	bytenetorder(&msg);
+	if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0,
+		   (struct sockaddr*)&net->dest_addr,
+		   sizeof(struct sockaddr)) < 0) {
+		trace_sendto_err(net->dest_addr.sin_addr);
+		return(SLAVE);
+	}
+
+	(void)gettimeofday(&then, 0);
+	then.tv_sec += 3;
+	for (;;) {
+		(void)gettimeofday(&wait, 0);
+		timevalsub(&wait,&then,&wait);
+		resp = readmsg(TSP_ANY, ANYADDR, &wait, net);
+		if (!resp)
+			return(MASTER);
+
+		switch (resp->tsp_type) {
+
+		case TSP_ACCEPT:
+			(void)addmach(resp->tsp_name, &from,fromnet);
+			break;
+
+		case TSP_MASTERUP:
+		case TSP_MASTERREQ:
+			/*
+			 * If another timedaemon is coming up at the same
+			 * time, give up, and let it be the master.
+			 */
+			if (++loop_lim < 5
+			    && !good_host_name(resp->tsp_name)) {
+				(void)addmach(resp->tsp_name, &from,fromnet);
+				suppress(&from, resp->tsp_name, net);
+				goto again;
+			}
+			rmnetmachs(net);
+			return(SLAVE);
+
+		case TSP_QUIT:
+		case TSP_REFUSE:
+			/*
+			 * Collision: change value of election timer
+			 * using exponential backoff. 
+			 *
+			 *  Fooey.
+			 * An exponential backoff on a delay starting at
+			 * 6 to 15 minutes for a process that takes
+			 * milliseconds is silly.  It is particularly
+			 * strange that the original code would increase
+			 * the backoff without bound.
+			 */
+			rmnetmachs(net);
+			return(SLAVE);
+
+		case TSP_ELECTION:
+			/* no master for another round */
+			htp = addmach(resp->tsp_name,&from,fromnet);
+			msg.tsp_type = TSP_REFUSE;
+			(void)strcpy(msg.tsp_name, hostname);
+			answer = acksend(&msg, &htp->addr, htp->name,
+					 TSP_ACK, 0, htp->noanswer);
+			if (!answer) {
+				syslog(LOG_ERR, "error in election from %s",
+				       htp->name);
+			}
+			break;
+
+		case TSP_SLAVEUP:
+			(void)addmach(resp->tsp_name, &from,fromnet);
+			break;
+
+		case TSP_SETDATE:
+		case TSP_SETDATEREQ:
+			break;
+
+		default:
+			if (trace) {
+				fprintf(fd, "candidate: ");
+				print(resp, &from);
+			}
+			break;
+		}
+	}
+}
diff --git a/timed.tproj/timed.tproj/cksum.c b/timed.tproj/timed.tproj/cksum.c
new file mode 100644
index 0000000..e50e438
--- /dev/null
+++ b/timed.tproj/timed.tproj/cksum.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cksum.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include <sys/types.h>
+
+/*
+ *			I N _ C K S U M
+ *
+ * Checksum routine for Internet Protocol family headers (C Version)
+ *
+ * There is no profit in a specialized version of the checksum
+ * function for any machine where int's are 32 bits and shorts are 16.
+ *
+ * All timed packets are smaller than 32K shorts, so there is no need to
+ * worry about carries except at the end.
+ */
+int
+in_cksum(addr, len)
+	u_short *addr;
+	int len;
+{
+	register int nleft = len;
+	register u_short *w = addr;
+	register u_short answer;
+	register int sum = 0;
+
+	/*
+	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
+	 *  we add sequential 16 bit words to it, and at the end, fold
+	 *  back all the carry bits from the top 16 bits into the lower
+	 *  16 bits.
+	 */
+	while( nleft > 1 )  {
+		sum += *w++;
+		nleft -= 2;
+	}
+
+	/* mop up an odd byte, if necessary */
+	if( nleft == 1 )
+		sum += (*(u_char *)w) << 8;
+
+	/*
+	 * add back carry outs from top 16 bits to low 16 bits
+	 */
+	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
+	sum += (sum >> 16);			/* add carry */
+	answer = ~sum;				/* truncate to 16 bits */
+	return (answer);
+}
diff --git a/timed.tproj/timed.tproj/correct.c b/timed.tproj/timed.tproj/correct.c
new file mode 100644
index 0000000..f092bca
--- /dev/null
+++ b/timed.tproj/timed.tproj/correct.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)correct.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "globals.h"
+#include <math.h>
+#include <sys/types.h>
+#include <sys/times.h>
+#ifdef sgi
+#include <sys/syssgi.h>
+#endif /* sgi */
+
+static void adjclock __P((struct timeval *));
+
+/*
+ * sends to the slaves the corrections for their clocks after fixing our
+ * own
+ */
+void
+correct(avdelta)
+	long avdelta;
+{
+	struct hosttbl *htp;
+	int corr;
+	struct timeval adjlocal;
+	struct tsp to;
+	struct tsp *answer;
+
+	mstotvround(&adjlocal, avdelta);
+
+	for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {
+		if (htp->delta != HOSTDOWN)  {
+			corr = avdelta - htp->delta;
+/* If the other machine is off in the weeds, set its time directly.
+ *	If a slave gets the wrong day, the original code would simply
+ *	fix the minutes.  If you fix a network partition, you can get
+ *	into such situations.
+ */
+			if (htp->need_set
+			    || corr >= MAXADJ*1000
+			    || corr <= -MAXADJ*1000) {
+				htp->need_set = 0;
+				(void)gettimeofday(&to.tsp_time,0);
+				timevaladd(&to.tsp_time, &adjlocal);
+				to.tsp_type = TSP_SETTIME;
+			} else {
+				mstotvround(&to.tsp_time, corr);
+				to.tsp_type = TSP_ADJTIME;
+			}
+			(void)strcpy(to.tsp_name, hostname);
+			answer = acksend(&to, &htp->addr, htp->name,
+					 TSP_ACK, 0, 0);
+			if (!answer) {
+				htp->delta = HOSTDOWN;
+				syslog(LOG_WARNING,
+				       "no reply to time correction from %s",
+				       htp->name);
+				if (++htp->noanswer >= LOSTHOST) {
+					if (trace) {
+						fprintf(fd,
+					     "purging %s for not answering\n",
+							htp->name);
+						(void)fflush(fd);
+					}
+					htp = remmach(htp);
+				}
+			}
+		}
+	}
+
+	/*
+	 * adjust our own clock now that we are not sending it out
+	 */
+	adjclock(&adjlocal);
+}
+
+
+static void
+adjclock(corr)
+	struct timeval *corr;
+{
+	static int passes = 0;
+	static int smoother = 0;
+	long delta;			/* adjustment in usec */
+	long ndelta;
+	struct timeval now;
+	struct timeval adj;
+
+	if (!timerisset(corr))
+		return;
+
+	adj = *corr;
+	if (adj.tv_sec < MAXADJ && adj.tv_sec > - MAXADJ) {
+		delta = adj.tv_sec*1000000 + adj.tv_usec;
+		/* If the correction is less than the minimum round
+		 *	trip time for an ICMP packet, and thus
+		 *	less than the likely error in the measurement,
+		 *	do not do the entire correction.  Do half
+		 *	or a quarter of it.
+		 */
+
+		if (delta > -MIN_ROUND*1000
+		    && delta < MIN_ROUND*1000) {
+			if (smoother <= 4)
+				smoother++;
+			ndelta = delta >> smoother;
+			if (trace)
+				fprintf(fd,
+					"trimming delta %ld usec to %ld\n",
+					delta, ndelta);
+			adj.tv_usec = ndelta;
+			adj.tv_sec = 0;
+		} else if (smoother > 0) {
+			smoother--;
+		}
+		if (0 > adjtime(corr, 0)) {
+			syslog(LOG_ERR, "adjtime: %m");
+		}
+		if (passes > 1
+		    && (delta < -BIG_ADJ || delta > BIG_ADJ)) {
+			smoother = 0;
+			passes = 0;
+			syslog(LOG_WARNING,
+			       "large time adjustment of %+.3f sec",
+			       delta/1000000.0);
+		}
+	} else {
+		syslog(LOG_WARNING,
+		       "clock correction %d sec too large to adjust",
+		       adj.tv_sec);
+		(void) gettimeofday(&now, 0);
+		timevaladd(&now, corr);
+		if (settimeofday(&now, 0) < 0)
+			syslog(LOG_ERR, "settimeofday: %m");
+	}
+
+#ifdef sgi
+	/* Accumulate the total change, and use it to adjust the basic
+	 * clock rate.
+	 */
+	if (++passes > 2) {
+#define F_USEC_PER_SEC	(1000000*1.0)	/* reduce typos */
+#define F_NSEC_PER_SEC	(F_USEC_PER_SEC*1000.0)
+
+		extern char *timetrim_fn;
+		extern char *timetrim_wpat;
+		extern long timetrim;
+		extern double tot_adj, hr_adj;	/* totals in nsec */
+		extern double tot_ticks, hr_ticks;
+
+		static double nag_tick;
+		double cur_ticks, hr_delta_ticks, tot_delta_ticks;
+		double tru_tot_adj, tru_hr_adj; /* nsecs of adjustment */
+		double tot_trim, hr_trim;   /* nsec/sec */
+		struct tms tm;
+		FILE *timetrim_st;
+
+		cur_ticks = times(&tm);
+		tot_adj += delta*1000.0;
+		hr_adj += delta*1000.0;
+
+		tot_delta_ticks = cur_ticks-tot_ticks;
+		if (tot_delta_ticks >= 16*SECDAY*CLK_TCK) {
+			tot_adj -= rint(tot_adj/16);
+			tot_ticks += rint(tot_delta_ticks/16);
+			tot_delta_ticks = cur_ticks-tot_ticks;
+		}
+		hr_delta_ticks = cur_ticks-hr_ticks;
+
+		tru_hr_adj = hr_adj + timetrim*rint(hr_delta_ticks/CLK_TCK);
+		tru_tot_adj = (tot_adj
+			       + timetrim*rint(tot_delta_ticks/CLK_TCK));
+
+		if (hr_delta_ticks >= SECDAY*CLK_TCK
+		    || (tot_delta_ticks < 4*SECDAY*CLK_TCK
+			&& hr_delta_ticks >= SECHR*CLK_TCK)
+		    || (trace && hr_delta_ticks >= (SECHR/10)*CLK_TCK)) {
+
+			tot_trim = rint(tru_tot_adj*CLK_TCK/tot_delta_ticks);
+			hr_trim = rint(tru_hr_adj*CLK_TCK/hr_delta_ticks);
+
+			if (trace
+			    || (abs(timetrim - hr_trim) > 100000.0
+				&& 0 == timetrim_fn
+				&& ((cur_ticks - nag_tick)
+				    >= 24*SECDAY*CLK_TCK))) {
+				nag_tick = cur_ticks;
+				syslog(LOG_NOTICE,
+		   "%+.3f/%.2f or %+.3f/%.2f sec/hr; timetrim=%+.0f or %+.0f",
+				       tru_tot_adj/F_NSEC_PER_SEC,
+				       tot_delta_ticks/(SECHR*CLK_TCK*1.0),
+				       tru_hr_adj/F_NSEC_PER_SEC,
+				       hr_delta_ticks/(SECHR*CLK_TCK*1.0),
+				       tot_trim,
+				       hr_trim);
+			}
+
+			if (tot_trim < -MAX_TRIM || tot_trim > MAX_TRIM) {
+				tot_ticks = hr_ticks;
+				tot_adj = hr_adj;
+			} else if (0 > syssgi(SGI_SETTIMETRIM,
+					      (long)tot_trim)) {
+				syslog(LOG_ERR, "SETTIMETRIM(%d): %m",
+				       (long)tot_trim);
+			} else {
+				if (0 != timetrim_fn) {
+				    timetrim_st = fopen(timetrim_fn, "w");
+				    if (0 == timetrim_st) {
+					syslog(LOG_ERR, "fopen(%s): %m",
+					       timetrim_fn);
+				    } else {
+					if (0 > fprintf(timetrim_st,
+							timetrim_wpat,
+							(long)tot_trim,
+							tru_tot_adj,
+							tot_delta_ticks)) {
+						syslog(LOG_ERR,
+						       "fprintf(%s): %m",
+						       timetrim_fn);
+					}
+					(void)fclose(timetrim_st);
+				    }
+				}
+
+				tot_adj -= ((tot_trim - timetrim)
+					    * rint(tot_delta_ticks/CLK_TCK));
+				timetrim = tot_trim;
+			}
+
+			hr_ticks = cur_ticks;
+			hr_adj = 0;
+		}
+	}
+#endif /* sgi */
+}
+
+
+/* adjust the time in a message by the time it
+ *	spent in the queue
+ */
+void
+adj_msg_time(msg, now)
+	struct tsp *msg;
+	struct timeval *now;
+{
+	msg->tsp_time.tv_sec += (now->tv_sec - from_when.tv_sec);
+	msg->tsp_time.tv_usec += (now->tv_usec - from_when.tv_usec);
+
+	while (msg->tsp_time.tv_usec < 0) {
+		msg->tsp_time.tv_sec--;
+		msg->tsp_time.tv_usec += 1000000;
+	}
+	while (msg->tsp_time.tv_usec >= 1000000) {
+		msg->tsp_time.tv_sec++;
+		msg->tsp_time.tv_usec -= 1000000;
+	}
+}
diff --git a/timed.tproj/timed.tproj/extern.h b/timed.tproj/timed.tproj/extern.h
new file mode 100644
index 0000000..00f9d35
--- /dev/null
+++ b/timed.tproj/timed.tproj/extern.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)extern.h	8.1 (Berkeley) 6/6/93
+ */
+
+struct hosttbl;
+struct netinfo;
+struct sockaddr_in;
+struct timeval;
+struct tsp;
+
+struct hosttbl *addmach __P((char *, struct sockaddr_in *, struct netinfo *));
+struct hosttbl *findhost __P((char *));
+struct hosttbl *remmach __P((struct hosttbl *));
+
+struct tsp *readmsg __P((int,
+	    char *, struct timeval *, struct netinfo *));
+struct tsp *acksend __P((struct tsp *,
+	    struct sockaddr_in *, char *, int, struct netinfo *, int));
+
+void	 addnetname __P((char *));
+void	 adj_msg_time __P((struct tsp *, struct timeval *));
+void	 bytehostorder __P((struct tsp *));
+void	 bytenetorder __P((struct tsp *));
+void	 byteorder __P((struct tsp *));
+long	 casual __P((long, long));
+int	 cksum __P((u_short *, int));
+void	 correct __P((long));
+char	*date __P((void));
+void	 doquit __P((struct tsp *));
+int	 election __P((struct netinfo *));
+void	 get_goodgroup __P((int));
+int	 good_host_name __P((char *));
+void	 ignoreack __P((void));
+int	 in_cksum __P((u_short *, int));
+void	 lookformaster __P((struct netinfo *));
+void	 makeslave __P((struct netinfo *));
+int	 master __P((void));
+void	 masterack __P((void));
+void	 masterup __P((struct netinfo *));
+int	 measure __P((u_long, u_long, char *, struct sockaddr_in *, int));
+void	 msterup __P((struct netinfo *));
+void	 mstotvround __P((struct timeval *, long));
+long	 networkdelta __P((void));
+void	 newslave __P((struct tsp *));
+void	 print __P((struct tsp *, struct sockaddr_in *));
+void	 prthp __P((clock_t));
+void	 rmnetmachs __P((struct netinfo *));
+void	 setstatus __P((void));
+int	 slave __P((void));
+void	 slaveack __P((void));
+void	 spreadtime __P((void));
+void	 suppress __P((struct sockaddr_in *, char *, struct netinfo *));
+void	 synch __P((long));
+void	 timevaladd __P((struct timeval *, struct timeval *));
+void	 timevalsub __P((struct timeval *, struct timeval *, struct timeval *));
+void	 traceoff __P((char *));
+void	 traceon __P((void));
+void	 xmit __P((int, u_int, struct sockaddr_in *));
diff --git a/timed.tproj/timed.tproj/globals.h b/timed.tproj/timed.tproj/globals.h
new file mode 100644
index 0000000..82cfc53
--- /dev/null
+++ b/timed.tproj/timed.tproj/globals.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)globals.h	8.1 (Berkeley) 6/6/93
+ */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <protocols/timed.h>
+#ifdef sgi
+#include <bstring.h>
+#include <sys/clock.h>
+/* use the constant HZ instead of the function CLK_TCK */
+#undef CLK_TCK
+#define CLK_TCK HZ
+#else
+#define	SECHR	(60*60)
+#define	SECDAY	(24*SECHR)
+#endif /* sgi */
+
+extern int errno;
+extern int sock;
+
+/* Best expected round trip for a measurement.
+ * This is essentially the number of milliseconds per CPU tick (CLK_TCK?).
+ * All delays shorter than this are usually reported as 0.
+ */
+#define MIN_ROUND ((1000-1)/CLK_TCK)
+
+
+#define SAMPLEINTVL	240		/* synch() freq for master in sec */
+#define	MAXADJ		20		/* max adjtime() correction in sec */
+
+#define MAX_TRIM	3000000		/* max drift in nsec/sec, 0.3% */
+#define BIG_ADJ		(MAX_TRIM/1000*SAMPLEINTVL*2)	/* max good adj */
+
+#define MINTOUT		360		/* election delays, 6-15 minutes */
+#define MAXTOUT		900
+
+#define BAD_STATUS	(-1)
+#define GOOD		1
+#define UNREACHABLE	2
+#define NONSTDTIME	3
+#define HOSTDOWN	0x7fffffff
+
+#define OFF		0
+#define ON		1
+
+#define MAX_HOPCNT	10		/* max value for tsp_hpcnt */
+
+#define LOSTHOST	3		/* forget after this many failures */
+
+#define VALID_RANGE (MAXADJ*1000)	/* good times in milliseconds */
+#define GOOD_RANGE (MIN_ROUND*2)
+#define VGOOD_RANGE (MIN_ROUND-1)
+
+
+/*
+ * Global and per-network states.
+ */
+#define NOMASTER	0		/* no good master */
+#define SLAVE		1
+#define MASTER		2
+#define IGNORE		4
+#define ALL		(SLAVE|MASTER|IGNORE)
+#define SUBMASTER	(SLAVE|MASTER)
+
+#define NHOSTS		1013		/* max of hosts controlled by timed
+					 * This must be a prime number.
+					 */
+struct hosttbl {
+	struct	hosttbl *h_bak;		/* hash chain */
+	struct	hosttbl *h_fwd;
+	struct  hosttbl *l_bak;		/* "sequential" list */
+	struct  hosttbl *l_fwd;
+	struct	netinfo *ntp;
+	struct	sockaddr_in addr;
+	char	name[MAXHOSTNAMELEN+1];
+	u_char	head;			/* 1=head of hash chain */
+	u_char	good;			/* 0=trusted host, for averaging */
+	u_char	noanswer;		/* count of failures to answer */
+	u_char	need_set;		/* need a SETTIME */
+	u_short seq;
+	long	delta;
+};
+
+/* closed hash table with internal chaining */
+extern struct hosttbl hosttbl[NHOSTS+1];
+#define self hosttbl[0]
+#define hostname (self.name)
+
+
+struct netinfo {
+	struct	netinfo *next;
+	struct	in_addr net;
+	u_long	mask;
+	struct	in_addr my_addr;
+	struct	sockaddr_in dest_addr;	/* broadcast addr or point-point */
+	long	status;
+	struct timeval slvwait;		/* delay before sending our time */
+	int	quit_count;		/* recent QUITs */
+};
+
+#include "extern.h"
+
+#define tvtomsround(tv) ((tv).tv_sec*1000 + ((tv).tv_usec + 500)/1000)
+
+extern struct netinfo *nettab;
+extern int status;
+extern int trace;
+extern int sock;
+extern struct sockaddr_in from;
+extern struct timeval from_when;	/* when the last msg arrived */
+extern u_short sequence;		/* TSP message sequence number */
+extern struct netinfo *fromnet, *slavenet;
+extern FILE *fd;
+extern long delay1, delay2;
+extern int nslavenets;			/* nets were I could be a slave */
+extern int nmasternets;			/* nets were I could be a master */
+extern int nignorednets;		/* ignored nets */
+extern int nnets;			/* nets I am connected to */
+
+
+#define trace_msg(msg)		{if (trace) fprintf(fd, msg);}
+
+#define trace_sendto_err(addr) {					\
+	int st_errno = errno;						\
+	syslog(LOG_ERR, "%s %d: sendto %s: %m",				\
+		__FILE__, __LINE__, inet_ntoa(addr));			\
+	if (trace)							\
+		fprintf(fd, "%s %d: sendto %s: %d", __FILE__, __LINE__,	\
+			inet_ntoa(addr), st_errno);			\
+}
+
+
+# define max(a,b) 	(a<b ? b : a)
+# define min(a,b) 	(a>b ? b : a)
+# define abs(x)		(x>=0 ? x : -(x))
diff --git a/timed.tproj/timed.tproj/master.c b/timed.tproj/timed.tproj/master.c
new file mode 100644
index 0000000..ddd3215
--- /dev/null
+++ b/timed.tproj/timed.tproj/master.c
@@ -0,0 +1,930 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)master.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "globals.h"
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/times.h>
+#include <setjmp.h>
+#ifdef sgi
+#include <sys/schedctl.h>
+#endif /* sgi */
+#include <utmp.h>
+#include "pathnames.h"
+
+extern int measure_delta;
+extern jmp_buf jmpenv;
+extern int Mflag;
+extern int justquit;
+
+static int dictate;
+static int slvcount;			/* slaves listening to our clock */
+
+static void mchgdate __P((struct tsp *));
+
+#ifdef sgi
+extern void logwtmp __P((struct timeval *, struct timeval *));
+#else
+extern void logwtmp __P((char *, char *, char *));
+#endif /* sgi */
+
+/*
+ * The main function of `master' is to periodically compute the differences
+ * (deltas) between its clock and the clocks of the slaves, to compute the
+ * network average delta, and to send to the slaves the differences between
+ * their individual deltas and the network delta.
+ * While waiting, it receives messages from the slaves (i.e. requests for
+ * master's name, remote requests to set the network time, ...), and
+ * takes the appropriate action.
+ */
+int
+master()
+{
+	struct hosttbl *htp;
+	long pollingtime;
+#define POLLRATE 4
+	int polls;
+	struct timeval wait, ntime;
+	struct tsp *msg, *answer, to;
+	char newdate[32];
+	struct sockaddr_in taddr;
+	char tname[MAXHOSTNAMELEN];
+	struct netinfo *ntp;
+	int i;
+
+	syslog(LOG_NOTICE, "This machine is master");
+	if (trace)
+		fprintf(fd, "This machine is master\n");
+	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+		if (ntp->status == MASTER)
+			masterup(ntp);
+	}
+	(void)gettimeofday(&ntime, 0);
+	pollingtime = ntime.tv_sec+3;
+	if (justquit)
+		polls = 0;
+	else
+		polls = POLLRATE-1;
+
+/* Process all outstanding messages before spending the long time necessary
+ *	to update all timers.
+ */
+loop:
+	(void)gettimeofday(&ntime, 0);
+	wait.tv_sec = pollingtime - ntime.tv_sec;
+	if (wait.tv_sec < 0)
+		wait.tv_sec = 0;
+	wait.tv_usec = 0;
+	msg = readmsg(TSP_ANY, ANYADDR, &wait, 0);
+	if (!msg) {
+		(void)gettimeofday(&ntime, 0);
+		if (ntime.tv_sec >= pollingtime) {
+			pollingtime = ntime.tv_sec + SAMPLEINTVL;
+			get_goodgroup(0);
+
+/* If a bogus master told us to quit, we can have decided to ignore a
+ * network.  Therefore, periodically try to take over everything.
+ */
+			polls = (polls + 1) % POLLRATE;
+			if (0 == polls && nignorednets > 0) {
+				trace_msg("Looking for nets to re-master\n");
+				for (ntp = nettab; ntp; ntp = ntp->next) {
+					if (ntp->status == IGNORE
+					    || ntp->status == NOMASTER) {
+						lookformaster(ntp);
+						if (ntp->status == MASTER) {
+							masterup(ntp);
+							polls = POLLRATE-1;
+						}
+					}
+					if (ntp->status == MASTER
+					    && --ntp->quit_count < 0)
+						ntp->quit_count = 0;
+				}
+				if (polls != 0)
+					setstatus();
+			}
+
+			synch(0L);
+
+			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+				to.tsp_type = TSP_LOOP;
+				to.tsp_vers = TSPVERSION;
+				to.tsp_seq = sequence++;
+				to.tsp_hopcnt = MAX_HOPCNT;
+				(void)strcpy(to.tsp_name, hostname);
+				bytenetorder(&to);
+				if (sendto(sock, (char *)&to,
+					   sizeof(struct tsp), 0,
+					   (struct sockaddr*)&ntp->dest_addr,
+					   sizeof(ntp->dest_addr)) < 0) {
+				   trace_sendto_err(ntp->dest_addr.sin_addr);
+				}
+			}
+		}
+
+
+	} else {
+		switch (msg->tsp_type) {
+
+		case TSP_MASTERREQ:
+			break;
+
+		case TSP_SLAVEUP:
+			newslave(msg);
+			break;
+
+		case TSP_SETDATE:
+			/*
+			 * XXX check to see it is from ourself
+			 */
+#ifdef sgi
+			(void)cftime(newdate, "%D %T", &msg->tsp_time.tv_sec);
+#else
+			(void)strcpy(newdate, ctime(&msg->tsp_time.tv_sec));
+#endif /* sgi */
+			if (!good_host_name(msg->tsp_name)) {
+				syslog(LOG_NOTICE,
+				       "attempted date change by %s to %s",
+				       msg->tsp_name, newdate);
+				spreadtime();
+				break;
+			}
+
+			mchgdate(msg);
+			(void)gettimeofday(&ntime, 0);
+			pollingtime = ntime.tv_sec + SAMPLEINTVL;
+			break;
+
+		case TSP_SETDATEREQ:
+			if (!fromnet || fromnet->status != MASTER)
+				break;
+#ifdef sgi
+			(void)cftime(newdate, "%D %T", &msg->tsp_time.tv_sec);
+#else
+			(void)strcpy(newdate, ctime(&msg->tsp_time.tv_sec));
+#endif /* sgi */
+			htp = findhost(msg->tsp_name);
+			if (htp == 0) {
+				syslog(LOG_ERR,
+				       "attempted SET DATEREQ by uncontrolled %s to %s",
+				       msg->tsp_name, newdate);
+				break;
+			}
+			if (htp->seq == msg->tsp_seq)
+				break;
+			htp->seq = msg->tsp_seq;
+			if (!htp->good) {
+				syslog(LOG_NOTICE,
+				"attempted SET DATEREQ by untrusted %s to %s",
+				       msg->tsp_name, newdate);
+				spreadtime();
+				break;
+			}
+
+			mchgdate(msg);
+			(void)gettimeofday(&ntime, 0);
+			pollingtime = ntime.tv_sec + SAMPLEINTVL;
+			break;
+
+		case TSP_MSITE:
+			xmit(TSP_ACK, msg->tsp_seq, &from);
+			break;
+
+		case TSP_MSITEREQ:
+			break;
+
+		case TSP_TRACEON:
+			traceon();
+			break;
+
+		case TSP_TRACEOFF:
+			traceoff("Tracing ended at %s\n");
+			break;
+
+		case TSP_ELECTION:
+			if (!fromnet)
+				break;
+			if (fromnet->status == MASTER) {
+				pollingtime = 0;
+				(void)addmach(msg->tsp_name, &from,fromnet);
+			}
+			taddr = from;
+			(void)strcpy(tname, msg->tsp_name);
+			to.tsp_type = TSP_QUIT;
+			(void)strcpy(to.tsp_name, hostname);
+			answer = acksend(&to, &taddr, tname,
+					 TSP_ACK, 0, 1);
+			if (answer == NULL) {
+				syslog(LOG_ERR, "election error by %s",
+				       tname);
+			}
+			break;
+
+		case TSP_CONFLICT:
+			/*
+			 * After a network partition, there can be
+			 * more than one master: the first slave to
+			 * come up will notify here the situation.
+			 */
+			if (!fromnet || fromnet->status != MASTER)
+				break;
+			(void)strcpy(to.tsp_name, hostname);
+
+			/* The other master often gets into the same state,
+			 * with boring results if we stay at it forever.
+			 */
+			ntp = fromnet;	/* (acksend() can leave fromnet=0 */
+			for (i = 0; i < 3; i++) {
+				to.tsp_type = TSP_RESOLVE;
+				(void)strcpy(to.tsp_name, hostname);
+				answer = acksend(&to, &ntp->dest_addr,
+						 ANYADDR, TSP_MASTERACK,
+						 ntp, 0);
+				if (!answer)
+					break;
+				htp = addmach(answer->tsp_name,&from,ntp);
+				to.tsp_type = TSP_QUIT;
+				msg = acksend(&to, &htp->addr, htp->name,
+					      TSP_ACK, 0, htp->noanswer);
+				if (msg == NULL) {
+					syslog(LOG_ERR,
+				    "no response from %s to CONFLICT-QUIT",
+					       htp->name);
+				}
+			}
+			masterup(ntp);
+			pollingtime = 0;
+			break;
+
+		case TSP_RESOLVE:
+			if (!fromnet || fromnet->status != MASTER)
+				break;
+			/*
+			 * do not want to call synch() while waiting
+			 * to be killed!
+			 */
+			(void)gettimeofday(&ntime, (struct timezone *)0);
+			pollingtime = ntime.tv_sec + SAMPLEINTVL;
+			break;
+
+		case TSP_QUIT:
+			doquit(msg);		/* become a slave */
+			break;
+
+		case TSP_LOOP:
+			if (!fromnet || fromnet->status != MASTER
+			    || !strcmp(msg->tsp_name, hostname))
+				break;
+			/*
+			 * We should not have received this from a net
+			 * we are master on.  There must be two masters.
+			 */
+			htp = addmach(msg->tsp_name, &from,fromnet);
+			to.tsp_type = TSP_QUIT;
+			(void)strcpy(to.tsp_name, hostname);
+			answer = acksend(&to, &htp->addr, htp->name,
+					 TSP_ACK, 0, 1);
+			if (!answer) {
+				syslog(LOG_WARNING,
+				"loop breakage: no reply from %s=%s to QUIT",
+				    htp->name, inet_ntoa(htp->addr.sin_addr));
+				(void)remmach(htp);
+			}
+
+		case TSP_TEST:
+			if (trace) {
+				fprintf(fd,
+		"\tnets = %d, masters = %d, slaves = %d, ignored = %d\n",
+		nnets, nmasternets, nslavenets, nignorednets);
+				setstatus();
+			}
+			pollingtime = 0;
+			polls = POLLRATE-1;
+			break;
+
+		default:
+			if (trace) {
+				fprintf(fd, "garbage message: ");
+				print(msg, &from);
+			}
+			break;
+		}
+	}
+	goto loop;
+}
+
+
+/*
+ * change the system date on the master
+ */
+static void
+mchgdate(msg)
+	struct tsp *msg;
+{
+	char tname[MAXHOSTNAMELEN];
+	char olddate[32];
+	struct timeval otime, ntime;
+
+	(void)strcpy(tname, msg->tsp_name);
+
+	xmit(TSP_DATEACK, msg->tsp_seq, &from);
+
+	(void)strcpy(olddate, date());
+
+	/* adjust time for residence on the queue */
+	(void)gettimeofday(&otime, 0);
+	adj_msg_time(msg,&otime);
+
+	timevalsub(&ntime, &msg->tsp_time, &otime);
+	if (ntime.tv_sec < MAXADJ && ntime.tv_sec > -MAXADJ) {
+		/*
+		 * do not change the clock if we can adjust it
+		 */
+		dictate = 3;
+		synch(tvtomsround(ntime));
+	} else {
+#ifdef sgi
+		if (0 > settimeofday(&msg->tsp_time, 0)) {
+			syslog(LOG_ERR, "settimeofday(): %m");
+		}
+		logwtmp(&otime, &msg->tsp_time);
+#else
+		logwtmp("|", "date", "");
+		(void)settimeofday(&msg->tsp_time, 0);
+		logwtmp("}", "date", "");
+#endif /* sgi */
+		spreadtime();
+	}
+
+	syslog(LOG_NOTICE, "date changed by %s from %s",
+	       tname, olddate);
+}
+
+
+/*
+ * synchronize all of the slaves
+ */
+void
+synch(mydelta)
+	long mydelta;
+{
+	struct hosttbl *htp;
+	int measure_status;
+	struct timeval check, stop, wait;
+#ifdef sgi
+	int pri;
+#endif /* sgi */
+
+	if (slvcount > 0) {
+		if (trace)
+			fprintf(fd, "measurements starting at %s\n", date());
+		(void)gettimeofday(&check, 0);
+#ifdef sgi
+		/* run fast to get good time */
+		pri = schedctl(NDPRI,0,NDPHIMIN);
+		if (pri < 0)
+			syslog(LOG_ERR, "schedctl(): %m");
+#endif /* sgi */
+		for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {
+			if (htp->noanswer != 0) {
+				measure_status = measure(500, 100,
+							 htp->name,
+							 &htp->addr,0);
+			} else {
+				measure_status = measure(3000, 100,
+							 htp->name,
+							 &htp->addr,0);
+			}
+			if (measure_status != GOOD) {
+				/* The slave did not respond.  We have
+				 * just wasted lots of time on it.
+				 */
+				htp->delta = HOSTDOWN;
+				if (++htp->noanswer >= LOSTHOST) {
+					if (trace) {
+						fprintf(fd,
+					"purging %s for not answering ICMP\n",
+							htp->name);
+						(void)fflush(fd);
+					}
+					htp = remmach(htp);
+				}
+			} else {
+				htp->delta = measure_delta;
+			}
+			(void)gettimeofday(&stop, 0);
+			timevalsub(&stop, &stop, &check);
+			if (stop.tv_sec >= 1) {
+				if (trace)
+					(void)fflush(fd);
+				/*
+				 * ack messages periodically
+				 */
+				wait.tv_sec = 0;
+				wait.tv_usec = 0;
+				if (0 != readmsg(TSP_TRACEON,ANYADDR,
+						 &wait,0))
+					traceon();
+				(void)gettimeofday(&check, 0);
+			}
+		}
+#ifdef sgi
+		if (pri >= 0)
+			(void)schedctl(NDPRI,0,pri);
+#endif /* sgi */
+		if (trace)
+			fprintf(fd, "measurements finished at %s\n", date());
+	}
+	if (!(status & SLAVE)) {
+		if (!dictate) {
+			mydelta = networkdelta();
+		} else {
+			dictate--;
+		}
+	}
+	if (trace && (mydelta != 0 || (status & SLAVE)))
+		fprintf(fd,"local correction of %ld ms.\n", mydelta);
+	correct(mydelta);
+}
+
+/*
+ * sends the time to each slave after the master
+ * has received the command to set the network time
+ */
+void
+spreadtime()
+{
+	struct hosttbl *htp;
+	struct tsp to;
+	struct tsp *answer;
+
+/* Do not listen to the consensus after forcing the time.  This is because
+ *	the consensus takes a while to reach the time we are dictating.
+ */
+	dictate = 2;
+	for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {
+		to.tsp_type = TSP_SETTIME;
+		(void)strcpy(to.tsp_name, hostname);
+		(void)gettimeofday(&to.tsp_time, 0);
+		answer = acksend(&to, &htp->addr, htp->name,
+				 TSP_ACK, 0, htp->noanswer);
+		if (answer == 0) {
+			/* We client does not respond, then we have
+			 * just wasted lots of time on it.
+			 */
+			syslog(LOG_WARNING,
+			       "no reply to SETTIME from %s", htp->name);
+			if (++htp->noanswer >= LOSTHOST) {
+				if (trace) {
+					fprintf(fd,
+					     "purging %s for not answering",
+						htp->name);
+					(void)fflush(fd);
+				}
+				htp = remmach(htp);
+			}
+		}
+	}
+}
+
+void
+prthp(delta)
+	clock_t delta;
+{
+	static time_t next_time;
+	time_t this_time;
+	struct tms tm;
+	struct hosttbl *htp;
+	int length, l;
+	int i;
+
+	if (!fd)			/* quit if tracing already off */
+		return;
+
+	this_time = times(&tm);
+	if (this_time + delta < next_time)
+		return;
+	next_time = this_time + CLK_TCK;
+
+	fprintf(fd, "host table: %d entries at %s\n", slvcount, date());
+	htp = self.l_fwd;
+	length = 1;
+	for (i = 1; i <= slvcount; i++, htp = htp->l_fwd) {
+		l = strlen(htp->name) + 1;
+		if (length+l >= 80) {
+			fprintf(fd, "\n");
+			length = 0;
+		}
+		length += l;
+		fprintf(fd, " %s", htp->name);
+	}
+	fprintf(fd, "\n");
+}
+
+
+static struct hosttbl *newhost_hash;
+static struct hosttbl *lasthfree = &hosttbl[0];
+
+
+struct hosttbl *			/* answer or 0 */
+findhost(name)
+	char *name;
+{
+	int i, j;
+	struct hosttbl *htp;
+	char *p;
+
+	j= 0;
+	for (p = name, i = 0; i < 8 && *p != '\0'; i++, p++)
+		j = (j << 2) ^ *p;
+	newhost_hash = &hosttbl[j % NHOSTS];
+
+	htp = newhost_hash;
+	if (htp->name[0] == '\0')
+		return(0);
+	do {
+		if (!strcmp(name, htp->name))
+			return(htp);
+		htp = htp->h_fwd;
+	} while (htp != newhost_hash);
+	return(0);
+}
+
+/*
+ * add a host to the list of controlled machines if not already there
+ */
+struct hosttbl *
+addmach(name, addr, ntp)
+	char *name;
+	struct sockaddr_in *addr;
+	struct netinfo *ntp;
+{
+	struct hosttbl *ret, *p, *b, *f;
+
+	ret = findhost(name);
+	if (ret == 0) {
+		if (slvcount >= NHOSTS) {
+			if (trace) {
+				fprintf(fd, "no more slots in host table\n");
+				prthp(CLK_TCK);
+			}
+			syslog(LOG_ERR, "no more slots in host table");
+			Mflag = 0;
+			longjmp(jmpenv, 2); /* give up and be a slave */
+		}
+
+		/* if our home hash slot is occupied, find a free entry
+		 * in the hash table
+		 */
+		if (newhost_hash->name[0] != '\0') {
+			do {
+				ret = lasthfree;
+				if (++lasthfree > &hosttbl[NHOSTS])
+					lasthfree = &hosttbl[1];
+			} while (ret->name[0] != '\0');
+
+			if (!newhost_hash->head) {
+				/* Move an interloper using our home.  Use
+				 * scratch pointers in case the new head is
+				 * pointing to itself.
+				 */
+				f = newhost_hash->h_fwd;
+				b = newhost_hash->h_bak;
+				f->h_bak = ret;
+				b->h_fwd = ret;
+				f = newhost_hash->l_fwd;
+				b = newhost_hash->l_bak;
+				f->l_bak = ret;
+				b->l_fwd = ret;
+				bcopy(newhost_hash,ret,sizeof(*ret));
+				ret = newhost_hash;
+				ret->head = 1;
+				ret->h_fwd = ret;
+				ret->h_bak = ret;
+			} else {
+				/* link to an existing chain in our home
+				 */
+				ret->head = 0;
+				p = newhost_hash->h_bak;
+				ret->h_fwd = newhost_hash;
+				ret->h_bak = p;
+				p->h_fwd = ret;
+				newhost_hash->h_bak = ret;
+			}
+		} else {
+			ret = newhost_hash;
+			ret->head = 1;
+			ret->h_fwd = ret;
+			ret->h_bak = ret;
+		}
+		ret->addr = *addr;
+		ret->ntp = ntp;
+		(void)strncpy(ret->name, name, sizeof(ret->name));
+		ret->good = good_host_name(name);
+		ret->l_fwd = &self;
+		ret->l_bak = self.l_bak;
+		self.l_bak->l_fwd = ret;
+		self.l_bak = ret;
+		slvcount++;
+
+		ret->noanswer = 0;
+		ret->need_set = 1;
+
+	} else {
+		ret->noanswer = (ret->noanswer != 0);
+	}
+
+	/* need to clear sequence number anyhow */
+	ret->seq = 0;
+	return(ret);
+}
+
+/*
+ * remove the machine with the given index in the host table.
+ */
+struct hosttbl *
+remmach(htp)
+	struct hosttbl *htp;
+{
+	struct hosttbl *lprv, *hnxt, *f, *b;
+
+	if (trace)
+		fprintf(fd, "remove %s\n", htp->name);
+
+	/* get out of the lists */
+	htp->l_fwd->l_bak = lprv = htp->l_bak;
+	htp->l_bak->l_fwd = htp->l_fwd;
+	htp->h_fwd->h_bak = htp->h_bak;
+	htp->h_bak->h_fwd = hnxt = htp->h_fwd;
+
+	/* If we are in the home slot, pull up the chain */
+	if (htp->head && hnxt != htp) {
+		if (lprv == hnxt)
+			lprv = htp;
+
+		/* Use scratch pointers in case the new head is pointing to
+		 * itself.
+		 */
+		f = hnxt->h_fwd;
+		b = hnxt->h_bak;
+		f->h_bak = htp;
+		b->h_fwd = htp;
+		f = hnxt->l_fwd;
+		b = hnxt->l_bak;
+		f->l_bak = htp;
+		b->l_fwd = htp;
+		hnxt->head = 1;
+		bcopy(hnxt, htp, sizeof(*htp));
+		lasthfree = hnxt;
+	} else {
+		lasthfree = htp;
+	}
+
+	lasthfree->name[0] = '\0';
+	lasthfree->h_fwd = 0;
+	lasthfree->l_fwd = 0;
+	slvcount--;
+
+	return lprv;
+}
+
+
+/*
+ * Remove all the machines from the host table that exist on the given
+ * network.  This is called when a master transitions to a slave on a
+ * given network.
+ */
+void
+rmnetmachs(ntp)
+	struct netinfo *ntp;
+{
+	struct hosttbl *htp;
+
+	if (trace)
+		prthp(CLK_TCK);
+	for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {
+		if (ntp == htp->ntp)
+			htp = remmach(htp);
+	}
+	if (trace)
+		prthp(CLK_TCK);
+}
+
+void
+masterup(net)
+	struct netinfo *net;
+{
+	xmit(TSP_MASTERUP, 0, &net->dest_addr);
+
+	/*
+	 * Do not tell new slaves our time for a while.  This ensures
+	 * we do not tell them to start using our time, before we have
+	 * found a good master.
+	 */
+	(void)gettimeofday(&net->slvwait, 0);
+}
+
+void
+newslave(msg)
+	struct tsp *msg;
+{
+	struct hosttbl *htp;
+	struct tsp *answer, to;
+	struct timeval now;
+
+	if (!fromnet || fromnet->status != MASTER)
+		return;
+
+	htp = addmach(msg->tsp_name, &from,fromnet);
+	htp->seq = msg->tsp_seq;
+	if (trace)
+		prthp(0);
+
+	/*
+	 * If we are stable, send our time to the slave.
+	 * Do not go crazy if the date has been changed.
+	 */
+	(void)gettimeofday(&now, 0);
+	if (now.tv_sec >= fromnet->slvwait.tv_sec+3
+	    || now.tv_sec < fromnet->slvwait.tv_sec) {
+		to.tsp_type = TSP_SETTIME;
+		(void)strcpy(to.tsp_name, hostname);
+		(void)gettimeofday(&to.tsp_time, 0);
+		answer = acksend(&to, &htp->addr,
+				 htp->name, TSP_ACK,
+				 0, htp->noanswer);
+		if (answer) {
+			htp->need_set = 0;
+		} else {
+			syslog(LOG_WARNING,
+			       "no reply to initial SETTIME from %s",
+			       htp->name);
+			htp->noanswer = LOSTHOST;
+		}
+	}
+}
+
+
+/*
+ * react to a TSP_QUIT:
+ */
+void
+doquit(msg)
+	struct tsp *msg;
+{
+	if (fromnet->status == MASTER) {
+		if (!good_host_name(msg->tsp_name)) {
+			if (fromnet->quit_count <= 0) {
+				syslog(LOG_NOTICE,"untrusted %s told us QUIT",
+				       msg->tsp_name);
+				suppress(&from, msg->tsp_name, fromnet);
+				fromnet->quit_count = 1;
+				return;
+			}
+			syslog(LOG_NOTICE, "untrusted %s told us QUIT twice",
+			       msg->tsp_name);
+			fromnet->quit_count = 2;
+			fromnet->status = NOMASTER;
+		} else {
+			fromnet->status = SLAVE;
+		}
+		rmnetmachs(fromnet);
+		longjmp(jmpenv, 2);		/* give up and be a slave */
+
+	} else {
+		if (!good_host_name(msg->tsp_name)) {
+			syslog(LOG_NOTICE, "untrusted %s told us QUIT",
+			       msg->tsp_name);
+			fromnet->quit_count = 2;
+		}
+	}
+}
+
+void
+traceon()
+{
+	if (!fd) {
+		fd = fopen(_PATH_TIMEDLOG, "w");
+		if (!fd) {
+			trace = 0;
+			return;
+		}
+		fprintf(fd,"Tracing started at %s\n", date());
+	}
+	trace = 1;
+	get_goodgroup(1);
+	setstatus();
+	prthp(CLK_TCK);
+}
+
+
+void
+traceoff(msg)
+	char *msg;
+{
+	get_goodgroup(1);
+	setstatus();
+	prthp(CLK_TCK);
+	if (trace) {
+		fprintf(fd, msg, date());
+		(void)fclose(fd);
+		fd = 0;
+	}
+#ifdef GPROF
+	moncontrol(0);
+	_mcleanup();
+	moncontrol(1);
+#endif
+	trace = OFF;
+}
+
+
+#ifdef sgi
+void
+logwtmp(otime, ntime)
+	struct timeval *otime, *ntime;
+{
+	static struct utmp wtmp[2] = {
+		{"","",OTIME_MSG,0,OLD_TIME,0,0,0},
+		{"","",NTIME_MSG,0,NEW_TIME,0,0,0}
+	};
+	static char *wtmpfile = WTMP_FILE;
+	int f;
+
+	wtmp[0].ut_time = otime->tv_sec + (otime->tv_usec + 500000) / 1000000;
+	wtmp[1].ut_time = ntime->tv_sec + (ntime->tv_usec + 500000) / 1000000;
+	if (wtmp[0].ut_time == wtmp[1].ut_time)
+		return;
+
+	setutent();
+	(void)pututline(&wtmp[0]);
+	(void)pututline(&wtmp[1]);
+	endutent();
+	if ((f = open(wtmpfile, O_WRONLY|O_APPEND)) >= 0) {
+		(void) write(f, (char *)wtmp, sizeof(wtmp));
+		(void) close(f);
+	}
+}
+#endif /* sgi */
diff --git a/timed.tproj/timed.tproj/measure.c b/timed.tproj/timed.tproj/measure.c
new file mode 100644
index 0000000..6b809b2
--- /dev/null
+++ b/timed.tproj/timed.tproj/measure.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)measure.c	8.2 (Berkeley) 3/26/95";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "globals.h"
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+
+#define MSEC_DAY	(SECDAY*1000)
+
+#define PACKET_IN	1024
+
+#define MSGS		5		/* timestamps to average */
+#define TRIALS		10		/* max # of timestamps sent */
+
+extern int sock_raw;
+
+int measure_delta;
+
+static n_short seqno = 0;
+
+/*
+ * Measures the differences between machines' clocks using
+ * ICMP timestamp messages.
+ */
+int					/* status val defined in globals.h */
+measure(maxmsec, wmsec, hname, addr, print)
+	u_long maxmsec;			/* wait this many msec at most */
+	u_long wmsec;			/* msec to wait for an answer */
+	char *hname;
+	struct sockaddr_in *addr;
+	int print;			/* print complaints on stderr */
+{
+	int length;
+	int measure_status;
+	int rcvcount, trials;
+	int cc, count;
+	fd_set ready;
+	long sendtime, recvtime, histime1, histime2;
+	long idelta, odelta, total;
+	long min_idelta, min_odelta;
+	struct timeval tdone, tcur, ttrans, twait, tout;
+	u_char packet[PACKET_IN], opacket[64];
+	register struct icmp *icp = (struct icmp *) packet;
+	register struct icmp *oicp = (struct icmp *) opacket;
+	struct ip *ip = (struct ip *) packet;
+
+	min_idelta = min_odelta = 0x7fffffff;
+	measure_status = HOSTDOWN;
+	measure_delta = HOSTDOWN;
+	errno = 0;
+
+	/* open raw socket used to measure time differences */
+	if (sock_raw < 0) {
+		sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+		if (sock_raw < 0)  {
+			syslog(LOG_ERR, "opening raw socket: %m");
+			goto quit;
+		}
+	}
+	    
+
+	/*
+	 * empty the icmp input queue
+	 */
+	FD_ZERO(&ready);
+	for (;;) {
+		tout.tv_sec = tout.tv_usec = 0;
+		FD_SET(sock_raw, &ready);
+		if (select(sock_raw+1, &ready, 0,0, &tout)) {
+			length = sizeof(struct sockaddr_in);
+			cc = recvfrom(sock_raw, (char *)packet, PACKET_IN, 0,
+				      0,&length);
+			if (cc < 0)
+				goto quit;
+			continue;
+		}
+		break;
+	}
+
+	/*
+	 * Choose the smallest transmission time in each of the two
+	 * directions. Use these two latter quantities to compute the delta
+	 * between the two clocks.
+	 */
+
+	oicp->icmp_type = ICMP_TSTAMP;
+	oicp->icmp_code = 0;
+	oicp->icmp_id = getpid();
+	oicp->icmp_rtime = 0;
+	oicp->icmp_ttime = 0;
+	oicp->icmp_seq = seqno;
+
+	FD_ZERO(&ready);
+
+#ifdef sgi
+	sginap(1);			/* start at a clock tick */
+#endif /* sgi */
+
+	(void)gettimeofday(&tdone, 0);
+	mstotvround(&tout, maxmsec);
+	timevaladd(&tdone, &tout);		/* when we give up */
+
+	mstotvround(&twait, wmsec);
+
+	rcvcount = 0;
+	trials = 0;
+	while (rcvcount < MSGS) {
+		(void)gettimeofday(&tcur, 0);
+
+		/*
+		 * keep sending until we have sent the max
+		 */
+		if (trials < TRIALS) {
+			trials++;
+			oicp->icmp_otime = htonl((tcur.tv_sec % SECDAY) * 1000
+						 + tcur.tv_usec / 1000);
+			oicp->icmp_cksum = 0;
+			oicp->icmp_cksum = in_cksum((u_short*)oicp,
+						    sizeof(*oicp));
+
+			count = sendto(sock_raw, opacket, sizeof(*oicp), 0,
+				       (struct sockaddr*)addr,
+				       sizeof(struct sockaddr));
+			if (count < 0) {
+				if (measure_status == HOSTDOWN)
+					measure_status = UNREACHABLE;
+				goto quit;
+			}
+			++oicp->icmp_seq;
+
+			ttrans = tcur;
+			timevaladd(&ttrans, &twait);
+		} else {
+			ttrans = tdone;
+		}
+
+		while (rcvcount < trials) {
+			timevalsub(&tout, &ttrans, &tcur);
+			if (tout.tv_sec < 0)
+				tout.tv_sec = 0;
+
+			FD_SET(sock_raw, &ready);
+			count = select(sock_raw+1, &ready, (fd_set *)0,
+				       (fd_set *)0, &tout);
+			(void)gettimeofday(&tcur, (struct timezone *)0);
+			if (count <= 0)
+				break;
+
+			length = sizeof(struct sockaddr_in);
+			cc = recvfrom(sock_raw, (char *)packet, PACKET_IN, 0,
+				      0,&length);
+			if (cc < 0)
+				goto quit;
+
+			/* 
+			 * got something.  See if it is ours
+			 */
+			icp = (struct icmp *)(packet + (ip->ip_hl << 2));
+			if (cc < sizeof(*ip)
+			    || icp->icmp_type != ICMP_TSTAMPREPLY
+			    || icp->icmp_id != oicp->icmp_id
+			    || icp->icmp_seq < seqno
+			    || icp->icmp_seq >= oicp->icmp_seq)
+				continue;
+
+
+			sendtime = ntohl(icp->icmp_otime);
+			recvtime = ((tcur.tv_sec % SECDAY) * 1000 +
+				    tcur.tv_usec / 1000);
+
+			total = recvtime-sendtime;
+			if (total < 0)	/* do not hassle midnight */
+				continue;
+
+			rcvcount++;
+			histime1 = ntohl(icp->icmp_rtime);
+			histime2 = ntohl(icp->icmp_ttime);
+			/*
+			 * a host using a time format different from
+			 * msec. since midnight UT (as per RFC792) should
+			 * set the high order bit of the 32-bit time
+			 * value it transmits.
+			 */
+			if ((histime1 & 0x80000000) != 0) {
+				measure_status = NONSTDTIME;
+				goto quit;
+			}
+			measure_status = GOOD;
+
+			idelta = recvtime-histime2;
+			odelta = histime1-sendtime;
+
+			/* do not be confused by midnight */
+			if (idelta < -MSEC_DAY/2) idelta += MSEC_DAY;
+			else if (idelta > MSEC_DAY/2) idelta -= MSEC_DAY;
+
+			if (odelta < -MSEC_DAY/2) odelta += MSEC_DAY;
+			else if (odelta > MSEC_DAY/2) odelta -= MSEC_DAY;
+
+			/* save the quantization error so that we can get a
+			 * measurement finer than our system clock.
+			 */
+			if (total < MIN_ROUND) {
+				measure_delta = (odelta - idelta)/2;
+				goto quit;
+			}
+
+			if (idelta < min_idelta)
+				min_idelta = idelta;
+			if (odelta < min_odelta)
+				min_odelta = odelta;
+
+			measure_delta = (min_odelta - min_idelta)/2;
+		}
+
+		if (tcur.tv_sec > tdone.tv_sec
+		    || (tcur.tv_sec == tdone.tv_sec
+			&& tcur.tv_usec >= tdone.tv_usec))
+			break;
+	}
+
+quit:
+	seqno += TRIALS;		/* allocate our sequence numbers */
+
+	/*
+	 * If no answer is received for TRIALS consecutive times,
+	 * the machine is assumed to be down
+	 */
+	if (measure_status == GOOD) {
+		if (trace) {
+			fprintf(fd,
+				"measured delta %4d, %d trials to %-15s %s\n",
+			   	measure_delta, trials,
+				inet_ntoa(addr->sin_addr), hname);
+		}
+	} else if (print) {
+		if (errno != 0)
+			fprintf(stderr, "measure %s: %s\n", hname,
+				strerror(errno));
+	} else {
+		if (errno != 0) {
+			syslog(LOG_ERR, "measure %s: %m", hname);
+		} else {
+			syslog(LOG_ERR, "measure: %s did not respond", hname);
+		}
+		if (trace) {
+			fprintf(fd,
+				"measure: %s failed after %d trials\n",
+				hname, trials);
+			(void)fflush(fd);
+		}
+	}
+
+	return(measure_status);
+}
+
+
+
+
+
+/*
+ * round a number of milliseconds into a struct timeval
+ */
+void
+mstotvround(res, x)
+	struct timeval *res;
+	long x;
+{
+#ifndef sgi
+	if (x < 0)
+		x = -((-x + 3)/5);
+	else
+		x = (x+3)/5;
+	x *= 5;
+#endif /* sgi */
+	res->tv_sec = x/1000;
+	res->tv_usec = (x-res->tv_sec*1000)*1000;
+	if (res->tv_usec < 0) {
+		res->tv_usec += 1000000;
+		res->tv_sec--;
+	}
+}
+
+void
+timevaladd(tv1, tv2)
+	struct timeval *tv1, *tv2;
+{
+	tv1->tv_sec += tv2->tv_sec;
+	tv1->tv_usec += tv2->tv_usec;
+	if (tv1->tv_usec >= 1000000) {
+		tv1->tv_sec++;
+		tv1->tv_usec -= 1000000;
+	}
+	if (tv1->tv_usec < 0) {
+		tv1->tv_sec--;
+		tv1->tv_usec += 1000000;
+	}
+}
+
+void
+timevalsub(res, tv1, tv2)
+	struct timeval *res, *tv1, *tv2;
+{
+	res->tv_sec = tv1->tv_sec - tv2->tv_sec;
+	res->tv_usec = tv1->tv_usec - tv2->tv_usec;
+	if (res->tv_usec >= 1000000) {
+		res->tv_sec++;
+		res->tv_usec -= 1000000;
+	}
+	if (res->tv_usec < 0) {
+		res->tv_sec--;
+		res->tv_usec += 1000000;
+	}
+}
diff --git a/timed.tproj/timed.tproj/networkdelta.c b/timed.tproj/timed.tproj/networkdelta.c
new file mode 100644
index 0000000..51576f6
--- /dev/null
+++ b/timed.tproj/timed.tproj/networkdelta.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)networkdelta.c	8.3 (Berkeley) 4/27/95";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "globals.h"
+
+static long median __P((double, float *, long *, long *, unsigned int));
+
+/*
+ * Compute a corrected date.
+ *	Compute the median of the reasonable differences.  First compute
+ *	the median of all authorized differences, and then compute the
+ *	median of all differences that are reasonably close to the first
+ *	median.
+ *
+ * This differs from the original BSD implementation, which looked for
+ *	the largest group of machines with essentially the same date.
+ *	That assumed that machines with bad clocks would be uniformly
+ *	distributed.  Unfortunately, in real life networks, the distribution
+ *	of machines is not uniform among models of machines, and the
+ *	distribution of errors in clocks tends to be quite consistent
+ *	for a given model.  In other words, all model VI Supre Servres
+ *	from GoFast Inc. tend to have about the same error.
+ *	The original BSD implementation would chose the clock of the
+ *	most common model, and discard all others.
+ *
+ *	Therefore, get best we can do is to try to average over all
+ *	of the machines in the network, while discarding "obviously"
+ *	bad values.
+ */
+long
+networkdelta()
+{
+	struct hosttbl *htp;
+	long med;
+	long lodelta, hidelta;
+	long logood, higood;
+	long x[NHOSTS];
+	long *xp;
+	int numdelta;
+	float eps;
+
+	/*
+	 * compute the median of the good values
+	 */
+	med = 0;
+	numdelta = 1;
+	xp = &x[0];
+	*xp = 0;			/* account for ourself */
+	for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {
+		if (htp->good
+		    && htp->noanswer == 0
+		    && htp->delta != HOSTDOWN) {
+			med += htp->delta;
+			numdelta++;
+			*++xp = htp->delta;
+		}
+	}
+
+	/*
+	 * If we are the only trusted time keeper, then do not change our
+	 * clock.  There may be another time keeping service active.
+	 */
+	if (numdelta == 1)
+		return 0;
+
+	/* get average of trusted values */
+	med /= numdelta;
+
+	if (trace)
+		fprintf(fd, "median of %d values starting at %ld is about ",
+			numdelta, med);
+	/* get median of all trusted values, using average as initial guess */
+	eps = med - x[0];
+	med = median(med, &eps, &x[0], xp+1, VALID_RANGE);
+
+	/* Compute the median of all good values.
+	 * Good values are those of all clocks, including untrusted clocks,
+	 * that are
+	 *	- trusted and somewhat close to the median of the
+	 *		trusted clocks
+	 *	- trusted or untrusted and very close to the median of the
+	 *		trusted clocks
+	 */
+	hidelta = med + GOOD_RANGE;
+	lodelta = med - GOOD_RANGE;
+	higood = med + VGOOD_RANGE;
+	logood = med - VGOOD_RANGE;
+	xp = &x[0];
+	htp = &self;
+	do {
+		if (htp->noanswer == 0
+		    && htp->delta >= lodelta
+		    && htp->delta <= hidelta
+		    && (htp->good
+			|| (htp->delta >= logood
+			    && htp->delta <= higood))) {
+			*xp++ = htp->delta;
+		}
+	} while (&self != (htp = htp->l_fwd));
+
+	if (xp == &x[0]) {
+		if (trace)
+			fprintf(fd, "nothing close to median %ld\n", med);
+		return med;
+	}
+
+	if (xp == &x[1]) {
+		if (trace)
+			fprintf(fd, "only value near median is %ld\n", x[0]);
+		return x[0];
+	}
+
+	if (trace)
+		fprintf(fd, "median of %d values starting at %ld is ",
+		        xp-&x[0], med);
+	return median(med, &eps, &x[0], xp, 1);
+}
+
+
+/*
+ * compute the median of an array of signed integers, using the idea
+ *	in <<Numerical Recipes>>.
+ */
+static long
+median(a0, eps_ptr, x, xlim, gnuf)
+	double a0;			/* initial guess for the median */
+	float *eps_ptr;			/* spacing near the median */
+	long *x, *xlim;			/* the data */
+	unsigned int gnuf;		/* good enough estimate */
+{
+	long *xptr;
+	float a = a0;
+	float ap = LONG_MAX;		/* bounds on the median */
+	float am = -LONG_MAX;
+	float aa;
+	int npts;			/* # of points above & below guess */
+	float xp;			/* closet point above the guess */
+	float xm;			/* closet point below the guess */
+	float eps;
+	float dum, sum, sumx;
+	int pass;
+#define AMP	1.5			/* smoothing constants */
+#define AFAC	1.5
+
+	eps = *eps_ptr;
+	if (eps < 1.0) {
+		eps = -eps;
+		if (eps < 1.0)
+			eps = 1.0;
+	}
+
+	for (pass = 1; ; pass++) {	/* loop over the data */
+		sum = 0.0;
+		sumx = 0.0;
+		npts = 0;
+		xp = LONG_MAX;
+		xm = -LONG_MAX;
+
+		for (xptr = x; xptr != xlim; xptr++) {
+			float xx = *xptr;
+
+			dum = xx - a;
+			if (dum != 0.0) {   /* avoid dividing by 0 */
+				if (dum > 0.0) {
+					npts++;
+					if (xx < xp)
+						xp = xx;
+				} else {
+					npts--;
+					if (xx > xm)
+						xm = xx;
+					dum = -dum;
+				}
+				dum = 1.0/(eps + dum);
+				sum += dum;
+				sumx += xx * dum;
+			}
+		}
+
+		if (ap-am < gnuf || sum == 0) {
+			if (trace)
+				fprintf(fd,
+					"%ld in %d passes;"
+					" early out balance=%d\n",
+				        (long)a, pass, npts);
+			return a;	/* guess was good enough */
+		}
+
+		aa = (sumx/sum-a)*AMP;
+		if (npts >= 2) {	/* guess was too low */
+			am = a;
+			aa = xp + max(0.0, aa);
+			if (aa >= ap)
+				aa = (a + ap)/2;
+
+		} else if (npts <= -2) {    /* guess was two high */
+			ap = a;
+			aa = xm + min(0.0, aa);
+			if (aa <= am)
+				aa = (a + am)/2;
+
+		} else {
+			break;		/* got it */
+		}
+
+		if (a == aa) {
+			if (trace)
+				fprintf(fd, "%ld in %d passes;"
+					" force out balance=%d\n",
+				        (long)a, pass, npts);
+			return a;
+		}
+		eps = AFAC*abs(aa - a);
+		*eps_ptr = eps;
+		a = aa;
+	}
+
+	if (((x - xlim) % 2) != 0) {    /* even number of points? */
+		if (npts == 0)		/* yes, return an average */
+			a = (xp+xm)/2;
+		else if (npts > 0)
+			a =  (a+xp)/2;
+		else
+			a = (xm+a)/2;
+
+	} else if (npts != 0) {		/* odd number of points */
+		if (npts > 0)
+			a = xp;
+		else
+			a = xm;
+	}
+
+	if (trace)
+		fprintf(fd, "%ld in %d passes\n", (long)a, pass);
+	return a;
+}
diff --git a/timed.tproj/timed.tproj/pathnames.h b/timed.tproj/timed.tproj/pathnames.h
new file mode 100644
index 0000000..1a3faf3
--- /dev/null
+++ b/timed.tproj/timed.tproj/pathnames.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/6/93
+ */
+
+#include <paths.h>
+
+#ifdef sgi
+#define	_PATH_MASTERLOG	"/usr/adm/timed.masterlog"
+#define	_PATH_TIMEDLOG	"/usr/adm/timed.log"
+#else
+#define	_PATH_MASTERLOG	"/var/log/timed.masterlog"
+#define	_PATH_TIMEDLOG	"/var/log/timed.log"
+#endif
diff --git a/timed.tproj/timed.tproj/readmsg.c b/timed.tproj/timed.tproj/readmsg.c
new file mode 100644
index 0000000..fab1e77
--- /dev/null
+++ b/timed.tproj/timed.tproj/readmsg.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)readmsg.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "globals.h"
+
+extern char *tsptype[];
+
+/*
+ * LOOKAT checks if the message is of the requested type and comes from
+ * the right machine, returning 1 in case of affirmative answer
+ */
+#define LOOKAT(msg, mtype, mfrom, netp, froms) \
+	(((mtype) == TSP_ANY || (mtype) == (msg).tsp_type) &&		\
+	 ((mfrom) == 0 || !strcmp((mfrom), (msg).tsp_name)) &&		\
+	 ((netp) == 0 || 						\
+	  ((netp)->mask & (froms).sin_addr.s_addr) == (netp)->net.s_addr))
+
+struct timeval rtime, rwait, rtout;
+struct tsp msgin;
+static struct tsplist {
+	struct tsp info;
+	struct timeval when;
+	struct sockaddr_in addr;
+	struct tsplist *p;
+} msgslist;
+struct sockaddr_in from;
+struct netinfo *fromnet;
+struct timeval from_when;
+
+/*
+ * `readmsg' returns message `type' sent by `machfrom' if it finds it
+ * either in the receive queue, or in a linked list of previously received
+ * messages that it maintains.
+ * Otherwise it waits to see if the appropriate message arrives within
+ * `intvl' seconds. If not, it returns NULL.
+ */
+
+struct tsp *
+readmsg(type, machfrom, intvl, netfrom)
+	int type;
+	char *machfrom;
+	struct timeval *intvl;
+	struct netinfo *netfrom;
+{
+	int length;
+	fd_set ready;
+	static struct tsplist *head = &msgslist;
+	static struct tsplist *tail = &msgslist;
+	static int msgcnt = 0;
+	struct tsplist *prev;
+	register struct netinfo *ntp;
+	register struct tsplist *ptr;
+
+	if (trace) {
+		fprintf(fd, "readmsg: looking for %s from %s, %s\n",
+			tsptype[type], machfrom == NULL ? "ANY" : machfrom,
+			netfrom == NULL ? "ANYNET" : inet_ntoa(netfrom->net));
+		if (head->p != 0) {
+			length = 1;
+			for (ptr = head->p; ptr != 0; ptr = ptr->p) {
+				/* do not repeat the hundreds of messages */
+				if (++length > 3) {
+					if (ptr == tail) {
+						fprintf(fd,"\t ...%d skipped\n",
+							length);
+					} else {
+						continue;
+					}
+				}
+				fprintf(fd, length > 1 ? "\t" : "queue:\t");
+				print(&ptr->info, &ptr->addr);
+			}
+		}
+	}
+
+	ptr = head->p;
+	prev = head;
+
+	/*
+	 * Look for the requested message scanning through the
+	 * linked list. If found, return it and free the space
+	 */
+
+	while (ptr != NULL) {
+		if (LOOKAT(ptr->info, type, machfrom, netfrom, ptr->addr)) {
+again:
+			msgin = ptr->info;
+			from = ptr->addr;
+			from_when = ptr->when;
+			prev->p = ptr->p;
+			if (ptr == tail)
+				tail = prev;
+			free((char *)ptr);
+			fromnet = NULL;
+			if (netfrom == NULL)
+			    for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+				    if ((ntp->mask & from.sin_addr.s_addr) ==
+					ntp->net.s_addr) {
+					    fromnet = ntp;
+					    break;
+				    }
+			    }
+			else
+			    fromnet = netfrom;
+			if (trace) {
+				fprintf(fd, "readmsg: found ");
+				print(&msgin, &from);
+			}
+
+/* The protocol can get far behind.  When it does, it gets
+ *	hopelessly confused.  So delete duplicate messages.
+ */
+			for (ptr = prev; (ptr = ptr->p) != NULL; prev = ptr) {
+				if (ptr->addr.sin_addr.s_addr
+					== from.sin_addr.s_addr
+				    && ptr->info.tsp_type == msgin.tsp_type) {
+					if (trace)
+						fprintf(fd, "\tdup ");
+					goto again;
+				}
+			}
+			msgcnt--;
+			return(&msgin);
+		} else {
+			prev = ptr;
+			ptr = ptr->p;
+		}
+	}
+
+	/*
+	 * If the message was not in the linked list, it may still be
+	 * coming from the network. Set the timer and wait
+	 * on a select to read the next incoming message: if it is the
+	 * right one, return it, otherwise insert it in the linked list.
+	 */
+
+	(void)gettimeofday(&rtout, 0);
+	timevaladd(&rtout, intvl);
+	FD_ZERO(&ready);
+	for (;;) {
+		(void)gettimeofday(&rtime, 0);
+		timevalsub(&rwait, &rtout, &rtime);
+		if (rwait.tv_sec < 0)
+			rwait.tv_sec = rwait.tv_usec = 0;
+		else if (rwait.tv_sec == 0
+			 && rwait.tv_usec < 1000000/CLK_TCK)
+			rwait.tv_usec = 1000000/CLK_TCK;
+
+		if (trace) {
+			fprintf(fd, "readmsg: wait %ld.%6ld at %s\n",
+				rwait.tv_sec, rwait.tv_usec, date());
+			/* Notice a full disk, as we flush trace info.
+			 * It is better to flush periodically than at
+			 * every line because the tracing consists of bursts
+			 * of many lines.  Without care, tracing slows
+			 * down the code enough to break the protocol.
+			 */
+			if (rwait.tv_sec != 0
+			    && EOF == fflush(fd))
+				traceoff("Tracing ended for cause at %s\n");
+		}
+
+		FD_SET(sock, &ready);
+		if (!select(sock+1, &ready, (fd_set *)0, (fd_set *)0,
+			   &rwait)) {
+			if (rwait.tv_sec == 0 && rwait.tv_usec == 0)
+				return(0);
+			continue;
+		}
+		length = sizeof(from);
+		if (recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 0,
+			     (struct sockaddr*)&from, &length) < 0) {
+			syslog(LOG_ERR, "recvfrom: %m");
+			exit(1);
+		}
+		(void)gettimeofday(&from_when, (struct timezone *)0);
+		bytehostorder(&msgin);
+
+		if (msgin.tsp_vers > TSPVERSION) {
+			if (trace) {
+			    fprintf(fd,"readmsg: version mismatch\n");
+			    /* should do a dump of the packet */
+			}
+			continue;
+		}
+
+		fromnet = NULL;
+		for (ntp = nettab; ntp != NULL; ntp = ntp->next)
+			if ((ntp->mask & from.sin_addr.s_addr) ==
+			    ntp->net.s_addr) {
+				fromnet = ntp;
+				break;
+			}
+
+		/*
+		 * drop packets from nets we are ignoring permanently
+		 */
+		if (fromnet == NULL) {
+			/*
+			 * The following messages may originate on
+			 * this host with an ignored network address
+			 */
+			if (msgin.tsp_type != TSP_TRACEON &&
+			    msgin.tsp_type != TSP_SETDATE &&
+			    msgin.tsp_type != TSP_MSITE &&
+			    msgin.tsp_type != TSP_TEST &&
+			    msgin.tsp_type != TSP_TRACEOFF) {
+				if (trace) {
+				    fprintf(fd,"readmsg: discard null net ");
+				    print(&msgin, &from);
+				}
+				continue;
+			}
+		}
+
+		/*
+		 * Throw away messages coming from this machine,
+		 * unless they are of some particular type.
+		 * This gets rid of broadcast messages and reduces
+		 * master processing time.
+		 */
+		if (!strcmp(msgin.tsp_name, hostname)
+		    && msgin.tsp_type != TSP_SETDATE
+		    && msgin.tsp_type != TSP_TEST
+		    && msgin.tsp_type != TSP_MSITE
+		    && msgin.tsp_type != TSP_TRACEON
+		    && msgin.tsp_type != TSP_TRACEOFF
+		    && msgin.tsp_type != TSP_LOOP) {
+			if (trace) {
+				fprintf(fd, "readmsg: discard own ");
+				print(&msgin, &from);
+			}
+			continue;
+		}
+
+		/*
+		 * Send acknowledgements here; this is faster and
+		 * avoids deadlocks that would occur if acks were
+		 * sent from a higher level routine.  Different
+		 * acknowledgements are necessary, depending on
+		 * status.
+		 */
+		if (fromnet == NULL)	/* do not de-reference 0 */
+			ignoreack();
+		else if (fromnet->status == MASTER)
+			masterack();
+		else if (fromnet->status == SLAVE)
+			slaveack();
+		else
+			ignoreack();
+
+		if (LOOKAT(msgin, type, machfrom, netfrom, from)) {
+			if (trace) {
+				fprintf(fd, "readmsg: ");
+				print(&msgin, &from);
+			}
+			return(&msgin);
+		} else if (++msgcnt > NHOSTS*3) {
+
+/* The protocol gets hopelessly confused if it gets too far
+*	behind.  However, it seems able to recover from all cases of lost
+*	packets.  Therefore, if we are swamped, throw everything away.
+*/
+			if (trace)
+				fprintf(fd,
+					"readmsg: discarding %d msgs\n",
+					msgcnt);
+			msgcnt = 0;
+			while ((ptr=head->p) != NULL) {
+				head->p = ptr->p;
+				free((char *)ptr);
+			}
+			tail = head;
+		} else {
+			tail->p = (struct tsplist *)
+				    malloc(sizeof(struct tsplist));
+			tail = tail->p;
+			tail->p = NULL;
+			tail->info = msgin;
+			tail->addr = from;
+			/* timestamp msgs so SETTIMEs are correct */
+			tail->when = from_when;
+		}
+	}
+}
+
+/*
+ * Send the necessary acknowledgements:
+ * only the type ACK is to be sent by a slave
+ */
+void
+slaveack()
+{
+	switch(msgin.tsp_type) {
+
+	case TSP_ADJTIME:
+	case TSP_SETTIME:
+	case TSP_ACCEPT:
+	case TSP_REFUSE:
+	case TSP_TRACEON:
+	case TSP_TRACEOFF:
+	case TSP_QUIT:
+		if (trace) {
+			fprintf(fd, "Slaveack: ");
+			print(&msgin, &from);
+		}
+		xmit(TSP_ACK,msgin.tsp_seq, &from);
+		break;
+
+	default:
+		if (trace) {
+			fprintf(fd, "Slaveack: no ack: ");
+			print(&msgin, &from);
+		}
+		break;
+	}
+}
+
+/*
+ * Certain packets may arrive from this machine on ignored networks.
+ * These packets should be acknowledged.
+ */
+void
+ignoreack()
+{
+	switch(msgin.tsp_type) {
+
+	case TSP_TRACEON:
+	case TSP_TRACEOFF:
+	case TSP_QUIT:
+		if (trace) {
+			fprintf(fd, "Ignoreack: ");
+			print(&msgin, &from);
+		}
+		xmit(TSP_ACK,msgin.tsp_seq, &from);
+		break;
+
+	default:
+		if (trace) {
+			fprintf(fd, "Ignoreack: no ack: ");
+			print(&msgin, &from);
+		}
+		break;
+	}
+}
+
+/*
+ * `masterack' sends the necessary acknowledgments
+ * to the messages received by a master
+ */
+void
+masterack()
+{
+	struct tsp resp;
+
+	resp = msgin;
+	resp.tsp_vers = TSPVERSION;
+	(void)strcpy(resp.tsp_name, hostname);
+
+	switch(msgin.tsp_type) {
+
+	case TSP_QUIT:
+	case TSP_TRACEON:
+	case TSP_TRACEOFF:
+	case TSP_MSITEREQ:
+		if (trace) {
+			fprintf(fd, "Masterack: ");
+			print(&msgin, &from);
+		}
+		xmit(TSP_ACK,msgin.tsp_seq, &from);
+		break;
+
+	case TSP_RESOLVE:
+	case TSP_MASTERREQ:
+		if (trace) {
+			fprintf(fd, "Masterack: ");
+			print(&msgin, &from);
+		}
+		xmit(TSP_MASTERACK,msgin.tsp_seq, &from);
+		break;
+
+	default:
+		if (trace) {
+			fprintf(fd,"Masterack: no ack: ");
+			print(&msgin, &from);
+		}
+		break;
+	}
+}
+
+/*
+ * Print a TSP message
+ */
+void
+print(msg, addr)
+	struct tsp *msg;
+	struct sockaddr_in *addr;
+{
+	char tm[26];
+	switch (msg->tsp_type) {
+
+	case TSP_LOOP:
+		fprintf(fd, "%s %d %-6u #%d %-15s %s\n",
+			tsptype[msg->tsp_type],
+			msg->tsp_vers,
+			msg->tsp_seq,
+			msg->tsp_hopcnt,
+			inet_ntoa(addr->sin_addr),
+			msg->tsp_name);
+		break;
+
+	case TSP_SETTIME:
+	case TSP_SETDATE:
+	case TSP_SETDATEREQ:
+#ifdef sgi
+		(void)cftime(tm, "%D %T", &msg->tsp_time.tv_sec);
+#else
+		strncpy(tm, ctime(&msg->tsp_time.tv_sec)+3+1, sizeof(tm));
+		tm[15] = '\0';		/* ugh */
+#endif /* sgi */
+		fprintf(fd, "%s %d %-6u %s %-15s %s\n",
+			tsptype[msg->tsp_type],
+			msg->tsp_vers,
+			msg->tsp_seq,
+			tm,
+			inet_ntoa(addr->sin_addr),
+			msg->tsp_name);
+		break;
+
+	case TSP_ADJTIME:
+		fprintf(fd, "%s %d %-6u (%ld,%ld) %-15s %s\n",
+			tsptype[msg->tsp_type],
+			msg->tsp_vers,
+			msg->tsp_seq,
+			msg->tsp_time.tv_sec,
+			msg->tsp_time.tv_usec,
+			inet_ntoa(addr->sin_addr),
+			msg->tsp_name);
+		break;
+
+	default:
+		fprintf(fd, "%s %d %-6u %-15s %s\n",
+			tsptype[msg->tsp_type],
+			msg->tsp_vers,
+			msg->tsp_seq,
+			inet_ntoa(addr->sin_addr),
+			msg->tsp_name);
+		break;
+	}
+}
diff --git a/timed.tproj/timed.tproj/slave.c b/timed.tproj/timed.tproj/slave.c
new file mode 100644
index 0000000..0b72058
--- /dev/null
+++ b/timed.tproj/timed.tproj/slave.c
@@ -0,0 +1,738 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)slave.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "globals.h"
+#include <setjmp.h>
+#include "pathnames.h"
+
+extern jmp_buf jmpenv;
+extern int Mflag;
+extern int justquit;
+
+extern u_short sequence;
+
+static char master_name[MAXHOSTNAMELEN+1];
+static struct netinfo *old_slavenet;
+static int old_status;
+
+static void schgdate __P((struct tsp *, char *));
+static void setmaster __P((struct tsp *));
+static void answerdelay __P((void));
+
+#ifdef sgi
+extern void logwtmp __P((struct timeval *, struct timeval *));
+#else
+extern void logwtmp __P((char *, char *, char *));
+#endif /* sgi */
+
+int
+slave()
+{
+	int tries;
+	long electiontime, refusetime, looktime, looptime, adjtime;
+	u_short seq;
+	long fastelection;
+#define FASTTOUT 3
+	struct in_addr cadr;
+	struct timeval otime;
+	struct sockaddr_in taddr;
+	char tname[MAXHOSTNAMELEN];
+	struct tsp *msg, to;
+	struct timeval ntime, wait;
+	struct tsp *answer;
+	int timeout();
+	char olddate[32];
+	char newdate[32];
+	struct netinfo *ntp;
+	struct hosttbl *htp;
+
+
+	old_slavenet = 0;
+	seq = 0;
+	refusetime = 0;
+	adjtime = 0;
+
+	(void)gettimeofday(&ntime, 0);
+	electiontime = ntime.tv_sec + delay2;
+	fastelection = ntime.tv_sec + FASTTOUT;
+	if (justquit)
+		looktime = electiontime;
+	else
+		looktime = fastelection;
+	looptime = fastelection;
+
+	if (slavenet)
+		xmit(TSP_SLAVEUP, 0, &slavenet->dest_addr);
+	if (status & MASTER) {
+		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+			if (ntp->status == MASTER)
+				masterup(ntp);
+		}
+	}
+
+loop:
+	get_goodgroup(0);
+	(void)gettimeofday(&ntime, (struct timezone *)0);
+	if (ntime.tv_sec > electiontime) {
+		if (trace)
+			fprintf(fd, "election timer expired\n");
+		longjmp(jmpenv, 1);
+	}
+
+	if (ntime.tv_sec >= looktime) {
+		if (trace)
+			fprintf(fd, "Looking for nets to master\n");
+
+		if (Mflag && nignorednets > 0) {
+			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+				if (ntp->status == IGNORE
+				    || ntp->status == NOMASTER) {
+					lookformaster(ntp);
+					if (ntp->status == MASTER) {
+						masterup(ntp);
+					} else if (ntp->status == MASTER) {
+						ntp->status = NOMASTER;
+					}
+				}
+				if (ntp->status == MASTER
+				    && --ntp->quit_count < 0)
+					ntp->quit_count = 0;
+			}
+			makeslave(slavenet);	/* prune extras */
+			setstatus();
+		}
+		(void)gettimeofday(&ntime, 0);
+		looktime = ntime.tv_sec + delay2;
+	}
+	if (ntime.tv_sec >= looptime) {
+		if (trace)
+			fprintf(fd, "Looking for loops\n");
+		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+		    if (ntp->status == MASTER) {
+			to.tsp_type = TSP_LOOP;
+			to.tsp_vers = TSPVERSION;
+			to.tsp_seq = sequence++;
+			to.tsp_hopcnt = MAX_HOPCNT;
+			(void)strcpy(to.tsp_name, hostname);
+			bytenetorder(&to);
+			if (sendto(sock, (char *)&to, sizeof(struct tsp), 0,
+				   (struct sockaddr*)&ntp->dest_addr,
+				   sizeof(ntp->dest_addr)) < 0) {
+				trace_sendto_err(ntp->dest_addr.sin_addr);
+			}
+		    }
+		}
+		(void)gettimeofday(&ntime, 0);
+		looptime = ntime.tv_sec + delay2;
+	}
+
+	wait.tv_sec = min(electiontime,min(looktime,looptime)) - ntime.tv_sec;
+	if (wait.tv_sec < 0)
+		wait.tv_sec = 0;
+	wait.tv_sec += FASTTOUT;
+	wait.tv_usec = 0;
+	msg = readmsg(TSP_ANY, ANYADDR, &wait, 0);
+
+	if (msg != NULL) {
+		/*
+		 * filter stuff not for us
+		 */
+		switch (msg->tsp_type) {
+		case TSP_SETDATE:
+		case TSP_TRACEOFF:
+		case TSP_TRACEON:
+			/*
+			 * XXX check to see they are from ourself
+			 */
+			break;
+
+		case TSP_TEST:
+		case TSP_MSITE:
+			break;
+
+		case TSP_MASTERUP:
+			if (!fromnet) {
+				if (trace) {
+					fprintf(fd, "slave ignored: ");
+					print(msg, &from);
+				}
+				goto loop;
+			}
+			break;
+
+		default:
+			if (!fromnet
+			    || fromnet->status == IGNORE
+			    || fromnet->status == NOMASTER) {
+				if (trace) {
+					fprintf(fd, "slave ignored: ");
+					print(msg, &from);
+				}
+				goto loop;
+			}
+			break;
+		}
+
+
+		/*
+		 * now process the message
+		 */
+		switch (msg->tsp_type) {
+
+		case TSP_ADJTIME:
+			if (fromnet != slavenet)
+				break;
+			if (!good_host_name(msg->tsp_name)) {
+				syslog(LOG_NOTICE,
+				   "attempted time adjustment by %s",
+				       msg->tsp_name);
+				suppress(&from, msg->tsp_name, fromnet);
+				break;
+			}
+			/*
+			 * Speed up loop detection in case we have a loop.
+			 * Otherwise the clocks can race until the loop
+			 * is found.
+			 */
+			(void)gettimeofday(&otime, 0);
+			if (adjtime < otime.tv_sec)
+				looptime -= (looptime-otime.tv_sec)/2 + 1;
+
+			setmaster(msg);
+			if (seq != msg->tsp_seq) {
+				seq = msg->tsp_seq;
+				synch(tvtomsround(msg->tsp_time));
+			}
+			(void)gettimeofday(&ntime, 0);
+			electiontime = ntime.tv_sec + delay2;
+			fastelection = ntime.tv_sec + FASTTOUT;
+			adjtime = ntime.tv_sec + SAMPLEINTVL*2;
+			break;
+
+		case TSP_SETTIME:
+			if (fromnet != slavenet)
+				break;
+			if (seq == msg->tsp_seq)
+				break;
+			seq = msg->tsp_seq;
+
+			/* adjust time for residence on the queue */
+			(void)gettimeofday(&otime, 0);
+			adj_msg_time(msg,&otime);
+#ifdef sgi
+			(void)cftime(newdate, "%D %T", &msg->tsp_time.tv_sec);
+			(void)cftime(olddate, "%D %T", &otime.tv_sec);
+#else
+			/*
+			 * the following line is necessary due to syslog
+			 * calling ctime() which clobbers the static buffer
+			 */
+			(void)strcpy(olddate, date());
+			(void)strcpy(newdate, ctime(&msg->tsp_time.tv_sec));
+#endif /* sgi */
+
+			if (!good_host_name(msg->tsp_name)) {
+				syslog(LOG_NOTICE,
+			    "attempted time setting by untrusted %s to %s",
+				       msg->tsp_name, newdate);
+				suppress(&from, msg->tsp_name, fromnet);
+				break;
+			}
+
+			setmaster(msg);
+			timevalsub(&ntime, &msg->tsp_time, &otime);
+			if (ntime.tv_sec < MAXADJ && ntime.tv_sec > -MAXADJ) {
+				/*
+				 * do not change the clock if we can adjust it
+				 */
+				synch(tvtomsround(ntime));
+			} else {
+#ifdef sgi
+				if (0 > settimeofday(&msg->tsp_time, 0)) {
+					syslog(LOG_ERR,"settimeofdate(): %m");
+					break;
+				}
+				logwtmp(&otime, &msg->tsp_time);
+#else
+				logwtmp("|", "date", "");
+				(void)settimeofday(&msg->tsp_time, 0);
+				logwtmp("}", "date", "");
+#endif /* sgi */
+				syslog(LOG_NOTICE,
+				       "date changed by %s from %s",
+					msg->tsp_name, olddate);
+				if (status & MASTER)
+					spreadtime();
+			}
+			(void)gettimeofday(&ntime, 0);
+			electiontime = ntime.tv_sec + delay2;
+			fastelection = ntime.tv_sec + FASTTOUT;
+
+/* This patches a bad protocol bug.  Imagine a system with several networks,
+ * where there are a pair of redundant gateways between a pair of networks,
+ * each running timed.  Assume that we start with a third machine mastering
+ * one of the networks, and one of the gateways mastering the other.
+ * Imagine that the third machine goes away and the non-master gateway
+ * decides to replace it.  If things are timed just 'right,' we will have
+ * each gateway mastering one network for a little while.  If a SETTIME
+ * message gets into the network at that time, perhaps from the newly
+ * masterful gateway as it was taking control, the SETTIME will loop
+ * forever.  Each time a gateway receives it on its slave side, it will
+ * call spreadtime to forward it on its mastered network.  We are now in
+ * a permanent loop, since the SETTIME msgs will keep any clock
+ * in the network from advancing.  Normally, the 'LOOP' stuff will detect
+ * and correct the situation.  However, with the clocks stopped, the
+ * 'looptime' timer cannot expire.  While they are in this state, the
+ * masters will try to saturate the network with SETTIME packets.
+ */
+			looptime = ntime.tv_sec + (looptime-otime.tv_sec)/2-1;
+			break;
+
+		case TSP_MASTERUP:
+			if (slavenet && fromnet != slavenet)
+				break;
+			if (!good_host_name(msg->tsp_name)) {
+				suppress(&from, msg->tsp_name, fromnet);
+				if (electiontime > fastelection)
+					electiontime = fastelection;
+				break;
+			}
+			makeslave(fromnet);
+			setmaster(msg);
+			setstatus();
+			answerdelay();
+			xmit(TSP_SLAVEUP, 0, &from);
+			(void)gettimeofday(&ntime, 0);
+			electiontime = ntime.tv_sec + delay2;
+			fastelection = ntime.tv_sec + FASTTOUT;
+			refusetime = 0;
+			break;
+
+		case TSP_MASTERREQ:
+			if (fromnet->status != SLAVE)
+				break;
+			(void)gettimeofday(&ntime, 0);
+			electiontime = ntime.tv_sec + delay2;
+			break;
+
+		case TSP_SETDATE:
+#ifdef sgi
+			(void)cftime(newdate, "%D %T", &msg->tsp_time.tv_sec);
+#else
+			(void)strcpy(newdate, ctime(&msg->tsp_time.tv_sec));
+#endif /* sgi */
+			schgdate(msg, newdate);
+			break;
+
+		case TSP_SETDATEREQ:
+			if (fromnet->status != MASTER)
+				break;
+#ifdef sgi
+			(void)cftime(newdate, "%D %T", &msg->tsp_time.tv_sec);
+#else
+			(void)strcpy(newdate, ctime(&msg->tsp_time.tv_sec));
+#endif /* sgi */
+			htp = findhost(msg->tsp_name);
+			if (0 == htp) {
+				syslog(LOG_WARNING,
+				       "DATEREQ from uncontrolled machine");
+				break;
+			}
+			if (!htp->good) {
+				syslog(LOG_WARNING,
+				"attempted date change by untrusted %s to %s",
+				       htp->name, newdate);
+				spreadtime();
+				break;
+			}
+			schgdate(msg, newdate);
+			break;
+
+		case TSP_TRACEON:
+			traceon();
+			break;
+
+		case TSP_TRACEOFF:
+			traceoff("Tracing ended at %s\n");
+			break;
+
+		case TSP_SLAVEUP:
+			newslave(msg);
+			break;
+
+		case TSP_ELECTION:
+			if (fromnet->status == SLAVE) {
+				(void)gettimeofday(&ntime, 0);
+				electiontime = ntime.tv_sec + delay2;
+				fastelection = ntime.tv_sec + FASTTOUT;
+				seq = 0;
+				if (!good_host_name(msg->tsp_name)) {
+					syslog(LOG_NOTICE,
+					       "suppress election of %s",
+					       msg->tsp_name);
+					to.tsp_type = TSP_QUIT;
+					electiontime = fastelection;
+				} else if (cadr.s_addr != from.sin_addr.s_addr
+					   && ntime.tv_sec < refusetime) {
+/* if the candidate has to repeat itself, the old code would refuse it
+ * the second time.  That would prevent elections.
+ */
+					to.tsp_type = TSP_REFUSE;
+				} else {
+					cadr.s_addr = from.sin_addr.s_addr;
+					to.tsp_type = TSP_ACCEPT;
+					refusetime = ntime.tv_sec + 30;
+				}
+				taddr = from;
+				(void)strcpy(tname, msg->tsp_name);
+				(void)strcpy(to.tsp_name, hostname);
+				answerdelay();
+				if (!acksend(&to, &taddr, tname,
+					     TSP_ACK, 0, 0))
+					syslog(LOG_WARNING,
+					     "no answer from candidate %s\n",
+					       tname);
+
+			} else {	/* fromnet->status == MASTER */
+				htp = addmach(msg->tsp_name, &from,fromnet);
+				to.tsp_type = TSP_QUIT;
+				(void)strcpy(to.tsp_name, hostname);
+				if (!acksend(&to, &htp->addr, htp->name,
+					     TSP_ACK, 0, htp->noanswer)) {
+					syslog(LOG_ERR,
+					  "no reply from %s to ELECTION-QUIT",
+					       htp->name);
+					(void)remmach(htp);
+				}
+			}
+			break;
+
+		case TSP_CONFLICT:
+			if (fromnet->status != MASTER)
+				break;
+			/*
+			 * After a network partition, there can be
+			 * more than one master: the first slave to
+			 * come up will notify here the situation.
+			 */
+			(void)strcpy(to.tsp_name, hostname);
+
+			/* The other master often gets into the same state,
+			 * with boring results.
+			 */
+			ntp = fromnet;	/* (acksend() can leave fromnet=0 */
+			for (tries = 0; tries < 3; tries++) {
+				to.tsp_type = TSP_RESOLVE;
+				answer = acksend(&to, &ntp->dest_addr,
+						 ANYADDR, TSP_MASTERACK,
+						 ntp, 0);
+				if (answer == NULL)
+					break;
+				htp = addmach(answer->tsp_name,&from,ntp);
+				to.tsp_type = TSP_QUIT;
+				answer = acksend(&to, &htp->addr, htp->name,
+						 TSP_ACK, 0, htp->noanswer);
+				if (!answer) {
+					syslog(LOG_WARNING,
+				  "conflict error: no reply from %s to QUIT",
+						htp->name);
+					(void)remmach(htp);
+				}
+			}
+			masterup(ntp);
+			break;
+
+		case TSP_MSITE:
+			if (!slavenet)
+				break;
+			taddr = from;
+			to.tsp_type = TSP_MSITEREQ;
+			to.tsp_vers = TSPVERSION;
+			to.tsp_seq = 0;
+			(void)strcpy(to.tsp_name, hostname);
+			answer = acksend(&to, &slavenet->dest_addr,
+					 ANYADDR, TSP_ACK,
+					 slavenet, 0);
+			if (answer != NULL
+			    && good_host_name(answer->tsp_name)) {
+				setmaster(answer);
+				to.tsp_type = TSP_ACK;
+				(void)strcpy(to.tsp_name, answer->tsp_name);
+				bytenetorder(&to);
+				if (sendto(sock, (char *)&to,
+					   sizeof(struct tsp), 0,
+					   (struct sockaddr*)&taddr, sizeof(taddr)) < 0) {
+					trace_sendto_err(taddr.sin_addr);
+				}
+			}
+			break;
+
+		case TSP_MSITEREQ:
+			break;
+
+		case TSP_ACCEPT:
+		case TSP_REFUSE:
+		case TSP_RESOLVE:
+			break;
+
+		case TSP_QUIT:
+			doquit(msg);		/* become a slave */
+			break;
+
+		case TSP_TEST:
+			electiontime = 0;
+			break;
+
+		case TSP_LOOP:
+			/* looking for loops of masters */
+			if (!(status & MASTER))
+				break;
+			if (fromnet->status == SLAVE) {
+			    if (!strcmp(msg->tsp_name, hostname)) {
+				/*
+				 * Someone forwarded our message back to
+				 * us.  There must be a loop.  Tell the
+				 * master of this network to quit.
+				 *
+				 * The other master often gets into
+				 * the same state, with boring results.
+				 */
+				ntp = fromnet;
+				for (tries = 0; tries < 3; tries++) {
+				    to.tsp_type = TSP_RESOLVE;
+				    answer = acksend(&to, &ntp->dest_addr,
+						     ANYADDR, TSP_MASTERACK,
+						     ntp,0);
+				    if (answer == NULL)
+					break;
+				    taddr = from;
+				    (void)strcpy(tname, answer->tsp_name);
+				    to.tsp_type = TSP_QUIT;
+				    (void)strcpy(to.tsp_name, hostname);
+				    if (!acksend(&to, &taddr, tname,
+						 TSP_ACK, 0, 1)) {
+					syslog(LOG_ERR,
+					"no reply from %s to slave LOOP-QUIT",
+						 tname);
+				    } else {
+					electiontime = 0;
+				    }
+				}
+				(void)gettimeofday(&ntime, 0);
+				looptime = ntime.tv_sec + FASTTOUT;
+			    } else {
+				if (msg->tsp_hopcnt-- < 1)
+				    break;
+				bytenetorder(msg);
+				for (ntp = nettab; ntp != 0; ntp = ntp->next) {
+				    if (ntp->status == MASTER
+					&& 0 > sendto(sock, (char *)msg,
+						      sizeof(struct tsp), 0,
+					      (struct sockaddr*)&ntp->dest_addr,
+						      sizeof(ntp->dest_addr)))
+				    trace_sendto_err(ntp->dest_addr.sin_addr);
+				}
+			    }
+			} else {	/* fromnet->status == MASTER */
+			    /*
+			     * We should not have received this from a net
+			     * we are master on.  There must be two masters,
+			     * unless the packet was really from us.
+			     */
+			    if (from.sin_addr.s_addr
+				== fromnet->my_addr.s_addr) {
+				if (trace)
+				    fprintf(fd,"discarding forwarded LOOP\n");
+				break;
+			    }
+
+			    /*
+			     * The other master often gets into the same
+			     * state, with boring results.
+			     */
+			    ntp = fromnet;
+			    for (tries = 0; tries < 3; tries++) {
+				to.tsp_type = TSP_RESOLVE;
+				answer = acksend(&to, &ntp->dest_addr,
+						 ANYADDR, TSP_MASTERACK,
+						ntp,0);
+				if (!answer)
+					break;
+				htp = addmach(answer->tsp_name,
+					      &from,ntp);
+				to.tsp_type = TSP_QUIT;
+				(void)strcpy(to.tsp_name, hostname);
+				if (!acksend(&to,&htp->addr,htp->name,
+					     TSP_ACK, 0, htp->noanswer)) {
+					syslog(LOG_ERR,
+				    "no reply from %s to master LOOP-QUIT",
+					       htp->name);
+					(void)remmach(htp);
+				}
+			    }
+			    (void)gettimeofday(&ntime, 0);
+			    looptime = ntime.tv_sec + FASTTOUT;
+			}
+			break;
+		default:
+			if (trace) {
+				fprintf(fd, "garbage message: ");
+				print(msg, &from);
+			}
+			break;
+		}
+	}
+	goto loop;
+}
+
+
+/*
+ * tell the world who our master is
+ */
+static void
+setmaster(msg)
+	struct tsp *msg;
+{
+	if (slavenet
+	    && (slavenet != old_slavenet
+		|| strcmp(msg->tsp_name, master_name)
+		|| old_status != status)) {
+		(void)strcpy(master_name, msg->tsp_name);
+		old_slavenet = slavenet;
+		old_status = status;
+
+		if (status & MASTER) {
+			syslog(LOG_NOTICE, "submaster to %s", master_name);
+			if (trace)
+				fprintf(fd, "submaster to %s\n", master_name);
+
+		} else {
+			syslog(LOG_NOTICE, "slave to %s", master_name);
+			if (trace)
+				fprintf(fd, "slave to %s\n", master_name);
+		}
+	}
+}
+
+
+
+/*
+ * handle date change request on a slave
+ */
+static void
+schgdate(msg, newdate)
+	struct tsp *msg;
+	char *newdate;
+{
+	struct tsp to;
+	u_short seq;
+	struct sockaddr_in taddr;
+	struct timeval otime;
+
+	if (!slavenet)
+		return;			/* no where to forward */
+
+	taddr = from;
+	seq = msg->tsp_seq;
+
+	syslog(LOG_INFO,
+	       "forwarding date change by %s to %s",
+	       msg->tsp_name, newdate);
+
+	/* adjust time for residence on the queue */
+	(void)gettimeofday(&otime, 0);
+	adj_msg_time(msg, &otime);
+
+	to.tsp_type = TSP_SETDATEREQ;
+	to.tsp_time = msg->tsp_time;
+	(void)strcpy(to.tsp_name, hostname);
+	if (!acksend(&to, &slavenet->dest_addr,
+		     ANYADDR, TSP_DATEACK,
+		     slavenet, 0))
+		return;			/* no answer */
+
+	xmit(TSP_DATEACK, seq, &taddr);
+}
+
+
+/*
+ * Used before answering a broadcast message to avoid network
+ * contention and likely collisions.
+ */
+static void
+answerdelay()
+{
+#ifdef sgi
+	sginap(delay1);
+#else
+	struct timeval timeout;
+
+	timeout.tv_sec = 0;
+	timeout.tv_usec = delay1;
+
+	(void)select(0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL,
+	    &timeout);
+	return;
+#endif /* sgi */
+}
diff --git a/timed.tproj/timed.tproj/timed.8 b/timed.tproj/timed.tproj/timed.8
new file mode 100644
index 0000000..8f8798d
--- /dev/null
+++ b/timed.tproj/timed.tproj/timed.8
@@ -0,0 +1,219 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)timed.8	8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt TIMED 8
+.Os BSD 4.3
+.Sh NAME
+.Nm timed
+.Nd time server daemon
+.Sh SYNOPSIS
+.Nm timed
+.Op Fl M
+.Op Fl t
+.Op Fl d
+.Op Fl i Ar network
+.Op Fl n Ar network
+.Op Fl F Ar host1 host2 ...
+.Sh DESCRIPTION
+This
+is a time server daemon and is normally invoked
+at boot time from the
+.Xr rc 8
+file.  
+It synchronizes the host's time with the time of other
+machines in a local area network running 
+.Nm timed 8 .
+These time servers will slow down the clocks of some machines
+and speed up the clocks of others to bring them to the average network time.
+The average network time is computed from measurements of clock differences
+using the
+.Tn ICMP
+timestamp request message.
+.Pp
+The service provided by
+.Nm timed
+is based  on a master-slave
+scheme.
+When
+.Nm timed 8
+is started on a machine, it asks the master for the network time
+and sets the host's clock to that time.
+After that, it accepts synchronization messages periodically sent by
+the master and calls 
+.Xr adjtime 2
+to perform the needed corrections on the host's clock.
+.Pp
+It also communicates with
+.Xr date 1
+in order to set the date globally,
+and with 
+.Xr timedc 8 ,
+a timed control program.
+If the machine running the master crashes, then the slaves will elect
+a new master from among slaves running with the 
+.Fl M
+flag.
+A
+.Nm timed
+running without the
+.Fl M
+or
+.Fl F
+flags will remain a slave.
+The 
+.Fl t
+flag enables
+.Nm timed
+to trace the messages it receives in the
+file
+.Pa /var/log/timed.log .
+Tracing can be turned on or off by the program
+.Xr timedc 8 .
+The
+.Fl d
+flag is for debugging the daemon.
+It causes the program to not put itself into the background.
+Normally
+.Nm timed
+checks for a master time server on each network to which
+it is connected, except as modified by the options described below.
+It will request synchronization service from the first master server
+located.
+If permitted by the
+.Fl M
+flag, it will provide synchronization service on any attached networks
+on which no current master server was detected.
+Such a server propagates the time computed by the top-level master.
+The 
+.Fl n
+flag, followed by the name of a network which the host is connected to
+(see
+.Xr networks 5 ) ,
+overrides the default choice of the
+network addresses made by the program.
+Each time the
+.Fl n
+flag appears, that network name is added to a list of valid networks.
+All other networks are ignored.
+The 
+.Fl i
+flag, followed by the name of a network to which the host is connected
+(see
+.Xr networks 5 ) ,
+overrides the default choice of the network addresses made by the program.
+Each time the
+.Fl i
+flag appears, that network name is added to a list of networks to ignore.
+All other networks are used by the time daemon.
+The
+.Fl n
+and 
+.Fl i
+flags are meaningless if used together.
+.Pp
+.Nm Timed
+checks for a master time server on each network to which
+it is connected, except as modified by the
+.Fl n
+and
+.Fl i
+options described above.
+If it finds masters on more than one network, it chooses one network
+on which to be a "slave," and then periodically checks the other
+networks to see if the masters there have disappeared.
+.Pp
+One way to synchronize a group of machines is to use an NTP daemon to 
+synchronize the clock of one machine to a distant standard or a radio
+receiver and 
+.Fl F Ar hostname
+to tell its timed daemon to trust only itself.
+.Pp
+Messages printed by the kernel on the system console occur with
+interrupts disabled. 
+This means that the clock stops while they are printing.
+A machine with many disk or network hardware problems and consequent
+messages cannot keep good time by itself.  Each message typically causes
+the clock to lose a dozen milliseconds.  A time daemon can
+correct the result.
+.Pp
+Messages in the system log about machines that failed to respond
+usually indicate machines that crashed or were turned off.
+Complaints about machines that failed to respond to initial time
+settings are often associated with "multi-homed" machines
+that looked for time masters on more than one network and eventually
+chose to become a slave on the other network.
+.SH WARNING
+If two or more time daemons, whether 
+.Nm timed ,
+.Xr NTP ,
+try to adjust the same clock, temporal chaos will result.
+If both 
+.Nm
+and another time daemon are run on the same machine,
+ensure that the 
+.Fl F
+flag is used, so that 
+.Nm timed
+never attempts to adjust the local clock.
+.Pp 
+The protocol is based on UDP/IP broadcasts.  All machines within
+the range of a broadcast that are using the TSP protocol must cooperate.
+There cannot be more than a single administrative domain using the
+.Fl F
+flag among all machines reached by a broadcast packet.
+Failure to follow this rule is usually indicated by complaints concerning
+"untrusted" machines in the system log.
+.Sh FILES
+.Bl -tag -width /var/log/timed.masterlog -compact
+.It Pa /var/log/timed.log
+tracing file for timed
+.It Pa /var/log/timed.masterlog
+log file for master timed 
+.El
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr adjtime 2 ,
+.Xr gettimeofday 2 ,
+.Xr icmp 4 ,
+.Xr timedc 8 ,
+.Rs
+.%T "TSP: The Time Synchronization Protocol for UNIX 4.3BSD"
+.%A R. Gusella
+.%A S. Zatti
+.Re
+.Sh HISTORY
+The
+.Nm
+daemon appeared in
+.Bx 4.3 .
diff --git a/timed.tproj/timed.tproj/timed.c b/timed.tproj/timed.tproj/timed.c
new file mode 100644
index 0000000..01fa981
--- /dev/null
+++ b/timed.tproj/timed.tproj/timed.c
@@ -0,0 +1,1006 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1985, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)timed.c	8.2 (Berkeley) 3/26/95";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif /* sgi */
+
+#define TSPTYPES
+#include "globals.h"
+#include <net/if.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <setjmp.h>
+#include "pathnames.h"
+#include <math.h>
+#include <sys/types.h>
+#include <sys/times.h>
+#ifdef sgi
+#include <unistd.h>
+#include <sys/syssgi.h>
+#include <sys/schedctl.h>
+#endif /* sgi */
+
+int trace = 0;
+int sock, sock_raw = -1;
+int status = 0;
+u_short sequence;			/* sequence number */
+long delay1;
+long delay2;
+
+int nslavenets;				/* nets were I could be a slave */
+int nmasternets;			/* nets were I could be a master */
+int nignorednets;			/* ignored nets */
+int nnets;				/* nets I am connected to */
+
+FILE *fd;				/* trace file FD */
+
+jmp_buf jmpenv;
+
+struct netinfo *nettab = 0;
+struct netinfo *slavenet;
+int Mflag;
+int justquit = 0;
+int debug;
+
+static struct nets {
+	char	*name;
+	long	net;
+	struct nets *next;
+} *nets = 0;
+
+struct hosttbl hosttbl[NHOSTS+1];	/* known hosts */
+
+static struct goodhost {		/* hosts that we trust */
+	char	name[MAXHOSTNAMELEN+1];
+	struct goodhost *next;
+	char	perm;
+} *goodhosts;
+
+static char *goodgroup;			/* net group of trusted hosts */
+static void checkignorednets __P((void));
+static void pickslavenet __P((struct netinfo *));
+static void add_good_host __P((char *, int));
+
+#ifdef sgi
+char *timetrim_fn;
+char *timetrim_wpat = "long timetrim = %ld;\ndouble tot_adj = %.0f;\ndouble tot_ticks = %.0f;\n/* timed version 2 */\n";
+char *timetrim_rpat = "long timetrim = %ld;\ndouble tot_adj = %lf;\ndouble tot_ticks = %lf;";
+long timetrim;
+double tot_adj, hr_adj;			/* totals in nsec */
+double tot_ticks, hr_ticks;
+
+int bufspace = 60*1024;
+#endif
+
+
+/*
+ * The timedaemons synchronize the clocks of hosts in a local area network.
+ * One daemon runs as master, all the others as slaves. The master
+ * performs the task of computing clock differences and sends correction
+ * values to the slaves.
+ * Slaves start an election to choose a new master when the latter disappears
+ * because of a machine crash, network partition, or when killed.
+ * A resolution protocol is used to kill all but one of the masters
+ * that happen to exist in segments of a partitioned network when the
+ * network partition is fixed.
+ *
+ * Authors: Riccardo Gusella & Stefano Zatti
+ *
+ * overhauled at Silicon Graphics
+ */
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int on;
+	int ret;
+	int nflag, iflag;
+	struct timeval ntime;
+	struct servent *srvp;
+	char buf[BUFSIZ], *cp, *cplim;
+	struct ifconf ifc;
+	struct ifreq ifreq, ifreqf, *ifr;
+	register struct netinfo *ntp;
+	struct netinfo *ntip;
+	struct netinfo *savefromnet;
+	struct netent *nentp;
+	struct nets *nt;
+	static struct sockaddr_in server;
+	u_short port;
+	char c;
+	extern char *optarg;
+	extern int optind, opterr;
+#ifdef sgi
+	FILE *timetrim_st;
+#endif
+
+#define	IN_MSG "timed: -i and -n make no sense together\n"
+#ifdef sgi
+	struct tms tms;
+#define USAGE "timed: [-dtM] [-i net|-n net] [-F host1 host2 ...] [-G netgp] [-P trimfile]\n"
+#else
+#ifdef HAVENIS
+#define USAGE "timed: [-dtM] [-i net|-n net] [-F host1 host2 ...] [-G netgp]\n"
+#else
+#define USAGE "timed: [-dtM] [-i net|-n net] [-F host1 host2 ...]\n"
+#endif /* HAVENIS */
+#endif /* sgi */
+
+#ifdef lint
+	ntip = NULL;
+#endif
+
+	on = 1;
+	nflag = OFF;
+	iflag = OFF;
+
+#ifdef sgi
+	if (0 > syssgi(SGI_GETTIMETRIM, &timetrim)) {
+		perror("timed: syssgi(GETTIMETRIM)");
+		timetrim = 0;
+	}
+	tot_ticks = hr_ticks = times(&tms);
+#endif /* sgi */
+
+	opterr = 0;
+	while ((c = getopt(argc, argv, "Mtdn:i:F:G:P:")) != EOF) {
+		switch (c) {
+		case 'M':
+			Mflag = 1;
+			break;
+
+		case 't':
+			trace = 1;
+			break;
+
+		case 'n':
+			if (iflag) {
+				fprintf(stderr, IN_MSG);
+				exit(1);
+			} else {
+				nflag = ON;
+				addnetname(optarg);
+			}
+			break;
+
+		case 'i':
+			if (nflag) {
+				fprintf(stderr, IN_MSG);
+				exit(1);
+			} else {
+				iflag = ON;
+				addnetname(optarg);
+			}
+			break;
+
+		case 'F':
+			add_good_host(optarg,1);
+			while (optind < argc && argv[optind][0] != '-')
+				add_good_host(argv[optind++], 1);
+			break;
+
+		case 'd':
+			debug = 1;
+			break;
+		case 'G':
+			if (goodgroup != 0) {
+				fprintf(stderr,"timed: only one net group\n");
+				exit(1);
+			}
+			goodgroup = optarg;
+			break;
+#ifdef sgi
+		case 'P':
+			timetrim_fn = optarg;
+			break;
+#endif /* sgi */
+
+		default:
+			fprintf(stderr, USAGE);
+			exit(1);
+			break;
+		}
+	}
+	if (optind < argc) {
+		fprintf(stderr, USAGE);
+		exit(1);
+	}
+
+#ifdef sgi
+	if (timetrim_fn == 0) {
+		;
+	} else if (0 == (timetrim_st = fopen(timetrim_fn, "r+"))) {
+		if (errno != ENOENT) {
+			(void)fprintf(stderr,"timed: ");
+			perror(timetrim_fn);
+			timetrim_fn = 0;
+		}
+	} else {
+		int i;
+		long trim;
+		double adj, ticks;
+
+		i = fscanf(timetrim_st, timetrim_rpat,
+			   &trim, &adj, &ticks);
+		if (i < 1
+		    || trim > MAX_TRIM
+		    || trim < -MAX_TRIM
+		    || i == 2
+		    || (i == 3
+			&& trim != rint(adj*CLK_TCK/ticks))) {
+			if (trace && i != EOF)
+				(void)fprintf(stderr,
+		    "timed: unrecognized contents in %s\n",
+					      timetrim_fn);
+		} else {
+			if (0 > syssgi(SGI_SETTIMETRIM,
+				       trim)) {
+			 perror("timed: syssgi(SETTIMETRIM)");
+			} else {
+				timetrim = trim;
+			}
+			if (i == 3)
+				tot_ticks -= ticks;
+		}
+		(void)fclose(timetrim_st);
+	}
+#endif /* sgi */
+
+	/* If we care about which machine is the master, then we must
+	 *	be willing to be a master
+	 */
+	if (0 != goodgroup || 0 != goodhosts)
+		Mflag = 1;
+
+	if (gethostname(hostname, sizeof(hostname) - 1) < 0) {
+		perror("gethostname");
+		exit(1);
+	}
+	self.l_bak = &self;
+	self.l_fwd = &self;
+	self.h_bak = &self;
+	self.h_fwd = &self;
+	self.head = 1;
+	self.good = 1;
+
+	if (goodhosts != 0)		/* trust ourself */
+		add_good_host(hostname,1);
+
+	srvp = getservbyname("timed", "udp");
+	if (srvp == 0) {
+		fprintf(stderr, "unknown service 'timed/udp'\n");
+		exit(1);
+	}
+	port = srvp->s_port;
+	server.sin_addr.s_addr = INADDR_ANY;
+	server.sin_port = srvp->s_port;
+	server.sin_family = AF_INET;
+	sock = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sock < 0) {
+		perror("socket");
+		exit(1);
+	}
+	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on,
+							sizeof(on)) < 0) {
+		perror("setsockopt");
+		exit(1);
+	}
+	if (bind(sock, (struct sockaddr*)&server, sizeof(server))) {
+		if (errno == EADDRINUSE)
+			fprintf(stderr,"timed: time daemon already running\n");
+		else
+			perror("bind");
+		exit(1);
+	}
+#ifdef sgi
+	/*
+	 * handle many slaves with our buffer
+	 */
+	if (0 > setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufspace,
+			 sizeof(bufspace))) {
+		perror("setsockopt");
+		exit(1);
+	}
+#endif /* sgi */
+
+	/* choose a unique seed for random number generation */
+	(void)gettimeofday(&ntime, 0);
+	srandom(ntime.tv_sec + ntime.tv_usec);
+
+	sequence = random();     /* initial seq number */
+
+#ifndef sgi
+	/* rounds kernel variable time to multiple of 5 ms. */
+	ntime.tv_sec = 0;
+	ntime.tv_usec = -((ntime.tv_usec/1000) % 5) * 1000;
+	(void)adjtime(&ntime, (struct timeval *)0);
+#endif /* sgi */
+
+	for (nt = nets; nt; nt = nt->next) {
+		nentp = getnetbyname(nt->name);
+		if (nentp == 0) {
+			nt->net = inet_network(nt->name);
+			if (nt->net != INADDR_NONE)
+				nentp = getnetbyaddr(nt->net, AF_INET);
+		}
+		if (nentp != 0) {
+			nt->net = nentp->n_net;
+		} else if (nt->net == INADDR_NONE) {
+			fprintf(stderr, "timed: unknown net %s\n", nt->name);
+			exit(1);
+		} else if (nt->net == INADDR_ANY) {
+			fprintf(stderr, "timed: bad net %s\n", nt->name);
+			exit(1);
+		} else {
+			fprintf(stderr,
+				"timed: warning: %s unknown in /etc/networks\n",
+				nt->name);
+		}
+
+		if (0 == (nt->net & 0xff000000))
+		    nt->net <<= 8;
+		if (0 == (nt->net & 0xff000000))
+		    nt->net <<= 8;
+		if (0 == (nt->net & 0xff000000))
+		    nt->net <<= 8;
+	}
+	ifc.ifc_len = sizeof(buf);
+	ifc.ifc_buf = buf;
+	if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+		perror("timed: get interface configuration");
+		exit(1);
+	}
+	ntp = NULL;
+#ifdef sgi
+#define size(p)	(sizeof(*ifr) - sizeof(ifr->ifr_name))  /* XXX hack. kludge */
+#else
+#define size(p)	max((p).sa_len, sizeof(p))
+#endif
+	cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
+	for (cp = buf; cp < cplim;
+			cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
+		ifr = (struct ifreq *)cp;
+		if (ifr->ifr_addr.sa_family != AF_INET)
+			continue;
+		if (!ntp)
+			ntp = (struct netinfo*)malloc(sizeof(struct netinfo));
+		bzero(ntp,sizeof(*ntp));
+		ntp->my_addr=((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
+		ntp->status = NOMASTER;
+		ifreq = *ifr;
+		ifreqf = *ifr;
+
+		if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreqf) < 0) {
+			perror("get interface flags");
+			continue;
+		}
+		if ((ifreqf.ifr_flags & IFF_UP) == 0)
+			continue;
+		if ((ifreqf.ifr_flags & IFF_BROADCAST) == 0 &&
+		    (ifreqf.ifr_flags & IFF_POINTOPOINT) == 0) {
+			continue;
+		}
+
+
+		if (ioctl(sock, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
+			perror("get netmask");
+			continue;
+		}
+		ntp->mask = ((struct sockaddr_in *)
+			&ifreq.ifr_addr)->sin_addr.s_addr;
+
+		if (ifreqf.ifr_flags & IFF_BROADCAST) {
+			if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
+				perror("get broadaddr");
+				continue;
+			}
+			ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_broadaddr;
+			/* What if the broadcast address is all ones?
+			 * So we cannot just mask ntp->dest_addr.  */
+			ntp->net = ntp->my_addr;
+			ntp->net.s_addr &= ntp->mask;
+		} else {
+			if (ioctl(sock, SIOCGIFDSTADDR,
+						(char *)&ifreq) < 0) {
+				perror("get destaddr");
+				continue;
+			}
+			ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_dstaddr;
+			ntp->net = ntp->dest_addr.sin_addr;
+		}
+
+		ntp->dest_addr.sin_port = port;
+
+		for (nt = nets; nt; nt = nt->next) {
+			if (ntp->net.s_addr == nt->net)
+				break;
+		}
+		if (nflag && !nt || iflag && nt)
+			continue;
+
+		ntp->next = NULL;
+		if (nettab == NULL) {
+			nettab = ntp;
+		} else {
+			ntip->next = ntp;
+		}
+		ntip = ntp;
+		ntp = NULL;
+	}
+	if (ntp)
+		(void) free((char *)ntp);
+	if (nettab == NULL) {
+		fprintf(stderr, "timed: no network usable\n");
+		exit(1);
+	}
+
+
+#ifdef sgi
+	(void)schedctl(RENICE,0,10);	   /* run fast to get good time */
+
+	/* ticks to delay before responding to a broadcast */
+	delay1 = casual(0, CLK_TCK/10);
+#else
+
+	/* microseconds to delay before responding to a broadcast */
+	delay1 = casual(1, 100*1000);
+#endif /* sgi */
+
+	/* election timer delay in secs. */
+	delay2 = casual(MINTOUT, MAXTOUT);
+
+
+#ifdef sgi
+	(void)_daemonize(debug ? _DF_NOFORK|_DF_NOCHDIR : 0, sock, -1, -1);
+#else
+	if (!debug)
+		daemon(debug, 0);
+#endif /* sgi */
+
+	if (trace)
+		traceon();
+	openlog("timed", LOG_CONS|LOG_PID, LOG_DAEMON);
+
+	/*
+	 * keep returning here
+	 */
+	ret = setjmp(jmpenv);
+	savefromnet = fromnet;
+	setstatus();
+
+	if (Mflag) {
+		switch (ret) {
+
+		case 0:
+			checkignorednets();
+			pickslavenet(0);
+			break;
+		case 1:
+			/* Just lost our master */
+			if (slavenet != 0)
+				slavenet->status = election(slavenet);
+			if (!slavenet || slavenet->status == MASTER) {
+				checkignorednets();
+				pickslavenet(0);
+			} else {
+				makeslave(slavenet);	/* prune extras */
+			}
+			break;
+
+		case 2:
+			/* Just been told to quit */
+			justquit = 1;
+			pickslavenet(savefromnet);
+			break;
+		}
+
+		setstatus();
+		if (!(status & MASTER) && sock_raw != -1) {
+			/* sock_raw is not being used now */
+			(void)close(sock_raw);
+			sock_raw = -1;
+		}
+
+		if (status == MASTER)
+			master();
+		else
+			slave();
+
+	} else {
+		if (sock_raw != -1) {
+			(void)close(sock_raw);
+			sock_raw = -1;
+		}
+
+		if (ret) {
+			/* we just lost our master or were told to quit */
+			justquit = 1;
+		}
+		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+			if (ntp->status == MASTER)
+				rmnetmachs(ntp);
+				ntp->status = NOMASTER;
+		}
+		checkignorednets();
+		pickslavenet(0);
+		setstatus();
+
+		slave();
+	}
+	/* NOTREACHED */
+#ifdef lint
+	return(0);
+#endif
+}
+
+/*
+ * suppress an upstart, untrustworthy, self-appointed master
+ */
+void
+suppress(addr, name,net)
+	struct sockaddr_in *addr;
+	char *name;
+	struct netinfo *net;
+{
+	struct sockaddr_in tgt;
+	char tname[MAXHOSTNAMELEN];
+	struct tsp msg;
+	static struct timeval wait;
+
+	if (trace)
+		fprintf(fd, "suppress: %s\n", name);
+	tgt = *addr;
+	(void)strcpy(tname, name);
+
+	while (0 != readmsg(TSP_ANY, ANYADDR, &wait, net)) {
+		if (trace)
+			fprintf(fd, "suppress:\tdiscarded packet from %s\n",
+				    name);
+	}
+
+	syslog(LOG_NOTICE, "suppressing false master %s", tname);
+	msg.tsp_type = TSP_QUIT;
+	(void)strcpy(msg.tsp_name, hostname);
+	(void)acksend(&msg, &tgt, tname, TSP_ACK, 0, 1);
+}
+
+void
+lookformaster(ntp)
+	struct netinfo *ntp;
+{
+	struct tsp resp, conflict, *answer;
+	struct timeval ntime;
+	char mastername[MAXHOSTNAMELEN];
+	struct sockaddr_in masteraddr;
+
+	get_goodgroup(0);
+	ntp->status = SLAVE;
+
+	/* look for master */
+	resp.tsp_type = TSP_MASTERREQ;
+	(void)strcpy(resp.tsp_name, hostname);
+	answer = acksend(&resp, &ntp->dest_addr, ANYADDR,
+			 TSP_MASTERACK, ntp, 0);
+	if (answer != 0 && !good_host_name(answer->tsp_name)) {
+		suppress(&from, answer->tsp_name, ntp);
+		ntp->status = NOMASTER;
+		answer = 0;
+	}
+	if (answer == 0) {
+		/*
+		 * Various conditions can cause conflict: races between
+		 * two just started timedaemons when no master is
+		 * present, or timedaemons started during an election.
+		 * A conservative approach is taken.  Give up and became a
+		 * slave, postponing election of a master until first
+		 * timer expires.
+		 */
+		ntime.tv_sec = ntime.tv_usec = 0;
+		answer = readmsg(TSP_MASTERREQ, ANYADDR, &ntime, ntp);
+		if (answer != 0) {
+			if (!good_host_name(answer->tsp_name)) {
+				suppress(&from, answer->tsp_name, ntp);
+				ntp->status = NOMASTER;
+			}
+			return;
+		}
+
+		ntime.tv_sec = ntime.tv_usec = 0;
+		answer = readmsg(TSP_MASTERUP, ANYADDR, &ntime, ntp);
+		if (answer != 0) {
+			if (!good_host_name(answer->tsp_name)) {
+				suppress(&from, answer->tsp_name, ntp);
+				ntp->status = NOMASTER;
+			}
+			return;
+		}
+
+		ntime.tv_sec = ntime.tv_usec = 0;
+		answer = readmsg(TSP_ELECTION, ANYADDR, &ntime, ntp);
+		if (answer != 0) {
+			if (!good_host_name(answer->tsp_name)) {
+				suppress(&from, answer->tsp_name, ntp);
+				ntp->status = NOMASTER;
+			}
+			return;
+		}
+
+		if (Mflag)
+			ntp->status = MASTER;
+		else
+			ntp->status = NOMASTER;
+		return;
+	}
+
+	ntp->status = SLAVE;
+	(void)strcpy(mastername, answer->tsp_name);
+	masteraddr = from;
+
+	/*
+	 * If network has been partitioned, there might be other
+	 * masters; tell the one we have just acknowledged that
+	 * it has to gain control over the others.
+	 */
+	ntime.tv_sec = 0;
+	ntime.tv_usec = 300000;
+	answer = readmsg(TSP_MASTERACK, ANYADDR, &ntime, ntp);
+	/*
+	 * checking also not to send CONFLICT to ack'ed master
+	 * due to duplicated MASTERACKs
+	 */
+	if (answer != NULL &&
+	    strcmp(answer->tsp_name, mastername) != 0) {
+		conflict.tsp_type = TSP_CONFLICT;
+		(void)strcpy(conflict.tsp_name, hostname);
+		if (!acksend(&conflict, &masteraddr, mastername,
+			     TSP_ACK, 0, 0)) {
+			syslog(LOG_ERR,
+			       "error on sending TSP_CONFLICT");
+		}
+	}
+}
+
+/*
+ * based on the current network configuration, set the status, and count
+ * networks;
+ */
+void
+setstatus()
+{
+	struct netinfo *ntp;
+
+	status = 0;
+	nmasternets = nslavenets = nnets = nignorednets = 0;
+	if (trace)
+		fprintf(fd, "Net status:\n");
+	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+		switch ((int)ntp->status) {
+		case MASTER:
+			nmasternets++;
+			break;
+		case SLAVE:
+			nslavenets++;
+			break;
+		case NOMASTER:
+		case IGNORE:
+			nignorednets++;
+			break;
+		}
+		if (trace) {
+			fprintf(fd, "\t%-16s", inet_ntoa(ntp->net));
+			switch ((int)ntp->status) {
+			case NOMASTER:
+				fprintf(fd, "NOMASTER\n");
+				break;
+			case MASTER:
+				fprintf(fd, "MASTER\n");
+				break;
+			case SLAVE:
+				fprintf(fd, "SLAVE\n");
+				break;
+			case IGNORE:
+				fprintf(fd, "IGNORE\n");
+				break;
+			default:
+				fprintf(fd, "invalid state %d\n",
+					(int)ntp->status);
+				break;
+			}
+		}
+		nnets++;
+		status |= ntp->status;
+	}
+	status &= ~IGNORE;
+	if (trace)
+		fprintf(fd,
+			"\tnets=%d masters=%d slaves=%d ignored=%d delay2=%d\n",
+			nnets, nmasternets, nslavenets, nignorednets, delay2);
+}
+
+void
+makeslave(net)
+	struct netinfo *net;
+{
+	register struct netinfo *ntp;
+
+	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+		if (ntp->status == SLAVE && ntp != net)
+			ntp->status = IGNORE;
+	}
+	slavenet = net;
+}
+
+/*
+ * Try to become master over ignored nets..
+ */
+static void
+checkignorednets()
+{
+	register struct netinfo *ntp;
+
+	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+		if (!Mflag && ntp->status == SLAVE)
+			break;
+
+		if (ntp->status == IGNORE || ntp->status == NOMASTER) {
+			lookformaster(ntp);
+			if (!Mflag && ntp->status == SLAVE)
+				break;
+		}
+	}
+}
+
+/*
+ * choose a good network on which to be a slave
+ *	The ignored networks must have already been checked.
+ *	Take a hint about for a good network.
+ */
+static void
+pickslavenet(ntp)
+	struct netinfo *ntp;
+{
+	if (slavenet != 0 && slavenet->status == SLAVE) {
+		makeslave(slavenet);		/* prune extras */
+		return;
+	}
+
+	if (ntp == 0 || ntp->status != SLAVE) {
+		for (ntp = nettab; ntp != 0; ntp = ntp->next) {
+			if (ntp->status == SLAVE)
+				break;
+		}
+	}
+	makeslave(ntp);
+}
+
+/*
+ * returns a random number in the range [inf, sup]
+ */
+long
+casual(inf, sup)
+	long inf, sup;
+{
+	double value;
+
+	value = ((double)(random() & 0x7fffffff)) / (0x7fffffff*1.0);
+	return(inf + (sup - inf)*value);
+}
+
+char *
+date()
+{
+#ifdef sgi
+	struct	timeval tv;
+	static char tm[32];
+
+	(void)gettimeofday(&tv, (struct timezone *)0);
+	(void)cftime(tm, "%D %T", &tv.tv_sec);
+	return (tm);
+#else
+	struct	timeval tv;
+
+	(void)gettimeofday(&tv, (struct timezone *)0);
+	return (ctime(&tv.tv_sec));
+#endif /* sgi */
+}
+
+void
+addnetname(name)
+	char *name;
+{
+	register struct nets **netlist = &nets;
+
+	while (*netlist)
+		netlist = &((*netlist)->next);
+	*netlist = (struct nets *)malloc(sizeof **netlist);
+	if (*netlist == 0) {
+		fprintf(stderr,"malloc failed\n");
+		exit(1);
+	}
+	bzero((char *)*netlist, sizeof(**netlist));
+	(*netlist)->name = name;
+}
+
+/* note a host as trustworthy */
+static void
+add_good_host(name, perm)
+	char *name;
+	int perm;			/* 1=not part of the netgroup */
+{
+	register struct goodhost *ghp;
+	register struct hostent *hentp;
+
+	ghp = (struct goodhost*)malloc(sizeof(*ghp));
+	if (!ghp) {
+		syslog(LOG_ERR, "malloc failed");
+		exit(1);
+	}
+
+	bzero((char*)ghp, sizeof(*ghp));
+	(void)strncpy(&ghp->name[0], name, sizeof(ghp->name));
+	ghp->next = goodhosts;
+	ghp->perm = perm;
+	goodhosts = ghp;
+
+	hentp = gethostbyname(name);
+	if (0 == hentp && perm)
+		(void)fprintf(stderr, "unknown host %s\n", name);
+}
+
+
+/* update our image of the net-group of trustworthy hosts
+ */
+void
+get_goodgroup(force)
+	int force;
+{
+# define NG_DELAY (30*60*CLK_TCK)	/* 30 minutes */
+	static unsigned long last_update = -NG_DELAY;
+	unsigned long new_update;
+	struct hosttbl *htp;
+	struct goodhost *ghp, **ghpp;
+	char *mach, *usr, *dom;
+	struct tms tm;
+
+
+	/* if no netgroup, then we are finished */
+	if (goodgroup == 0 || !Mflag)
+		return;
+
+	/* Do not chatter with the netgroup master too often.
+	 */
+	new_update = times(&tm);
+	if (new_update < last_update + NG_DELAY
+	    && !force)
+		return;
+	last_update = new_update;
+
+	/* forget the old temporary entries */
+	ghpp = &goodhosts;
+	while (0 != (ghp = *ghpp)) {
+		if (!ghp->perm) {
+			*ghpp = ghp->next;
+			free((char*)ghp);
+		} else {
+			ghpp = &ghp->next;
+		}
+	}
+
+#ifdef HAVENIS
+	/* quit now if we are not one of the trusted masters
+	 */
+	if (!innetgr(goodgroup, &hostname[0], 0,0)) {
+		if (trace)
+			(void)fprintf(fd, "get_goodgroup: %s not in %s\n",
+				      &hostname[0], goodgroup);
+		return;
+	}
+	if (trace)
+		(void)fprintf(fd, "get_goodgroup: %s in %s\n",
+				  &hostname[0], goodgroup);
+
+	/* mark the entire netgroup as trusted */
+	(void)setnetgrent(goodgroup);
+	while (getnetgrent(&mach,&usr,&dom)) {
+		if (0 != mach)
+			add_good_host(mach,0);
+	}
+	(void)endnetgrent();
+
+	/* update list of slaves */
+	for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {
+		htp->good = good_host_name(&htp->name[0]);
+	}
+#endif /* HAVENIS */
+}
+
+
+/* see if a machine is trustworthy
+ */
+int					/* 1=trust hp to change our date */
+good_host_name(name)
+	char *name;
+{
+	register struct goodhost *ghp = goodhosts;
+	register char c;
+
+	if (!ghp || !Mflag)		/* trust everyone if no one named */
+		return 1;
+
+	c = *name;
+	do {
+		if (c == ghp->name[0]
+		    && !strcasecmp(name, ghp->name))
+			return 1;	/* found him, so say so */
+	} while (0 != (ghp = ghp->next));
+
+	if (!strcasecmp(name,hostname))	/* trust ourself */
+		return 1;
+
+	return 0;			/* did not find him */
+}
diff --git a/timed.tproj/timedc.tproj/Makefile b/timed.tproj/timedc.tproj/Makefile
new file mode 100644
index 0000000..ae13f3a
--- /dev/null
+++ b/timed.tproj/timedc.tproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = timedc
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = extern.h timedc.h
+
+CFILES = cmds.c cmdtab.c timedc.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
+            h.template
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD/$(NAME)
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/timed.tproj/timedc.tproj/Makefile.postamble b/timed.tproj/timedc.tproj/Makefile.postamble
new file mode 100644
index 0000000..7b861e1
--- /dev/null
+++ b/timed.tproj/timedc.tproj/Makefile.postamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
+VPATH += :../timed.tproj
diff --git a/timed.tproj/timedc.tproj/Makefile.preamble b/timed.tproj/timedc.tproj/Makefile.preamble
new file mode 100644
index 0000000..b5b8eac
--- /dev/null
+++ b/timed.tproj/timedc.tproj/Makefile.preamble
@@ -0,0 +1,130 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = byteorder.o measure.o cksum.o
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES =
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
diff --git a/timed.tproj/timedc.tproj/PB.project b/timed.tproj/timedc.tproj/PB.project
new file mode 100644
index 0000000..a4a35bf
--- /dev/null
+++ b/timed.tproj/timedc.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (extern.h, timedc.h); 
+        OTHER_LINKED = (cmds.c, cmdtab.c, timedc.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, m.template, h.template); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD/$(NAME)"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = timedc; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/timed.tproj/timedc.tproj/cmds.c b/timed.tproj/timedc.tproj/cmds.c
new file mode 100644
index 0000000..a844190
--- /dev/null
+++ b/timed.tproj/timedc.tproj/cmds.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cmds.c	8.2 (Berkeley) 3/26/95";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "timedc.h"
+#include <sys/file.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+
+#define TSPTYPES
+#include <protocols/timed.h>
+
+#ifdef sgi
+#include <bstring.h>
+#include <sys/clock.h>
+#else
+#define	SECHR	(60*60)
+#define	SECDAY	(24*SECHR)
+#endif /* sgi */
+
+# define DATE_PROTO "udp"
+# define DATE_PORT "time"
+
+
+int sock;
+int sock_raw;
+char myname[MAXHOSTNAMELEN];
+struct hostent *hp;
+struct sockaddr_in server;
+struct sockaddr_in dayaddr;
+extern int measure_delta;
+
+void bytenetorder(struct tsp *);
+void bytehostorder(struct tsp *);
+
+
+#define BU ((unsigned long)2208988800)	/* seconds before UNIX epoch */
+
+
+/* compute the difference between our date and another machine
+ */
+static int				/* difference in days from our time */
+daydiff(hostname)
+	char *hostname;
+{
+	int i;
+	int trials;
+	struct timeval tout, now;
+	fd_set ready;
+	struct sockaddr from;
+	int fromlen;
+	unsigned long sec;
+
+
+	/* wait 2 seconds between 10 tries */
+	tout.tv_sec = 2;
+	tout.tv_usec = 0;
+	for (trials = 0; trials < 10; trials++) {
+		/* ask for the time */
+		sec = 0;
+		if (sendto(sock, &sec, sizeof(sec), 0,
+			   (struct sockaddr*)&dayaddr, sizeof(dayaddr)) < 0) {
+			perror("sendto(sock)");
+			return 0;
+		}
+
+		for (;;) {
+			FD_ZERO(&ready);
+			FD_SET(sock, &ready);
+			i = select(sock+1, &ready, (fd_set *)0,
+				   (fd_set *)0, &tout);
+			if (i < 0) {
+				if (errno == EINTR)
+					continue;
+				perror("select(date read)");
+				return 0;
+			}
+			if (0 == i)
+				break;
+
+			fromlen = sizeof(from);
+			if (recvfrom(sock,&sec,sizeof(sec),0,
+				     &from,&fromlen) < 0) {
+				perror("recvfrom(date read)");
+				return 0;
+			}
+
+			sec = ntohl(sec);
+			if (sec < BU) {
+				fprintf(stderr,
+					"%s says it is before 1970: %lu",
+					hostname, sec);
+				return 0;
+			}
+			sec -= BU;
+
+			(void)gettimeofday(&now, (struct timezone*)0);
+			return (sec - now.tv_sec);
+		}
+	}
+
+	/* if we get here, we tried too many times */
+	fprintf(stderr,"%s will not tell us the date\n", hostname);
+	return 0;
+}
+
+
+/*
+ * Clockdiff computes the difference between the time of the machine on
+ * which it is called and the time of the machines given as argument.
+ * The time differences measured by clockdiff are obtained using a sequence
+ * of ICMP TSTAMP messages which are returned to the sender by the IP module
+ * in the remote machine.
+ * In order to compare clocks of machines in different time zones, the time
+ * is transmitted (as a 32-bit value) in milliseconds since midnight UT.
+ * If a hosts uses a different time format, it should set the high order
+ * bit of the 32-bit quantity it transmits.
+ * However, VMS apparently transmits the time in milliseconds since midnight
+ * local time (rather than GMT) without setting the high order bit.
+ * Furthermore, it does not understand daylight-saving time.  This makes
+ * clockdiff behaving inconsistently with hosts running VMS.
+ *
+ * In order to reduce the sensitivity to the variance of message transmission
+ * time, clockdiff sends a sequence of messages.  Yet, measures between
+ * two `distant' hosts can be affected by a small error. The error can,
+ * however, be reduced by increasing the number of messages sent in each
+ * measurement.
+ */
+void
+clockdiff(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int measure_status;
+	extern int measure(u_long, u_long, char *, struct sockaddr_in*, int);
+	register int avg_cnt;
+	register long avg;
+	struct servent *sp;
+
+	if (argc < 2)  {
+		printf("Usage: clockdiff host ... \n");
+		return;
+	}
+
+	(void)gethostname(myname,sizeof(myname));
+
+	/* get the address for the date ready */
+	sp = getservbyname(DATE_PORT, DATE_PROTO);
+	if (!sp) {
+		(void)fprintf(stderr, "%s/%s is an unknown service\n",
+			      DATE_PORT, DATE_PROTO);
+		dayaddr.sin_port = 0;
+	} else {
+		dayaddr.sin_port = sp->s_port;
+	}
+
+	while (argc > 1) {
+		argc--; argv++;
+		hp = gethostbyname(*argv);
+		if (hp == NULL) {
+			fprintf(stderr, "timedc: %s: ", *argv);
+			herror(0);
+			continue;
+		}
+
+		server.sin_family = hp->h_addrtype;
+		bcopy(hp->h_addr, &server.sin_addr.s_addr, hp->h_length);
+		for (avg_cnt = 0, avg = 0; avg_cnt < 16; avg_cnt++) {
+			measure_status = measure(10000,100, *argv, &server, 1);
+			if (measure_status != GOOD)
+				break;
+			avg += measure_delta;
+		}
+		if (measure_status == GOOD)
+			measure_delta = avg/avg_cnt;
+
+		switch (measure_status) {
+		case HOSTDOWN:
+			printf("%s is down\n", hp->h_name);
+			continue;
+		case NONSTDTIME:
+			printf("%s transmitts a non-standard time format\n",
+			       hp->h_name);
+			continue;
+		case UNREACHABLE:
+			printf("%s is unreachable\n", hp->h_name);
+			continue;
+		}
+
+		/*
+		 * Try to get the date only after using ICMP timestamps to
+		 * get the time.  This is because the date protocol
+		 * is optional.
+		 */
+		if (dayaddr.sin_port != 0) {
+			dayaddr.sin_family = hp->h_addrtype;
+			bcopy(hp->h_addr, &dayaddr.sin_addr.s_addr,
+			      hp->h_length);
+			avg = daydiff(*argv);
+			if (avg > SECDAY) {
+				printf("time on %s is %ld days ahead %s\n",
+				       hp->h_name, avg/SECDAY, myname);
+				continue;
+			} else if (avg < -SECDAY) {
+				printf("time on %s is %ld days behind %s\n",
+				       hp->h_name, -avg/SECDAY, myname);
+				continue;
+			}
+		}
+
+		if (measure_delta > 0) {
+			printf("time on %s is %d ms. ahead of time on %s\n",
+			       hp->h_name, measure_delta, myname);
+		} else if (measure_delta == 0) {
+			printf("%s and %s have the same time\n",
+			       hp->h_name, myname);
+		} else {
+			printf("time on %s is %d ms. behind time on %s\n",
+			       hp->h_name, -measure_delta, myname);
+		}
+	}
+	return;
+}
+
+
+/*
+ * finds location of master timedaemon
+ */
+void
+msite(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int cc;
+	fd_set ready;
+	struct sockaddr_in dest;
+	int i, length;
+	struct sockaddr from;
+	struct timeval tout;
+	struct tsp msg;
+	struct servent *srvp;
+	char *tgtname;
+
+	if (argc < 1) {
+		printf("Usage: msite [hostname]\n");
+		return;
+	}
+
+	srvp = getservbyname("timed", "udp");
+	if (srvp == 0) {
+		fprintf(stderr, "udp/timed: unknown service\n");
+		return;
+	}
+	dest.sin_port = srvp->s_port;
+	dest.sin_family = AF_INET;
+
+	(void)gethostname(myname, sizeof(myname));
+	i = 1;
+	do {
+		tgtname = (i >= argc) ? myname : argv[i];
+		hp = gethostbyname(tgtname);
+		if (hp == 0) {
+			fprintf(stderr, "timedc: %s: ", tgtname);
+			herror(0);
+			continue;
+		}
+		bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length);
+
+		(void)strcpy(msg.tsp_name, myname);
+		msg.tsp_type = TSP_MSITE;
+		msg.tsp_vers = TSPVERSION;
+		bytenetorder(&msg);
+		if (sendto(sock, &msg, sizeof(struct tsp), 0,
+			   (struct sockaddr*)&dest,
+			   sizeof(struct sockaddr)) < 0) {
+			perror("sendto");
+			continue;
+		}
+
+		tout.tv_sec = 15;
+		tout.tv_usec = 0;
+		FD_ZERO(&ready);
+		FD_SET(sock, &ready);
+		if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0,
+			   &tout)) {
+			length = sizeof(struct sockaddr);
+			cc = recvfrom(sock, &msg, sizeof(struct tsp), 0,
+				      &from, &length);
+			if (cc < 0) {
+				perror("recvfrom");
+				continue;
+			}
+			bytehostorder(&msg);
+			if (msg.tsp_type == TSP_ACK) {
+				printf("master timedaemon at %s is %s\n",
+				       tgtname, msg.tsp_name);
+			} else {
+				printf("received wrong ack: %s\n",
+				       tsptype[msg.tsp_type]);
+			}
+		} else {
+			printf("communication error with %s\n", tgtname);
+		}
+	} while (++i < argc);
+}
+
+/*
+ * quits timedc
+ */
+void
+quit()
+{
+	exit(0);
+}
+
+
+/*
+ * Causes the election timer to expire on the selected hosts
+ * It sends just one udp message per machine, relying on
+ * reliability of communication channel.
+ */
+void
+testing(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct servent *srvp;
+	struct sockaddr_in sin;
+	struct tsp msg;
+
+	if (argc < 2)  {
+		printf("Usage: election host1 [host2 ...]\n");
+		return;
+	}
+
+	srvp = getservbyname("timed", "udp");
+	if (srvp == 0) {
+		fprintf(stderr, "udp/timed: unknown service\n");
+		return;
+	}
+
+	while (argc > 1) {
+		argc--; argv++;
+		hp = gethostbyname(*argv);
+		if (hp == NULL) {
+			fprintf(stderr, "timedc: %s: ", *argv);
+			herror(0);
+			argc--; argv++;
+			continue;
+		}
+		sin.sin_port = srvp->s_port;
+		sin.sin_family = hp->h_addrtype;
+		bcopy(hp->h_addr, &sin.sin_addr.s_addr, hp->h_length);
+
+		msg.tsp_type = TSP_TEST;
+		msg.tsp_vers = TSPVERSION;
+		(void)gethostname(myname, sizeof(myname));
+		(void)strncpy(msg.tsp_name, myname, sizeof(msg.tsp_name));
+		bytenetorder(&msg);
+		if (sendto(sock, &msg, sizeof(struct tsp), 0,
+			   (struct sockaddr*)&sin,
+			   sizeof(struct sockaddr)) < 0) {
+			perror("sendto");
+		}
+	}
+}
+
+
+/*
+ * Enables or disables tracing on local timedaemon
+ */
+void
+tracing(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int onflag;
+	int length;
+	int cc;
+	fd_set ready;
+	struct sockaddr_in dest;
+	struct sockaddr from;
+	struct timeval tout;
+	struct tsp msg;
+	struct servent *srvp;
+
+	if (argc != 2) {
+		printf("Usage: tracing { on | off }\n");
+		return;
+	}
+
+	srvp = getservbyname("timed", "udp");
+	if (srvp == 0) {
+		fprintf(stderr, "udp/timed: unknown service\n");
+		return;
+	}
+	dest.sin_port = srvp->s_port;
+	dest.sin_family = AF_INET;
+
+	(void)gethostname(myname,sizeof(myname));
+	hp = gethostbyname(myname);
+	bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length);
+
+	if (strcmp(argv[1], "on") == 0) {
+		msg.tsp_type = TSP_TRACEON;
+		onflag = ON;
+	} else {
+		msg.tsp_type = TSP_TRACEOFF;
+		onflag = OFF;
+	}
+
+	(void)strcpy(msg.tsp_name, myname);
+	msg.tsp_vers = TSPVERSION;
+	bytenetorder(&msg);
+	if (sendto(sock, &msg, sizeof(struct tsp), 0,
+		   (struct sockaddr*)&dest, sizeof(struct sockaddr)) < 0) {
+		perror("sendto");
+		return;
+	}
+
+	tout.tv_sec = 5;
+	tout.tv_usec = 0;
+	FD_ZERO(&ready);
+	FD_SET(sock, &ready);
+	if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout)) {
+		length = sizeof(struct sockaddr);
+		cc = recvfrom(sock, &msg, sizeof(struct tsp), 0,
+			      &from, &length);
+		if (cc < 0) {
+			perror("recvfrom");
+			return;
+		}
+		bytehostorder(&msg);
+		if (msg.tsp_type == TSP_ACK)
+			if (onflag)
+				printf("timed tracing enabled\n");
+			else
+				printf("timed tracing disabled\n");
+		else
+			printf("wrong ack received: %s\n",
+						tsptype[msg.tsp_type]);
+	} else
+		printf("communication error\n");
+}
+
+int
+priv_resources()
+{
+	int port;
+	struct sockaddr_in sin;
+
+	sock = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sock < 0) {
+		perror("opening socket");
+		return(-1);
+	}
+
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = 0;
+	for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) {
+		sin.sin_port = htons((u_short)port);
+		if (bind(sock, (struct sockaddr*)&sin, sizeof (sin)) >= 0)
+			break;
+		if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
+			perror("bind");
+			(void) close(sock);
+			return(-1);
+		}
+	}
+	if (port == IPPORT_RESERVED / 2) {
+		fprintf(stderr, "all reserved ports in use\n");
+		(void) close(sock);
+		return(-1);
+	}
+
+	sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+	if (sock_raw < 0)  {
+		perror("opening raw socket");
+		(void) close(sock);
+		return(-1);
+	}
+	return(1);
+}
diff --git a/timed.tproj/timedc.tproj/cmdtab.c b/timed.tproj/timedc.tproj/cmdtab.c
new file mode 100644
index 0000000..546a206
--- /dev/null
+++ b/timed.tproj/timedc.tproj/cmdtab.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cmdtab.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include "timedc.h"
+
+char	clockdiffhelp[] =	"measures clock differences between machines";
+char	helphelp[] =		"gets help on commands";
+char	msitehelp[] =		"finds location of master";
+char	quithelp[] =		"exits timedc";
+char	testinghelp[] =		"causes election timers to expire";
+char	tracinghelp[] =		"turns tracing on or off";
+
+struct cmd cmdtab[] = {
+	{ "clockdiff",	clockdiffhelp,	clockdiff,	0 },
+	{ "election",	testinghelp,	testing,	1 },
+	{ "help",	helphelp,	help,		0 },
+	{ "msite",	msitehelp,	msite,		0 },
+	{ "quit",	quithelp,	quit,		0 },
+	{ "trace",	tracinghelp,	tracing,	1 },
+	{ "?",		helphelp,	help,		0 },
+};
+
+int	NCMDS = sizeof (cmdtab) / sizeof (cmdtab[0]);
diff --git a/timed.tproj/timedc.tproj/extern.h b/timed.tproj/timedc.tproj/extern.h
new file mode 100644
index 0000000..22e2e29
--- /dev/null
+++ b/timed.tproj/timedc.tproj/extern.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)extern.h	8.1 (Berkeley) 6/6/93
+ */
+
+#if __STDC__
+struct tsp;
+#endif
+
+extern struct cmd cmdtab[];
+
+void	bytehostorder __P((struct tsp *));
+void	bytenetorder __P((struct tsp *));
+void	clockdiff __P((int, char *[]));
+void	help __P((int, char *[]));
+void	intr __P((int));
+void	makeargv __P((void));
+void	msite __P((int, char *[]));
+int	priv_resources __P((void));
+void	quit __P((void));
+void	testing __P((int, char *[]));
+void	tracing __P((int, char *[]));
diff --git a/timed.tproj/timedc.tproj/h.template b/timed.tproj/timedc.tproj/h.template
new file mode 100644
index 0000000..f3c1b04
--- /dev/null
+++ b/timed.tproj/timedc.tproj/h.template
@@ -0,0 +1,11 @@
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+#import <Foundation/Foundation.h>
+
+@interface $FILENAMESANSEXTENSION$ : NSObject
+{
+
+}
+
+@end
diff --git a/timed.tproj/timedc.tproj/m.template b/timed.tproj/timedc.tproj/m.template
new file mode 100644
index 0000000..1216fe5
--- /dev/null
+++ b/timed.tproj/timedc.tproj/m.template
@@ -0,0 +1,18 @@
+$$ Lines starting with $$ are not inserted into newly created files
+$$ The following substitutions are made:
+$$
+$$ $FILENAME$                e.g. foo.m
+$$ $FILENAMESANSEXTENSION$   e.g. foo
+$$ $DIRECTORY$               e.g. /tmp/MyNewApp
+$$ $PROJECTNAME$             e.g. MyNewApp
+$$ $SUBPROJECTNAME$          e.g. TheGoodPart.subproj
+$$ $USERNAME$                e.g. mwagner
+$$ $DATE$                    e.g. Jan-1-1994
+$$
+/* $FILENAME$ created by $USERNAME$ on $DATE$ */
+
+#import "$FILENAMESANSEXTENSION$.h"
+
+@implementation $FILENAMESANSEXTENSION$
+
+@end
diff --git a/timed.tproj/timedc.tproj/timedc.c b/timed.tproj/timedc.tproj/timedc.c
new file mode 100644
index 0000000..63e2884
--- /dev/null
+++ b/timed.tproj/timedc.tproj/timedc.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1985, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)timedc.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.1.1.1 $"
+#endif
+
+#include "timedc.h"
+#include <strings.h>
+#include <signal.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <syslog.h>
+
+int trace = 0;
+FILE *fd = 0;
+int	margc;
+int	fromatty;
+char	*margv[20];
+char	cmdline[200];
+jmp_buf	toplevel;
+static struct cmd *getcmd __P((char *));
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register struct cmd *c;
+
+	openlog("timedc", LOG_ODELAY, LOG_AUTH);
+
+	/*
+	 * security dictates!
+	 */
+	if (priv_resources() < 0) {
+		fprintf(stderr, "Could not get privileged resources\n");
+		exit(1);
+	}
+	(void) setuid(getuid());
+
+	if (--argc > 0) {
+		c = getcmd(*++argv);
+		if (c == (struct cmd *)-1) {
+			printf("?Ambiguous command\n");
+			exit(1);
+		}
+		if (c == 0) {
+			printf("?Invalid command\n");
+			exit(1);
+		}
+		if (c->c_priv && getuid()) {
+			printf("?Privileged command\n");
+			exit(1);
+		}
+		(*c->c_handler)(argc, argv);
+		exit(0);
+	}
+
+	fromatty = isatty(fileno(stdin));
+	if (setjmp(toplevel))
+		putchar('\n');
+	(void) signal(SIGINT, intr);
+	for (;;) {
+		if (fromatty) {
+			printf("timedc> ");
+			(void) fflush(stdout);
+		}
+		if (fgets(cmdline, sizeof(cmdline), stdin) == 0)
+			quit();
+		if (cmdline[0] == 0)
+			break;
+		makeargv();
+		if (margv[0] == 0)
+			continue;
+		c = getcmd(margv[0]);
+		if (c == (struct cmd *)-1) {
+			printf("?Ambiguous command\n");
+			continue;
+		}
+		if (c == 0) {
+			printf("?Invalid command\n");
+			continue;
+		}
+		if (c->c_priv && getuid()) {
+			printf("?Privileged command\n");
+			continue;
+		}
+		(*c->c_handler)(margc, margv);
+	}
+	return 0;
+}
+
+void
+intr(signo)
+	int signo;
+{
+	if (!fromatty)
+		exit(0);
+	longjmp(toplevel, 1);
+}
+
+
+static struct cmd *
+getcmd(name)
+	char *name;
+{
+	register char *p, *q;
+	register struct cmd *c, *found;
+	register int nmatches, longest;
+	extern int NCMDS;
+
+	longest = 0;
+	nmatches = 0;
+	found = 0;
+	for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
+		p = c->c_name;
+		for (q = name; *q == *p++; q++)
+			if (*q == 0)		/* exact match? */
+				return(c);
+		if (!*q) {			/* the name was a prefix */
+			if (q - name > longest) {
+				longest = q - name;
+				nmatches = 1;
+				found = c;
+			} else if (q - name == longest)
+				nmatches++;
+		}
+	}
+	if (nmatches > 1)
+		return((struct cmd *)-1);
+	return(found);
+}
+
+/*
+ * Slice a string up into argc/argv.
+ */
+void
+makeargv()
+{
+	register char *cp;
+	register char **argp = margv;
+
+	margc = 0;
+	for (cp = cmdline; *cp;) {
+		while (isspace(*cp))
+			cp++;
+		if (*cp == '\0')
+			break;
+		*argp++ = cp;
+		margc += 1;
+		while (*cp != '\0' && !isspace(*cp))
+			cp++;
+		if (*cp == '\0')
+			break;
+		*cp++ = '\0';
+	}
+	*argp++ = 0;
+}
+
+#define HELPINDENT (sizeof ("directory"))
+
+/*
+ * Help command.
+ */
+void
+help(argc, argv)
+	int argc;
+	char *argv[];
+{
+	register struct cmd *c;
+
+	if (argc == 1) {
+		register int i, j, w;
+		int columns, width = 0, lines;
+		extern int NCMDS;
+
+		printf("Commands may be abbreviated.  Commands are:\n\n");
+		for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
+			int len = strlen(c->c_name);
+
+			if (len > width)
+				width = len;
+		}
+		width = (width + 8) &~ 7;
+		columns = 80 / width;
+		if (columns == 0)
+			columns = 1;
+		lines = (NCMDS + columns - 1) / columns;
+		for (i = 0; i < lines; i++) {
+			for (j = 0; j < columns; j++) {
+				c = cmdtab + j * lines + i;
+				printf("%s", c->c_name);
+				if (c + lines >= &cmdtab[NCMDS]) {
+					printf("\n");
+					break;
+				}
+				w = strlen(c->c_name);
+				while (w < width) {
+					w = (w + 8) &~ 7;
+					putchar('\t');
+				}
+			}
+		}
+		return;
+	}
+	while (--argc > 0) {
+		register char *arg;
+		arg = *++argv;
+		c = getcmd(arg);
+		if (c == (struct cmd *)-1)
+			printf("?Ambiguous help command %s\n", arg);
+		else if (c == (struct cmd *)0)
+			printf("?Invalid help command %s\n", arg);
+		else
+			printf("%-*s\t%s\n", (int)HELPINDENT,
+				c->c_name, c->c_help);
+	}
+}
diff --git a/timed.tproj/timedc.tproj/timedc.h b/timed.tproj/timedc.tproj/timedc.h
new file mode 100644
index 0000000..43ca72c
--- /dev/null
+++ b/timed.tproj/timedc.tproj/timedc.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)timedc.h	8.1 (Berkeley) 6/6/93
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#ifdef sgi
+#include <sys/uio.h>
+#endif
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+
+extern int errno;
+
+#define ON		1
+#define OFF		0
+
+#define GOOD		1
+#define UNREACHABLE	2
+#define NONSTDTIME	3
+#define HOSTDOWN 	0x7fffffff
+
+struct	cmd {
+	char	*c_name;		/* command name */
+	char	*c_help;		/* help message */
+	void	(*c_handler)();		/* routine to do the work */
+	int	c_priv;			/* privileged command */
+};
+
+#include "extern.h"
diff --git a/traceroute.tproj/Makefile b/traceroute.tproj/Makefile
new file mode 100644
index 0000000..75c293b
--- /dev/null
+++ b/traceroute.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = traceroute
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = traceroute.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble mean.awk\
+            median.awk README traceroute.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/traceroute.tproj/Makefile.postamble b/traceroute.tproj/Makefile.postamble
new file mode 100644
index 0000000..de54c24
--- /dev/null
+++ b/traceroute.tproj/Makefile.postamble
@@ -0,0 +1,110 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app)
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+
+
+# Change defaults assumed by the standard app makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if
+# you would like changes to them to invalidate previous builds.  The project
+# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build.
+#MAKEFILES = Makefile 
+
+# Optimization flag passed to compiler:
+#OPTIMIZATION_CFLAG = -O
+
+# Flags always passed to compiler:
+#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall  
+
+# Flags passed to compiler in normal 'app' compiles:
+#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG)
+
+# Flags passed to compiler in 'debug' compiles:
+#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG
+
+# Flags passed to compiler in 'profile' compiles
+#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Ownership and permissions of files installed by 'install' target
+INSTALL_AS_USER = root        # User to chown app to
+#INSTALL_AS_GROUP = wheel      # Group to chgrp app to 
+INSTALL_PERMISSIONS = 4555        # If set, 'install' chmod's executable to this
+
+# Options to strip for bundles, apps with bundles, and apps without bundles, 
+# respectively.
+#RELOCATABLE_STRIP_OPTS = -x -u
+#DYLD_APP_STRIP_OPTS = -A -n
+#APP_STRIP_OPTS = 
+#TOOL_STRIP_OPTS = 
+#LIBRARY_STRIP_OPTS = -x -S   # Note: -S strips debugging symbols
+# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but
+#  developers doing their own dynamic loading should set this to 
+#  $(DYLD_APP_STRIP_OPTS)).
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Typical 
+# user-defined rules are before_install and after_install (please don't 
+# redefine things like install or app, as they are owned by the top-level 
+# Makefile API), which are rules that get invoked before and after the install 
+# target runs.  Such rules should be specified with the '::' syntax rather than 
+# a single colon.
diff --git a/traceroute.tproj/Makefile.preamble b/traceroute.tproj/Makefile.preamble
new file mode 100644
index 0000000..2c9003c
--- /dev/null
+++ b/traceroute.tproj/Makefile.preamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags here.  To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+
+BUNDLELDFLAGS =            # use iff project is a bundle
+PALETTELDFLAGS =           # use iff project is a palette
+
+## Specify which headers in this project should be published to the outside 
+## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be 
+## prepended by DSTROOT, below.  Any subset of these public headers can be
+## precompiled automatically after installation, with extra user-defined flags.
+PUBLIC_HEADER_DIR = 
+PUBLIC_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+## Configure what is linked in at each level here.  Libraries are only used in
+## the final 'app' linking step.  Final 'app' linking is only done via the
+## 'app', 'debug', and 'profile' targets when they are invoked for
+## the top-level app.
+
+# Additional relocatables to be linked in at this level
+OTHER_OFILES = 
+# Additional libs to link apps against ('app' target)
+#OTHER_LIBS = 
+# Additional libs to link apps against ('debug' target)
+OTHER_DEBUG_LIBS = 
+# Additional libs to link apps against ('profile' target)
+OTHER_PROF_LIBS = 
+
+# More 'app' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# More 'debug' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_DEBUG_LIBS = 
+# More 'profile' libs when $(JAPANESE) = "YES"
+OTHER_JAPANESE_PROF_LIBS = 
+
+# If this is a bundle, and you *know* the enclosing application will not
+# be linking with a library which you require in your bundle code, then
+# mention it here so that it gets linked into the bundle.  Note that this
+# is wasteful but sometimes necessary.
+BUNDLE_LIBS = 
+
+## Configure how things get built here.  Additional dependencies, sourcefiles, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+# Precompiled headers to be built before any compilation occurs (e.g., draw.p)
+PRECOMPS = 
+
+# Targets to be built before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# Set the following to "YES" if you want the old behavior of recursively
+# cleaning all nested subprojects during 'make clean'.
+CLEAN_ALL_SUBPROJECTS =
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+# To include a version string, project source must exist in a directory named
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/traceroute.tproj/PB.project b/traceroute.tproj/PB.project
new file mode 100644
index 0000000..a843e7e
--- /dev/null
+++ b/traceroute.tproj/PB.project
@@ -0,0 +1,49 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (traceroute.c); 
+        OTHER_SOURCES = (
+            Makefile.preamble, 
+            Makefile, 
+            Makefile.postamble, 
+            mean.awk, 
+            median.awk, 
+            README, 
+            traceroute.8
+        ); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = traceroute; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/traceroute.tproj/README b/traceroute.tproj/README
new file mode 100644
index 0000000..6d33c6c
--- /dev/null
+++ b/traceroute.tproj/README
@@ -0,0 +1,126 @@
+Tue Dec 27 06:24:24 PST 1988
+
+Traceroute is a system administrators utility to trace the route
+ip packets from the current system take in getting to some
+destination system.  See the comments at the front of the
+program for a description of its use.
+
+This program 
+
+ a) can only be run by root (it uses raw ip sockets).
+
+ b) REQUIRES A KERNEL MOD to the raw ip output code to run.
+
+If you want to hack on your kernel, my modified version of the
+routine rip_output (in file /sys/netinet/raw_ip.c) is attached.
+This code may or may not resemble the code in your kernel.
+It may offer you a place to start but I make no promises.
+If you do hack your kernel, remember to test everything that uses
+raw ip sockets (e.g., ping and egpup/gated) & make sure they still
+work.  I wish you the best of luck and you're on your own.
+
+If your system has the ttl bug mentioned in the source, you
+might want to fix it while you're in the kernel.  (This bug
+appears in all releases of BSD up to but not including 4.3tahoe.
+If your version of netinet/ip_icmp.c is any earlier than 7.3
+(April, '87), it has the bug.)  The fix is just to add the line
+	ip->ip_ttl = MAXTTL;
+after the line
+	ip->ip_src = t;
+(or anywhere before the call to icmp_send) in routine icmp_reflect.
+
+If you're running this on a pre-4.3bsd system (e.g., Sun 3.x,
+Ultrix) that strips ip headers from icmp messages, add -DARCHAIC
+to CFLAGS in the Makefile.  Also note that rip_output contains
+a conditional for a 4.2/4.3 change in the location of a raw
+socket's protocol number.  I've checked this under 4.3 & Sun OS
+3.5 but you should double-check your system to make sure the
+appropriate branch of the #if is taken (check the line that
+assigned to ip->ip_p in your system's original rip_output).
+
+A couple of awk programs to massage the traceroute output are
+included.  "mean.awk" and "median.awk" compute the mean and median
+time to each hop, respectively.  I've found that something like
+
+	traceroute -q 7 foo.somewhere >t
+	awk -f median.awk t | graph
+
+can give you a quick picture of the bad spots on a long
+path (median is usually a better noise filter than mean).
+
+Enjoy.
+
+ - Van Jacobson (van@helios.ee.lbl.gov)
+
+-------------------- rip_output from /sys/netinet/raw_ip.c
+rip_output(m, so)
+	register struct mbuf *m;
+	struct socket *so;
+{
+	register struct ip *ip;
+	int error;
+	struct rawcb *rp = sotorawcb(so);
+	struct sockaddr_in *sin;
+#if BSD>=43
+	short proto = rp->rcb_proto.sp_protocol;
+#else
+	short proto = so->so_proto->pr_protocol;
+#endif
+	/*
+	 * if the protocol is IPPROTO_RAW, the user handed us a 
+	 * complete IP packet.  Otherwise, allocate an mbuf for a
+	 * header and fill it in as needed.
+	 */
+	if (proto != IPPROTO_RAW) {
+		/*
+		 * Calculate data length and get an mbuf
+		 * for IP header.
+		 */
+		int len = 0;
+		struct mbuf *m0;
+
+		for (m0 = m; m; m = m->m_next)
+			len += m->m_len;
+
+		m = m_get(M_DONTWAIT, MT_HEADER);
+		if (m == 0) {
+			m = m0;
+			error = ENOBUFS;
+			goto bad;
+		}
+		m->m_off = MMAXOFF - sizeof(struct ip);
+		m->m_len = sizeof(struct ip);
+		m->m_next = m0;
+
+		ip = mtod(m, struct ip *);
+		ip->ip_tos = 0;
+		ip->ip_off = 0;
+		ip->ip_p = proto;
+		ip->ip_len = sizeof(struct ip) + len;
+		ip->ip_ttl = MAXTTL;
+	} else
+		ip = mtod(m, struct ip *);
+
+	if (rp->rcb_flags & RAW_LADDR) {
+		sin = (struct sockaddr_in *)&rp->rcb_laddr;
+		if (sin->sin_family != AF_INET) {
+			error = EAFNOSUPPORT;
+			goto bad;
+		}
+		ip->ip_src.s_addr = sin->sin_addr.s_addr;
+	} else
+		ip->ip_src.s_addr = 0;
+
+	ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
+
+#if BSD>=43
+	return (ip_output(m, rp->rcb_options, &rp->rcb_route, 
+	   (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
+#else
+	return (ip_output(m, (struct mbuf *)0, &rp->rcb_route, 
+	   (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
+#endif
+bad:
+	m_freem(m);
+	return (error);
+}
diff --git a/traceroute.tproj/mean.awk b/traceroute.tproj/mean.awk
new file mode 100644
index 0000000..e97a56f
--- /dev/null
+++ b/traceroute.tproj/mean.awk
@@ -0,0 +1,50 @@
+#!/bin/awk -f
+#
+# Copyright (c) 1990, 1993
+#	The Regents of the University of California.  All rights reserved.
+#
+# This code is derived from software contributed to Berkeley by
+# Van Jacobson.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+#    must display the following acknowledgement:
+#	This product includes software developed by the University of
+#	California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+#    may be used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#	@(#)mean.awk	8.1 (Berkeley) 6/6/93
+#
+/^ *[0-9]/	{
+	# print out the average time to each hop along a route.
+	tottime = 0; n = 0;
+	for (f = 5; f <= NF; ++f) {
+		if ($f == "ms") {
+			tottime += $(f - 1)
+			++n
+		}
+	}
+	if (n > 0)
+		print $1, tottime/n, median
+}
diff --git a/traceroute.tproj/median.awk b/traceroute.tproj/median.awk
new file mode 100644
index 0000000..1a8d81d
--- /dev/null
+++ b/traceroute.tproj/median.awk
@@ -0,0 +1,67 @@
+#!/bin/awk -f
+#
+# Copyright (c) 1990, 1993
+#	The Regents of the University of California.  All rights reserved.
+#
+# This code is derived from software contributed to Berkeley by
+# Van Jacobson.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+#    must display the following acknowledgement:
+#	This product includes software developed by the University of
+#	California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+#    may be used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#	@(#)median.awk	8.1 (Berkeley) 6/6/93
+#
+/^ *[0-9]/	{
+	# print out the median time to each hop along a route.
+	tottime = 0; n = 0;
+	for (f = 5; f <= NF; ++f) {
+		if ($f == "ms") {
+			++n
+			time[n] = $(f - 1)
+		}
+	}
+	if (n > 0) {
+		# insertion sort the times to find the median
+		for (i = 2; i <= n; ++i) {
+			v = time[i]; j = i - 1;
+			while (time[j] > v) {
+				time[j+1] = time[j];
+				j = j - 1;
+				if (j < 0)
+					break;
+			}
+			time[j+1] = v;
+		}
+		if (n > 1 && (n % 2) == 0)
+			median = (time[n/2] + time[(n/2) + 1]) / 2
+		else
+			median = time[(n+1)/2]
+
+		print $1, median
+	}
+}
diff --git a/traceroute.tproj/traceroute.8 b/traceroute.tproj/traceroute.8
new file mode 100644
index 0000000..5a1ca4c
--- /dev/null
+++ b/traceroute.tproj/traceroute.8
@@ -0,0 +1,337 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Van Jacobson.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)traceroute.8	8.2 (Berkeley) 6/1/94
+.\"
+.Dd June 1, 1994
+.Dt TRACEROUTE 8
+.Os BSD 4.3
+.Sh NAME
+.Nm traceroute
+.Nd print the route packets take to network host
+.Sh SYNOPSIS
+.Nm traceroute
+.Op Fl m Ar max_ttl
+.Op Fl n
+.Op Fl p Ar port
+.Op Fl q Ar nqueries
+.Op Fl r
+.Bk -words
+.Op Fl s Ar src_addr
+.Ek
+.Op Fl t Ar tos
+.Op Fl w Ar waittime
+.Ar host
+.Op Ar packetsize
+.Sh DESCRIPTION
+The Internet is a large and complex aggregation of
+network hardware, connected together by gateways.
+Tracking the route one's packets follow (or finding the miscreant
+gateway that's discarding your packets) can be difficult.
+.Nm Traceroute
+utilizes the IP protocol `time to live' field and attempts to elicit an
+.Tn ICMP
+.Dv TIME_EXCEEDED
+response from each gateway along the path to some
+host.
+.Pp
+The only mandatory parameter is the destination host name or IP number.
+The default probe datagram length is 38 bytes, but this may be increased
+by specifying a packet size (in bytes) after the destination host
+name.
+.Pp
+Other options are:
+.Bl -tag -width Ds
+.It Fl m Ar max_ttl
+Set the max time-to-live (max number of hops) used in outgoing probe
+packets.  The default is 30 hops (the same default used for
+.Tn TCP
+connections).
+.It Fl n
+Print hop addresses numerically rather than symbolically and numerically
+(saves a nameserver address-to-name lookup for each gateway found on the
+path).
+.It Fl p Ar port
+Set the base
+.Tn UDP
+.Ar port
+number used in probes (default is 33434).
+.Nm Traceroute
+hopes that nothing is listening on
+.Tn UDP
+ports
+.Em base
+to
+.Em base+nhops-1
+at the destination host (so an
+.Tn ICMP
+.Dv PORT_UNREACHABLE
+message will
+be returned to terminate the route tracing).  If something is
+listening on a port in the default range, this option can be used
+to pick an unused port range.
+.It Fl q Ar nqueries
+Set the number of probes per ``ttl'' to
+.Ar nqueries
+(default is three probes).
+.It Fl r
+Bypass the normal routing tables and send directly to a host on an attached
+network.
+If the host is not on a directly-attached network,
+an error is returned.
+This option can be used to ping a local host through an interface
+that has no route through it (e.g., after the interface was dropped by
+.Xr routed 8 ) .
+.It Fl s Ar src_addr
+Use the following IP address
+(which must be given as an IP number, not
+a hostname) as the source address in outgoing probe packets.  On
+hosts with more than one IP address, this option can be used to
+force the source address to be something other than the IP address
+of the interface the probe packet is sent on.  If the IP address
+is not one of this machine's interface addresses, an error is
+returned and nothing is sent.
+.ne 1i
+.It Fl t Ar tos
+Set the
+.Em type-of-service
+in probe packets to the following value (default zero).  The value must be
+a decimal integer in the range 0 to 255.  This option can be used to
+see if different types-of-service result in different paths.  (If you
+are not running a
+.Bx 4.3 tahoe
+or later system, this may be academic since the normal network
+services like telnet and ftp don't let you control the
+.Dv TOS ) .
+Not all values of
+.Dv TOS
+are legal or
+meaningful \- see the IP spec for definitions.  Useful values are
+probably
+.Ql \-t 16
+(low delay) and
+.Ql \-t 8
+(high throughput).
+.It Fl v
+Verbose output.  Received
+.Tn ICMP
+packets other than
+.Dv TIME_EXCEEDED
+and
+.Dv UNREACHABLE Ns s
+are listed.
+.It Fl w
+Set the time (in seconds) to wait for a response to a probe (default 3
+sec.).
+.El
+.Pp
+This program attempts to trace the route an IP packet would follow to some
+internet host by launching
+.Tn UDP
+probe
+packets with a small ttl (time to live) then listening for an
+.Tn ICMP
+"time exceeded" reply from a gateway.  We start our probes
+with a ttl of one and increase by one until we get an
+.Tn ICMP
+"port unreachable"
+(which means we got to "host") or hit a max (which
+defaults to 30 hops & can be changed with the
+.Fl m
+flag).  Three
+probes (changed with
+.Fl q
+flag) are sent at each ttl setting and a
+line is printed showing the ttl, address of the gateway and
+round trip time of each probe.  If the probe answers come from
+different gateways, the address of each responding system will
+be printed.  If there is no response within a 3 sec. timeout
+interval (changed with the
+.Fl w
+flag), a "*" is printed for that
+probe.
+.Pp
+We don't want the destination
+host to process the
+.Tn UDP
+probe packets so the destination port is set to an
+unlikely value (if some clod on the destination is using that
+value, it can be changed with the
+.Fl p
+flag).
+.Pp
+A sample use and output might be:
+.Bd -literal
+[yak 71]% traceroute nis.nsf.net.
+traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
+1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
+2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
+3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
+4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
+5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
+6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
+7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
+8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
+9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
+10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
+11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
+
+.Ed
+Note that lines 2 & 3 are the same.  This is due to a buggy
+kernel on the 2nd hop system \- lbl-csam.arpa \- that forwards
+packets with a zero ttl (a bug in the distributed version
+of 4.3
+.Tn BSD ) .
+Note that you have to guess what path
+the packets are taking cross-country since the
+.Tn NSFNet
+(129.140)
+doesn't supply address-to-name translations for its
+.Tn NSS Ns es .
+.Pp
+A more interesting example is:
+.Bd -literal
+[yak 72]% traceroute allspice.lcs.mit.edu.
+traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
+1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
+2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
+3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
+4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
+5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
+6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
+7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
+8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
+9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
+10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
+11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
+12  * * *
+13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
+14  * * *
+15  * * *
+16  * * *
+17  * * *
+18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
+
+.Ed
+Note that the gateways 12, 14, 15, 16 & 17 hops away
+either don't send
+.Tn ICMP
+"time exceeded" messages or send them
+with a ttl too small to reach us.  14 \- 17 are running the
+.Tn MIT
+C Gateway code that doesn't send "time exceeded"s.  God
+only knows what's going on with 12.
+.Pp
+The silent gateway 12 in the above may be the result of a bug in
+the 4.[23]
+.Tn BSD
+network code (and its derivatives):  4.x (x <= 3)
+sends an unreachable message using whatever ttl remains in the
+original datagram.  Since, for gateways, the remaining ttl is
+zero, the
+.Tn ICMP
+"time exceeded" is guaranteed to not make it back
+to us.  The behavior of this bug is slightly more interesting
+when it appears on the destination system:
+.Bd -literal
+1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
+2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
+3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
+4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
+5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
+6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
+7  * * *
+8  * * *
+9  * * *
+10  * * *
+11  * * *
+12  * * *
+13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
+
+.Ed
+Notice that there are 12 "gateways" (13 is the final
+destination) and exactly the last half of them are "missing".
+What's really happening is that rip (a Sun-3 running Sun OS3.5)
+is using the ttl from our arriving datagram as the ttl in its
+.Tn ICMP
+reply.  So, the reply will time out on the return path
+(with no notice sent to anyone since
+.Tn ICMP's
+aren't sent for
+.Tn ICMP's )
+until we probe with a ttl that's at least twice the path
+length.  I.e., rip is really only 7 hops away.  A reply that
+returns with a ttl of 1 is a clue this problem exists.
+.Nm Traceroute
+prints a "!" after the time if the ttl is <= 1.
+Since vendors ship a lot of obsolete
+.Pf ( Tn DEC Ns \'s
+Ultrix, Sun 3.x) or
+non-standard
+.Pq Tn HPUX
+software, expect to see this problem
+frequently and/or take care picking the target host of your
+probes.
+Other possible annotations after the time are
+.Sy !H ,
+.Sy !N ,
+.Sy !P
+(got a host, network or protocol unreachable, respectively),
+.Sy !S
+or
+.Sy !F
+(source route failed or fragmentation needed \- neither of these should
+ever occur and the associated gateway is busted if you see one).  If
+almost all the probes result in some kind of unreachable,
+.Nm traceroute
+will give up and exit.
+.Pp
+This program is intended for use in network testing, measurement
+and management.
+It should be used primarily for manual fault isolation.
+Because of the load it could impose on the network, it is unwise to use
+.Nm traceroute
+during normal operations or from automated scripts.
+.Sh AUTHOR
+Implemented by Van Jacobson from a suggestion by Steve Deering.  Debugged
+by a cast of thousands with particularly cogent suggestions or fixes from
+C. Philip Wood, Tim Seaver and Ken Adelman.
+.Sh SEE ALSO
+.Xr netstat 1 ,
+.Xr ping 8
+.Sh HISTORY
+The
+.Nm
+command
+.Bt
diff --git a/traceroute.tproj/traceroute.c b/traceroute.tproj/traceroute.c
new file mode 100644
index 0000000..1f8a5fa
--- /dev/null
+++ b/traceroute.tproj/traceroute.c
@@ -0,0 +1,858 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)traceroute.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * traceroute host  - trace the route ip packets follow going to "host".
+ *
+ * Attempt to trace the route an ip packet would follow to some
+ * internet host.  We find out intermediate hops by launching probe
+ * packets with a small ttl (time to live) then listening for an
+ * icmp "time exceeded" reply from a gateway.  We start our probes
+ * with a ttl of one and increase by one until we get an icmp "port
+ * unreachable" (which means we got to "host") or hit a max (which
+ * defaults to 30 hops & can be changed with the -m flag).  Three
+ * probes (change with -q flag) are sent at each ttl setting and a
+ * line is printed showing the ttl, address of the gateway and
+ * round trip time of each probe.  If the probe answers come from
+ * different gateways, the address of each responding system will
+ * be printed.  If there is no response within a 5 sec. timeout
+ * interval (changed with the -w flag), a "*" is printed for that
+ * probe.
+ *
+ * Probe packets are UDP format.  We don't want the destination
+ * host to process them so the destination port is set to an
+ * unlikely value (if some clod on the destination is using that
+ * value, it can be changed with the -p flag).
+ *
+ * A sample use might be:
+ *
+ *     [yak 71]% traceroute nis.nsf.net.
+ *     traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
+ *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
+ *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
+ *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
+ *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
+ *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
+ *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
+ *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
+ *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
+ *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
+ *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
+ *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
+ *
+ * Note that lines 2 & 3 are the same.  This is due to a buggy
+ * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
+ * packets with a zero ttl.
+ *
+ * A more interesting example is:
+ *
+ *     [yak 72]% traceroute allspice.lcs.mit.edu.
+ *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
+ *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
+ *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
+ *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
+ *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
+ *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
+ *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
+ *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
+ *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
+ *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
+ *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
+ *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
+ *     12  * * *
+ *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
+ *     14  * * *
+ *     15  * * *
+ *     16  * * *
+ *     17  * * *
+ *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
+ *
+ * (I start to see why I'm having so much trouble with mail to
+ * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
+ * either don't send ICMP "time exceeded" messages or send them
+ * with a ttl too small to reach us.  14 - 17 are running the
+ * MIT C Gateway code that doesn't send "time exceeded"s.  God
+ * only knows what's going on with 12.
+ *
+ * The silent gateway 12 in the above may be the result of a bug in
+ * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
+ * sends an unreachable message using whatever ttl remains in the
+ * original datagram.  Since, for gateways, the remaining ttl is
+ * zero, the icmp "time exceeded" is guaranteed to not make it back
+ * to us.  The behavior of this bug is slightly more interesting
+ * when it appears on the destination system:
+ *
+ *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
+ *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
+ *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
+ *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
+ *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
+ *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
+ *      7  * * *
+ *      8  * * *
+ *      9  * * *
+ *     10  * * *
+ *     11  * * *
+ *     12  * * *
+ *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
+ *
+ * Notice that there are 12 "gateways" (13 is the final
+ * destination) and exactly the last half of them are "missing".
+ * What's really happening is that rip (a Sun-3 running Sun OS3.5)
+ * is using the ttl from our arriving datagram as the ttl in its
+ * icmp reply.  So, the reply will time out on the return path
+ * (with no notice sent to anyone since icmp's aren't sent for
+ * icmp's) until we probe with a ttl that's at least twice the path
+ * length.  I.e., rip is really only 7 hops away.  A reply that
+ * returns with a ttl of 1 is a clue this problem exists.
+ * Traceroute prints a "!" after the time if the ttl is <= 1.
+ * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
+ * non-standard (HPUX) software, expect to see this problem
+ * frequently and/or take care picking the target host of your
+ * probes.
+ *
+ * Other possible annotations after the time are !H, !N, !P (got a host,
+ * network or protocol unreachable, respectively), !S or !F (source
+ * route failed or fragmentation needed -- neither of these should
+ * ever occur and the associated gateway is busted if you see one).  If
+ * almost all the probes result in some kind of unreachable, traceroute
+ * will give up and exit.
+ *
+ * Notes
+ * -----
+ * This program must be run by root or be setuid.  (I suggest that
+ * you *don't* make it setuid -- casual use could result in a lot
+ * of unnecessary traffic on our poor, congested nets.)
+ *
+ * This program requires a kernel mod that does not appear in any
+ * system available from Berkeley:  A raw ip socket using proto
+ * IPPROTO_RAW must interpret the data sent as an ip datagram (as
+ * opposed to data to be wrapped in a ip datagram).  See the README
+ * file that came with the source to this program for a description
+ * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
+ * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
+ * MODIFIED TO RUN THIS PROGRAM.
+ *
+ * The udp port usage may appear bizarre (well, ok, it is bizarre).
+ * The problem is that an icmp message only contains 8 bytes of
+ * data from the original datagram.  8 bytes is the size of a udp
+ * header so, if we want to associate replies with the original
+ * datagram, the necessary information must be encoded into the
+ * udp header (the ip id could be used but there's no way to
+ * interlock with the kernel's assignment of ip id's and, anyway,
+ * it would have taken a lot more kernel hacking to allow this
+ * code to set the ip id).  So, to allow two or more users to
+ * use traceroute simultaneously, we use this task's pid as the
+ * source port (the high bit is set to move the port number out
+ * of the "likely" range).  To keep track of which probe is being
+ * replied to (so times and/or hop counts don't get confused by a
+ * reply that was delayed in transit), we increment the destination
+ * port number before each probe.
+ *
+ * Don't use this as a coding example.  I was trying to find a
+ * routing problem and this code sort-of popped out after 48 hours
+ * without sleep.  I was amazed it ever compiled, much less ran.
+ *
+ * I stole the idea for this program from Steve Deering.  Since
+ * the first release, I've learned that had I attended the right
+ * IETF working group meetings, I also could have stolen it from Guy
+ * Almes or Matt Mathis.  I don't know (or care) who came up with
+ * the idea first.  I envy the originators' perspicacity and I'm
+ * glad they didn't keep the idea a secret.
+ *
+ * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
+ * enhancements to the original distribution.
+ *
+ * I've hacked up a round-trip-route version of this that works by
+ * sending a loose-source-routed udp datagram through the destination
+ * back to yourself.  Unfortunately, SO many gateways botch source
+ * routing, the thing is almost worthless.  Maybe one day...
+ *
+ *  -- Van Jacobson (van@helios.ee.lbl.gov)
+ *     Tue Dec 20 03:50:13 PST 1988
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+
+#include <arpa/inet.h>
+
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define	MAXPACKET	65535	/* max ip packet size */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN	64
+#endif
+
+#ifndef FD_SET
+#define NFDBITS         (8*sizeof(fd_set))
+#define FD_SETSIZE      NFDBITS
+#define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
+#endif
+
+#define Fprintf (void)fprintf
+#define Sprintf (void)sprintf
+#define Printf (void)printf
+
+/*
+ * format of a (udp) probe packet.
+ */
+struct opacket {
+	struct ip ip;
+	struct udphdr udp;
+	u_char seq;		/* sequence number of this packet */
+	u_char ttl;		/* ttl packet left with */
+	struct timeval tv;	/* time packet left */
+};
+
+u_char	packet[512];		/* last inbound (icmp) packet */
+struct opacket	*outpacket;	/* last output (udp) packet */
+
+int wait_for_reply __P((int, struct sockaddr_in *));
+void send_probe __P((int, int));
+double deltaT __P((struct timeval *, struct timeval *));
+int packet_ok __P((u_char *, int, struct sockaddr_in *, int));
+void print __P((u_char *, int, struct sockaddr_in *));
+void tvsub __P((struct timeval *, struct timeval *));
+char *inetname __P((struct in_addr));
+void usage __P(());
+
+int s;				/* receive (icmp) socket file descriptor */
+int sndsock;			/* send (udp) socket file descriptor */
+struct timezone tz;		/* leftover */
+
+struct sockaddr whereto;	/* Who to try to reach */
+int datalen;			/* How much data */
+
+char *source = 0;
+char *hostname;
+
+int nprobes = 3;
+int max_ttl = 30;
+u_short ident;
+u_short port = 32768+666;	/* start udp dest port # for probe packets */
+int options;			/* socket options */
+int verbose;
+int waittime = 5;		/* time to wait for response (in seconds) */
+int nflag;			/* print addresses numerically */
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	extern char *optarg;
+	extern int optind;
+	struct hostent *hp;
+	struct protoent *pe;
+	struct sockaddr_in from, *to;
+	int ch, i, on, probe, seq, tos, ttl;
+
+	on = 1;
+	seq = tos = 0;
+	to = (struct sockaddr_in *)&whereto;
+	while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF)
+		switch(ch) {
+		case 'd':
+			options |= SO_DEBUG;
+			break;
+		case 'm':
+			max_ttl = atoi(optarg);
+			if (max_ttl <= 1) {
+				Fprintf(stderr,
+				    "traceroute: max ttl must be >1.\n");
+				exit(1);
+			}
+			break;
+		case 'n':
+			nflag++;
+			break;
+		case 'p':
+			port = atoi(optarg);
+			if (port < 1) {
+				Fprintf(stderr,
+				    "traceroute: port must be >0.\n");
+				exit(1);
+			}
+			break;
+		case 'q':
+			nprobes = atoi(optarg);
+			if (nprobes < 1) {
+				Fprintf(stderr,
+				    "traceroute: nprobes must be >0.\n");
+				exit(1);
+			}
+			break;
+		case 'r':
+			options |= SO_DONTROUTE;
+			break;
+		case 's':
+			/*
+			 * set the ip source address of the outbound
+			 * probe (e.g., on a multi-homed host).
+			 */
+			source = optarg;
+			break;
+		case 't':
+			tos = atoi(optarg);
+			if (tos < 0 || tos > 255) {
+				Fprintf(stderr,
+				    "traceroute: tos must be 0 to 255.\n");
+				exit(1);
+			}
+			break;
+		case 'v':
+			verbose++;
+			break;
+		case 'w':
+			waittime = atoi(optarg);
+			if (waittime <= 1) {
+				Fprintf(stderr,
+				    "traceroute: wait must be >1 sec.\n");
+				exit(1);
+			}
+			break;
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc < 1)
+		usage();
+
+	setlinebuf (stdout);
+
+	(void) bzero((char *)&whereto, sizeof(struct sockaddr));
+	to->sin_family = AF_INET;
+	to->sin_addr.s_addr = inet_addr(*argv);
+	if (to->sin_addr.s_addr != -1)
+		hostname = *argv;
+	else {
+		hp = gethostbyname(*argv);
+		if (hp) {
+			to->sin_family = hp->h_addrtype;
+			bcopy(hp->h_addr, (caddr_t)&to->sin_addr, hp->h_length);
+			hostname = hp->h_name;
+		} else {
+			(void)fprintf(stderr,
+			    "traceroute: unknown host %s\n", *argv);
+			exit(1);
+		}
+	}
+	if (*++argv)
+		datalen = atoi(*argv);
+	if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket)) {
+		Fprintf(stderr,
+		    "traceroute: packet size must be 0 <= s < %ld.\n",
+		    MAXPACKET - sizeof(struct opacket));
+		exit(1);
+	}
+	datalen += sizeof(struct opacket);
+	outpacket = (struct opacket *)malloc((unsigned)datalen);
+	if (! outpacket) {
+		perror("traceroute: malloc");
+		exit(1);
+	}
+	(void) bzero((char *)outpacket, datalen);
+	outpacket->ip.ip_dst = to->sin_addr;
+	outpacket->ip.ip_tos = tos;
+	outpacket->ip.ip_v = IPVERSION;
+	outpacket->ip.ip_id = 0;
+
+	ident = (getpid() & 0xffff) | 0x8000;
+
+	if ((pe = getprotobyname("icmp")) == NULL) {
+		Fprintf(stderr, "icmp: unknown protocol\n");
+		exit(10);
+	}
+	if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0) {
+		perror("traceroute: icmp socket");
+		exit(5);
+	}
+	if (options & SO_DEBUG)
+		(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
+				  (char *)&on, sizeof(on));
+	if (options & SO_DONTROUTE)
+		(void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,
+				  (char *)&on, sizeof(on));
+
+	if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
+		perror("traceroute: raw socket");
+		exit(5);
+	}
+#ifdef SO_SNDBUF
+	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
+		       sizeof(datalen)) < 0) {
+		perror("traceroute: SO_SNDBUF");
+		exit(6);
+	}
+#endif SO_SNDBUF
+#ifdef IP_HDRINCL
+	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
+		       sizeof(on)) < 0) {
+		perror("traceroute: IP_HDRINCL");
+		exit(6);
+	}
+#endif IP_HDRINCL
+	if (options & SO_DEBUG)
+		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
+				  (char *)&on, sizeof(on));
+	if (options & SO_DONTROUTE)
+		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
+				  (char *)&on, sizeof(on));
+
+	if (source) {
+		(void) bzero((char *)&from, sizeof(struct sockaddr));
+		from.sin_family = AF_INET;
+		from.sin_addr.s_addr = inet_addr(source);
+		if (from.sin_addr.s_addr == -1) {
+			Printf("traceroute: unknown host %s\n", source);
+			exit(1);
+		}
+		outpacket->ip.ip_src = from.sin_addr;
+#ifndef IP_HDRINCL
+		if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0) {
+			perror ("traceroute: bind:");
+			exit (1);
+		}
+#endif IP_HDRINCL
+	}
+
+	Fprintf(stderr, "traceroute to %s (%s)", hostname,
+		inet_ntoa(to->sin_addr));
+	if (source)
+		Fprintf(stderr, " from %s", source);
+	Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);
+	(void) fflush(stderr);
+
+	for (ttl = 1; ttl <= max_ttl; ++ttl) {
+		u_long lastaddr = 0;
+		int got_there = 0;
+		int unreachable = 0;
+
+		Printf("%2d ", ttl);
+		for (probe = 0; probe < nprobes; ++probe) {
+			int cc;
+			struct timeval t1, t2;
+			struct timezone tz;
+			struct ip *ip;
+
+			(void) gettimeofday(&t1, &tz);
+			send_probe(++seq, ttl);
+			while (cc = wait_for_reply(s, &from)) {
+				(void) gettimeofday(&t2, &tz);
+				if ((i = packet_ok(packet, cc, &from, seq))) {
+					if (from.sin_addr.s_addr != lastaddr) {
+						print(packet, cc, &from);
+						lastaddr = from.sin_addr.s_addr;
+					}
+					Printf("  %g ms", deltaT(&t1, &t2));
+					switch(i - 1) {
+					case ICMP_UNREACH_PORT:
+#ifndef ARCHAIC
+						ip = (struct ip *)packet;
+						if (ip->ip_ttl <= 1)
+							Printf(" !");
+#endif ARCHAIC
+						++got_there;
+						break;
+					case ICMP_UNREACH_NET:
+						++unreachable;
+						Printf(" !N");
+						break;
+					case ICMP_UNREACH_HOST:
+						++unreachable;
+						Printf(" !H");
+						break;
+					case ICMP_UNREACH_PROTOCOL:
+						++got_there;
+						Printf(" !P");
+						break;
+					case ICMP_UNREACH_NEEDFRAG:
+						++unreachable;
+						Printf(" !F");
+						break;
+					case ICMP_UNREACH_SRCFAIL:
+						++unreachable;
+						Printf(" !S");
+						break;
+					}
+					break;
+				}
+			}
+			if (cc == 0)
+				Printf(" *");
+			(void) fflush(stdout);
+		}
+		putchar('\n');
+		if (got_there || unreachable >= nprobes-1)
+			exit(0);
+	}
+}
+
+int
+wait_for_reply(sock, from)
+	int sock;
+	struct sockaddr_in *from;
+{
+	fd_set fds;
+	struct timeval wait;
+	int cc = 0;
+	int fromlen = sizeof (*from);
+
+	FD_ZERO(&fds);
+	FD_SET(sock, &fds);
+	wait.tv_sec = waittime; wait.tv_usec = 0;
+
+	if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0)
+		cc=recvfrom(s, (char *)packet, sizeof(packet), 0,
+			    (struct sockaddr *)from, &fromlen);
+
+	return(cc);
+}
+
+
+void
+send_probe(seq, ttl)
+	int seq, ttl;
+{
+	struct opacket *op = outpacket;
+	struct ip *ip = &op->ip;
+	struct udphdr *up = &op->udp;
+	int i;
+
+	ip->ip_off = 0;
+	ip->ip_hl = sizeof(*ip) >> 2;
+	ip->ip_p = IPPROTO_UDP;
+	ip->ip_len = datalen;
+	ip->ip_ttl = ttl;
+	ip->ip_v = IPVERSION;
+	ip->ip_id = htons(ident+seq);
+
+	up->uh_sport = htons(ident);
+	up->uh_dport = htons(port+seq);
+	up->uh_ulen = htons((u_short)(datalen - sizeof(struct ip)));
+	up->uh_sum = 0;
+
+	op->seq = seq;
+	op->ttl = ttl;
+	(void) gettimeofday(&op->tv, &tz);
+
+	i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto,
+		   sizeof(struct sockaddr));
+	if (i < 0 || i != datalen)  {
+		if (i<0)
+			perror("sendto");
+		Printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
+			datalen, i);
+		(void) fflush(stdout);
+	}
+}
+
+
+double
+deltaT(t1p, t2p)
+	struct timeval *t1p, *t2p;
+{
+	register double dt;
+
+	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
+	     (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
+	return (dt);
+}
+
+
+/*
+ * Convert an ICMP "type" field to a printable string.
+ */
+char *
+pr_type(t)
+	u_char t;
+{
+	static char *ttab[] = {
+	"Echo Reply",	"ICMP 1",	"ICMP 2",	"Dest Unreachable",
+	"Source Quench", "Redirect",	"ICMP 6",	"ICMP 7",
+	"Echo",		"ICMP 9",	"ICMP 10",	"Time Exceeded",
+	"Param Problem", "Timestamp",	"Timestamp Reply", "Info Request",
+	"Info Reply"
+	};
+
+	if(t > 16)
+		return("OUT-OF-RANGE");
+
+	return(ttab[t]);
+}
+
+
+int
+packet_ok(buf, cc, from, seq)
+	u_char *buf;
+	int cc;
+	struct sockaddr_in *from;
+	int seq;
+{
+	register struct icmp *icp;
+	u_char type, code;
+	int hlen;
+#ifndef ARCHAIC
+	struct ip *ip;
+
+	ip = (struct ip *) buf;
+	hlen = ip->ip_hl << 2;
+	if (cc < hlen + ICMP_MINLEN) {
+		if (verbose)
+			Printf("packet too short (%d bytes) from %s\n", cc,
+				inet_ntoa(from->sin_addr));
+		return (0);
+	}
+	cc -= hlen;
+	icp = (struct icmp *)(buf + hlen);
+#else
+	icp = (struct icmp *)buf;
+#endif ARCHAIC
+	type = icp->icmp_type; code = icp->icmp_code;
+	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
+	    type == ICMP_UNREACH) {
+		struct ip *hip;
+		struct udphdr *up;
+
+		hip = &icp->icmp_ip;
+		hlen = hip->ip_hl << 2;
+		up = (struct udphdr *)((u_char *)hip + hlen);
+		if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP &&
+		    up->uh_sport == htons(ident) &&
+		    up->uh_dport == htons(port+seq))
+			return (type == ICMP_TIMXCEED? -1 : code+1);
+	}
+#ifndef ARCHAIC
+	if (verbose) {
+		int i;
+		u_long *lp = (u_long *)&icp->icmp_ip;
+
+		Printf("\n%d bytes from %s to %s", cc,
+			inet_ntoa(from->sin_addr), inet_ntoa(ip->ip_dst));
+		Printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
+		       icp->icmp_code);
+		for (i = 4; i < cc ; i += sizeof(long))
+			Printf("%2d: x%8.8lx\n", i, *lp++);
+	}
+#endif ARCHAIC
+	return(0);
+}
+
+
+void
+print(buf, cc, from)
+	u_char *buf;
+	int cc;
+	struct sockaddr_in *from;
+{
+	struct ip *ip;
+	int hlen;
+
+	ip = (struct ip *) buf;
+	hlen = ip->ip_hl << 2;
+	cc -= hlen;
+
+	if (nflag)
+		Printf(" %s", inet_ntoa(from->sin_addr));
+	else
+		Printf(" %s (%s)", inetname(from->sin_addr),
+		       inet_ntoa(from->sin_addr));
+
+	if (verbose)
+		Printf (" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
+}
+
+
+#ifdef notyet
+/*
+ * Checksum routine for Internet Protocol family headers (C Version)
+ */
+u_short
+in_cksum(addr, len)
+	u_short *addr;
+	int len;
+{
+	register int nleft = len;
+	register u_short *w = addr;
+	register u_short answer;
+	register int sum = 0;
+
+	/*
+	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
+	 *  we add sequential 16 bit words to it, and at the end, fold
+	 *  back all the carry bits from the top 16 bits into the lower
+	 *  16 bits.
+	 */
+	while (nleft > 1)  {
+		sum += *w++;
+		nleft -= 2;
+	}
+
+	/* mop up an odd byte, if necessary */
+	if (nleft == 1)
+		sum += *(u_char *)w;
+
+	/*
+	 * add back carry outs from top 16 bits to low 16 bits
+	 */
+	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
+	sum += (sum >> 16);			/* add carry */
+	answer = ~sum;				/* truncate to 16 bits */
+	return (answer);
+}
+#endif notyet
+
+/*
+ * Subtract 2 timeval structs:  out = out - in.
+ * Out is assumed to be >= in.
+ */
+void
+tvsub(out, in)
+	register struct timeval *out, *in;
+{
+	if ((out->tv_usec -= in->tv_usec) < 0)   {
+		out->tv_sec--;
+		out->tv_usec += 1000000;
+	}
+	out->tv_sec -= in->tv_sec;
+}
+
+
+/*
+ * Construct an Internet address representation.
+ * If the nflag has been supplied, give
+ * numeric value, otherwise try for symbolic name.
+ */
+char *
+inetname(in)
+	struct in_addr in;
+{
+	register char *cp;
+	static char line[50];
+	struct hostent *hp;
+	static char domain[MAXHOSTNAMELEN + 1];
+	static int first = 1;
+
+	if (first && !nflag) {
+		first = 0;
+		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
+		    (cp = index(domain, '.')))
+			(void) strcpy(domain, cp + 1);
+		else
+			domain[0] = 0;
+	}
+	cp = 0;
+	if (!nflag && in.s_addr != INADDR_ANY) {
+		hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
+		if (hp) {
+			if ((cp = index(hp->h_name, '.')) &&
+			    !strcmp(cp + 1, domain))
+				*cp = 0;
+			cp = hp->h_name;
+		}
+	}
+	if (cp)
+		(void) strcpy(line, cp);
+	else {
+		in.s_addr = ntohl(in.s_addr);
+#define C(x)	((x) & 0xff)
+		Sprintf(line, "%lu.%lu.%lu.%lu", C(in.s_addr >> 24),
+			C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
+	}
+	return (line);
+}
+
+void
+usage()
+{
+	(void)fprintf(stderr,
+"usage: traceroute [-dnrv] [-m max_ttl] [-p port#] [-q nqueries]\n\t\
+[-s src_addr] [-t tos] [-w wait] host [data size]\n");
+	exit(1);
+}
diff --git a/trpt.tproj/Makefile b/trpt.tproj/Makefile
new file mode 100644
index 0000000..3a0f3a7
--- /dev/null
+++ b/trpt.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = trpt
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = trpt.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble trpt.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/trpt.tproj/Makefile.postamble b/trpt.tproj/Makefile.postamble
new file mode 100644
index 0000000..a38e0df
--- /dev/null
+++ b/trpt.tproj/Makefile.postamble
@@ -0,0 +1,110 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app)
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+
+
+# Change defaults assumed by the standard app makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if
+# you would like changes to them to invalidate previous builds.  The project
+# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build.
+#MAKEFILES = Makefile 
+
+# Optimization flag passed to compiler:
+#OPTIMIZATION_CFLAG = -O
+
+# Flags always passed to compiler:
+#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall  
+
+# Flags passed to compiler in normal 'app' compiles:
+#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG)
+
+# Flags passed to compiler in 'debug' compiles:
+#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG
+
+# Flags passed to compiler in 'profile' compiles
+#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User to chown app to
+INSTALL_AS_GROUP = kmem      # Group to chgrp app to 
+INSTALL_PERMISSIONS = 2555        # If set, 'install' chmod's executable to this
+
+# Options to strip for bundles, apps with bundles, and apps without bundles, 
+# respectively.
+#RELOCATABLE_STRIP_OPTS = -x -u
+#DYLD_APP_STRIP_OPTS = -A -n
+#APP_STRIP_OPTS = 
+#TOOL_STRIP_OPTS = 
+#LIBRARY_STRIP_OPTS = -x -S   # Note: -S strips debugging symbols
+# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but
+#  developers doing their own dynamic loading should set this to 
+#  $(DYLD_APP_STRIP_OPTS)).
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Typical 
+# user-defined rules are before_install and after_install (please don't 
+# redefine things like install or app, as they are owned by the top-level 
+# Makefile API), which are rules that get invoked before and after the install 
+# target runs.  Such rules should be specified with the '::' syntax rather than 
+# a single colon.
diff --git a/trpt.tproj/Makefile.preamble b/trpt.tproj/Makefile.preamble
new file mode 100644
index 0000000..2c9003c
--- /dev/null
+++ b/trpt.tproj/Makefile.preamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags here.  To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+
+BUNDLELDFLAGS =            # use iff project is a bundle
+PALETTELDFLAGS =           # use iff project is a palette
+
+## Specify which headers in this project should be published to the outside 
+## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be 
+## prepended by DSTROOT, below.  Any subset of these public headers can be
+## precompiled automatically after installation, with extra user-defined flags.
+PUBLIC_HEADER_DIR = 
+PUBLIC_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+## Configure what is linked in at each level here.  Libraries are only used in
+## the final 'app' linking step.  Final 'app' linking is only done via the
+## 'app', 'debug', and 'profile' targets when they are invoked for
+## the top-level app.
+
+# Additional relocatables to be linked in at this level
+OTHER_OFILES = 
+# Additional libs to link apps against ('app' target)
+#OTHER_LIBS = 
+# Additional libs to link apps against ('debug' target)
+OTHER_DEBUG_LIBS = 
+# Additional libs to link apps against ('profile' target)
+OTHER_PROF_LIBS = 
+
+# More 'app' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# More 'debug' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_DEBUG_LIBS = 
+# More 'profile' libs when $(JAPANESE) = "YES"
+OTHER_JAPANESE_PROF_LIBS = 
+
+# If this is a bundle, and you *know* the enclosing application will not
+# be linking with a library which you require in your bundle code, then
+# mention it here so that it gets linked into the bundle.  Note that this
+# is wasteful but sometimes necessary.
+BUNDLE_LIBS = 
+
+## Configure how things get built here.  Additional dependencies, sourcefiles, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+# Precompiled headers to be built before any compilation occurs (e.g., draw.p)
+PRECOMPS = 
+
+# Targets to be built before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# Set the following to "YES" if you want the old behavior of recursively
+# cleaning all nested subprojects during 'make clean'.
+CLEAN_ALL_SUBPROJECTS =
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+# To include a version string, project source must exist in a directory named
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/trpt.tproj/PB.project b/trpt.tproj/PB.project
new file mode 100644
index 0000000..e382ae0
--- /dev/null
+++ b/trpt.tproj/PB.project
@@ -0,0 +1,41 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (trpt.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, trpt.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = trpt; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/trpt.tproj/trpt.8 b/trpt.tproj/trpt.8
new file mode 100644
index 0000000..8cc6c2a
--- /dev/null
+++ b/trpt.tproj/trpt.8
@@ -0,0 +1,151 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)trpt.8	8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt TRPT 8
+.Os BSD 4.2
+.Sh NAME
+.Nm trpt
+.Nd transliterate protocol trace
+.Sh SYNOPSIS
+.Nm trpt
+.Op Fl a
+.Op Fl f
+.Op Fl j
+.Op Fl p Ar hex-address
+.Op Fl s
+.Op Fl t
+.Oo
+.Ar system Op Ar core
+.Oc
+.Sh DESCRIPTION
+.Nm Trpt
+interrogates the buffer of
+.Tn TCP
+trace records created
+when a socket is marked for
+.Dq debugging
+(see
+.Xr setsockopt 2 ) ,
+and prints a readable description of these records.
+When no options are supplied, 
+.Nm trpt
+prints all the trace records found in the system
+grouped according to
+.Tn TCP
+connection protocol control
+block
+.Pq Tn PCB .
+The following options may be used to
+alter this behavior.
+.Bl -tag -width Ds
+.It Fl a
+In addition to the normal output,
+print the values of the source and destination
+addresses for each packet recorded.
+.It Fl f
+Follow the trace as it occurs, waiting a short time for additional records
+each time the end of the log is reached.
+.It Fl j
+Just give a list of the protocol control block
+addresses for which there are trace records.
+.It Fl p
+Show only trace records associated with the protocol
+control block at the given address
+.Ar hex-address .
+.It Fl s
+In addition to the normal output,
+print a detailed description of the packet
+sequencing information.
+.It Fl t
+in addition to the normal output,
+print the values for all timers at each
+point in the trace.
+.El
+.Pp
+The recommended use of
+.Nm trpt
+is as follows.
+Isolate the problem and enable debugging on the
+socket(s) involved in the connection.
+Find the address of the protocol control blocks
+associated with the sockets using the 
+.Fl A
+option to 
+.Xr netstat 1 .
+Then run
+.Nm trpt
+with the
+.Fl p
+option, supplying the associated
+protocol control block addresses.
+The
+.Fl f
+option can be used to follow the trace log once the trace is located.
+If there are
+many sockets using the debugging option, the
+.Fl j
+option may be useful in checking to see if
+any trace records are present for the socket in
+question.
+.Pp
+If debugging is being performed on a system or
+core file other than the default, the last two
+arguments may be used to supplant the defaults.
+.Sh FILES
+.Bl -tag -width /dev/kmem -compact
+.It Pa /vmunix
+.It Pa /dev/kmem
+.El
+.Sh SEE ALSO
+.Xr netstat 1 ,
+.Xr setsockopt 2 ,
+.Xr trsp 8
+.Sh DIAGNOSTICS
+.Bl -tag -width Ds
+.It Sy no namelist
+When the system image doesn't
+contain the proper symbols to find the trace buffer;
+others which should be self explanatory.
+.El
+.Sh BUGS
+Should also print the data for each input or output,
+but this is not saved in the race record.
+.Pp
+The output format is inscrutable and should be described
+here.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/trpt.tproj/trpt.c b/trpt.tproj/trpt.c
new file mode 100644
index 0000000..63ad900
--- /dev/null
+++ b/trpt.tproj/trpt.c
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1988, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)trpt.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#if BSD >= 199103
+#define NEWVM
+#endif
+#ifndef NEWVM
+#include <machine/pte.h>
+#include <sys/vmmac.h>
+#endif
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#define PRUREQUESTS
+#include <sys/protosw.h>
+#include <sys/file.h>
+
+#include <net/route.h>
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#define TCPSTATES
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#define	TCPTIMERS
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#define	TANAMES
+#include <netinet/tcp_debug.h>
+
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <nlist.h>
+#include <paths.h>
+
+struct	tcp_debug tcp_debug[TCP_NDEBUG];
+int	tcp_debx;
+
+struct nlist nl[] = {
+#define	N_TCP_DEBUG	0
+	{ "_tcp_debug" },
+#define	N_TCP_DEBX	1
+	{ "_tcp_debx" },
+#ifndef NEWVM
+#define	N_SYSMAP	2
+	{ "_Sysmap" },
+#define	N_SYSSIZE	3
+	{ "_Syssize" },
+#endif
+	{ "" },
+};
+
+#ifndef NEWVM
+static struct pte *Sysmap;
+#endif
+static caddr_t tcp_pcbs[TCP_NDEBUG];
+static n_time ntime;
+static int aflag, kflag, memf, follow, sflag, tflag;
+
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	extern char *optarg;
+	extern int optind;
+	int ch, i, jflag, npcbs, numeric();
+	char *system, *core, *malloc();
+	off_t lseek();
+
+	jflag = npcbs = 0;
+	while ((ch = getopt(argc, argv, "afjp:st")) != EOF)
+		switch (ch) {
+		case 'a':
+			++aflag;
+			break;
+		case 'f':
+			++follow;
+			setlinebuf(stdout);
+			break;
+		case 'j':
+			++jflag;
+			break;
+		case 'p':
+			if (npcbs >= TCP_NDEBUG) {
+				fputs("trpt: too many pcb's specified\n",
+				    stderr);
+				exit(1);
+			}
+			(void)sscanf(optarg, "%x", (int *)&tcp_pcbs[npcbs++]);
+			break;
+		case 's':
+			++sflag;
+			break;
+		case 't':
+			++tflag;
+			break;
+		case '?':
+		default:
+			(void)fprintf(stderr,
+"usage: trpt [-afjst] [-p hex-address] [system [core]]\n");
+			exit(1);
+		}
+	argc -= optind;
+	argv += optind;
+
+	core = _PATH_KMEM;
+	if (argc > 0) {
+		system = *argv;
+		argc--, argv++;
+		if (argc > 0) {
+			core = *argv;
+			argc--, argv++;
+			++kflag;
+		}
+		/*
+		 * Discard setgid privileges if not the running kernel so that
+		 * bad guys can't print interesting stuff from kernel memory.
+		 */
+		setgid(getgid());
+	}
+	else
+		system = _PATH_UNIX;
+
+	if (nlist(system, nl) < 0 || !nl[0].n_value) {
+		fprintf(stderr, "trpt: %s: no namelist\n", system);
+		exit(1);
+	}
+	if ((memf = open(core, O_RDONLY)) < 0) {
+		perror(core);
+		exit(2);
+	}
+	if (kflag) {
+#ifdef NEWVM
+		fputs("trpt: can't do core files yet\n", stderr);
+		exit(1);
+#else
+		off_t off;
+
+		Sysmap = (struct pte *)
+		   malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
+		if (!Sysmap) {
+			fputs("trpt: can't get memory for Sysmap.\n", stderr);
+			exit(1);
+		}
+		off = nl[N_SYSMAP].n_value & ~KERNBASE;
+		(void)lseek(memf, off, L_SET);
+		(void)read(memf, (char *)Sysmap,
+		    (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
+#endif
+	}
+	(void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET);
+	if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) !=
+	    sizeof(tcp_debx)) {
+		perror("trpt: tcp_debx");
+		exit(3);
+	}
+	(void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
+	if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) !=
+	    sizeof(tcp_debug)) {
+		perror("trpt: tcp_debug");
+		exit(3);
+	}
+	/*
+	 * If no control blocks have been specified, figure
+	 * out how many distinct one we have and summarize
+	 * them in tcp_pcbs for sorting the trace records
+	 * below.
+	 */
+	if (!npcbs) {
+		for (i = 0; i < TCP_NDEBUG; i++) {
+			register struct tcp_debug *td = &tcp_debug[i];
+			register int j;
+
+			if (td->td_tcb == 0)
+				continue;
+			for (j = 0; j < npcbs; j++)
+				if (tcp_pcbs[j] == td->td_tcb)
+					break;
+			if (j >= npcbs)
+				tcp_pcbs[npcbs++] = td->td_tcb;
+		}
+		if (!npcbs)
+			exit(0);
+	}
+	qsort(tcp_pcbs, npcbs, sizeof(caddr_t), numeric);
+	if (jflag) {
+		for (i = 0;;) {
+			printf("%x", (int)tcp_pcbs[i]);
+			if (++i == npcbs)
+				break;
+			fputs(", ", stdout);
+		}
+		putchar('\n');
+	}
+	else for (i = 0; i < npcbs; i++) {
+		printf("\n%x:\n", (int)tcp_pcbs[i]);
+		dotrace(tcp_pcbs[i]);
+	}
+	exit(0);
+}
+
+dotrace(tcpcb)
+	register caddr_t tcpcb;
+{
+	register struct tcp_debug *td;
+	register int i;
+	int prev_debx = tcp_debx;
+
+again:	if (--tcp_debx < 0)
+		tcp_debx = TCP_NDEBUG - 1;
+	for (i = prev_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) {
+		td = &tcp_debug[i];
+		if (tcpcb && td->td_tcb != tcpcb)
+			continue;
+		ntime = ntohl(td->td_time);
+		tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
+		    &td->td_th, td->td_req);
+		if (i == tcp_debx)
+			goto done;
+	}
+	for (i = 0; i <= tcp_debx % TCP_NDEBUG; i++) {
+		td = &tcp_debug[i];
+		if (tcpcb && td->td_tcb != tcpcb)
+			continue;
+		ntime = ntohl(td->td_time);
+		tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
+		    &td->td_th, td->td_req);
+	}
+done:	if (follow) {
+		prev_debx = tcp_debx + 1;
+		if (prev_debx >= TCP_NDEBUG)
+			prev_debx = 0;
+		do {
+			sleep(1);
+			(void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET);
+			if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) !=
+			    sizeof(tcp_debx)) {
+				perror("trpt: tcp_debx");
+				exit(3);
+			}
+		} while (tcp_debx == prev_debx);
+		(void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
+		if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) !=
+		    sizeof(tcp_debug)) {
+			perror("trpt: tcp_debug");
+			exit(3);
+		}
+		goto again;
+	}
+}
+
+/*
+ * Tcp debug routines
+ */
+/*ARGSUSED*/
+tcp_trace(act, ostate, atp, tp, ti, req)
+	short act, ostate;
+	struct tcpcb *atp, *tp;
+	struct tcpiphdr *ti;
+	int req;
+{
+	tcp_seq seq, ack;
+	int flags, len, win, timer;
+
+	printf("%03ld %s:%s ",(ntime/10) % 1000, tcpstates[ostate],
+	    tanames[act]);
+	switch (act) {
+	case TA_INPUT:
+	case TA_OUTPUT:
+	case TA_DROP:
+		if (aflag) {
+			printf("(src=%s,%u, ",
+			    inet_ntoa(ti->ti_src), ntohs(ti->ti_sport));
+			printf("dst=%s,%u)",
+			    inet_ntoa(ti->ti_dst), ntohs(ti->ti_dport));
+		}
+		seq = ti->ti_seq;
+		ack = ti->ti_ack;
+		len = ti->ti_len;
+		win = ti->ti_win;
+		if (act == TA_OUTPUT) {
+			seq = ntohl(seq);
+			ack = ntohl(ack);
+			len = ntohs(len);
+			win = ntohs(win);
+		}
+		if (act == TA_OUTPUT)
+			len -= sizeof(struct tcphdr);
+		if (len)
+			printf("[%lx..%lx)", seq, seq + len);
+		else
+			printf("%lx", seq);
+		printf("@%lx", ack);
+		if (win)
+			printf("(win=%x)", win);
+		flags = ti->ti_flags;
+		if (flags) {
+			register char *cp = "<";
+#define	pf(flag, string) { \
+	if (ti->ti_flags&flag) { \
+		(void)printf("%s%s", cp, string); \
+		cp = ","; \
+	} \
+}
+			pf(TH_SYN, "SYN");
+			pf(TH_ACK, "ACK");
+			pf(TH_FIN, "FIN");
+			pf(TH_RST, "RST");
+			pf(TH_PUSH, "PUSH");
+			pf(TH_URG, "URG");
+			printf(">");
+		}
+		break;
+	case TA_USER:
+		timer = req >> 8;
+		req &= 0xff;
+		printf("%s", prurequests[req]);
+		if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO)
+			printf("<%s>", tcptimers[timer]);
+		break;
+	}
+	printf(" -> %s", tcpstates[tp->t_state]);
+	/* print out internal state of tp !?! */
+	printf("\n");
+	if (sflag) {
+		printf("\trcv_nxt %lx rcv_wnd %x snd_una %lx snd_nxt %lx snd_max %lx\n",
+		    tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt,
+		    tp->snd_max);
+		printf("\tsnd_wl1 %lx snd_wl2 %lx snd_wnd %x\n", tp->snd_wl1,
+		    tp->snd_wl2, tp->snd_wnd);
+	}
+	/* print out timers? */
+	if (tflag) {
+		register char *cp = "\t";
+		register int i;
+
+		for (i = 0; i < TCPT_NTIMERS; i++) {
+			if (tp->t_timer[i] == 0)
+				continue;
+			printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]);
+			if (i == TCPT_REXMT)
+				printf(" (t_rxtshft=%d)", tp->t_rxtshift);
+			cp = ", ";
+		}
+		if (*cp != '\t')
+			putchar('\n');
+	}
+}
+
+numeric(c1, c2)
+	caddr_t *c1, *c2;
+{
+	return(*c1 - *c2);
+}
+
+klseek(fd, base, off)
+	int fd, off;
+	off_t base;
+{
+	off_t lseek();
+
+#ifndef NEWVM
+	if (kflag) {	/* get kernel pte */
+		base &= ~KERNBASE;
+		base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
+	}
+#endif
+	(void)lseek(fd, base, off);
+}
diff --git a/trsp.tproj/Makefile b/trsp.tproj/Makefile
new file mode 100644
index 0000000..4291787
--- /dev/null
+++ b/trsp.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = trsp
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = trsp.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble trsp.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/trsp.tproj/Makefile.postamble b/trsp.tproj/Makefile.postamble
new file mode 100644
index 0000000..a38e0df
--- /dev/null
+++ b/trsp.tproj/Makefile.postamble
@@ -0,0 +1,110 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app)
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+
+
+# Change defaults assumed by the standard app makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if
+# you would like changes to them to invalidate previous builds.  The project
+# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build.
+#MAKEFILES = Makefile 
+
+# Optimization flag passed to compiler:
+#OPTIMIZATION_CFLAG = -O
+
+# Flags always passed to compiler:
+#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall  
+
+# Flags passed to compiler in normal 'app' compiles:
+#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG)
+
+# Flags passed to compiler in 'debug' compiles:
+#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG
+
+# Flags passed to compiler in 'profile' compiles
+#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User to chown app to
+INSTALL_AS_GROUP = kmem      # Group to chgrp app to 
+INSTALL_PERMISSIONS = 2555        # If set, 'install' chmod's executable to this
+
+# Options to strip for bundles, apps with bundles, and apps without bundles, 
+# respectively.
+#RELOCATABLE_STRIP_OPTS = -x -u
+#DYLD_APP_STRIP_OPTS = -A -n
+#APP_STRIP_OPTS = 
+#TOOL_STRIP_OPTS = 
+#LIBRARY_STRIP_OPTS = -x -S   # Note: -S strips debugging symbols
+# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but
+#  developers doing their own dynamic loading should set this to 
+#  $(DYLD_APP_STRIP_OPTS)).
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Typical 
+# user-defined rules are before_install and after_install (please don't 
+# redefine things like install or app, as they are owned by the top-level 
+# Makefile API), which are rules that get invoked before and after the install 
+# target runs.  Such rules should be specified with the '::' syntax rather than 
+# a single colon.
diff --git a/trsp.tproj/Makefile.preamble b/trsp.tproj/Makefile.preamble
new file mode 100644
index 0000000..2c9003c
--- /dev/null
+++ b/trsp.tproj/Makefile.preamble
@@ -0,0 +1,113 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags here.  To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+
+BUNDLELDFLAGS =            # use iff project is a bundle
+PALETTELDFLAGS =           # use iff project is a palette
+
+## Specify which headers in this project should be published to the outside 
+## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be 
+## prepended by DSTROOT, below.  Any subset of these public headers can be
+## precompiled automatically after installation, with extra user-defined flags.
+PUBLIC_HEADER_DIR = 
+PUBLIC_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+## Configure what is linked in at each level here.  Libraries are only used in
+## the final 'app' linking step.  Final 'app' linking is only done via the
+## 'app', 'debug', and 'profile' targets when they are invoked for
+## the top-level app.
+
+# Additional relocatables to be linked in at this level
+OTHER_OFILES = 
+# Additional libs to link apps against ('app' target)
+#OTHER_LIBS = 
+# Additional libs to link apps against ('debug' target)
+OTHER_DEBUG_LIBS = 
+# Additional libs to link apps against ('profile' target)
+OTHER_PROF_LIBS = 
+
+# More 'app' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_LIBS = 
+# More 'debug' libraries when $(JAPANESE) = "YES"
+OTHER_JAPANESE_DEBUG_LIBS = 
+# More 'profile' libs when $(JAPANESE) = "YES"
+OTHER_JAPANESE_PROF_LIBS = 
+
+# If this is a bundle, and you *know* the enclosing application will not
+# be linking with a library which you require in your bundle code, then
+# mention it here so that it gets linked into the bundle.  Note that this
+# is wasteful but sometimes necessary.
+BUNDLE_LIBS = 
+
+## Configure how things get built here.  Additional dependencies, sourcefiles, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+# Precompiled headers to be built before any compilation occurs (e.g., draw.p)
+PRECOMPS = 
+
+# Targets to be built before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# Set the following to "YES" if you want the old behavior of recursively
+# cleaning all nested subprojects during 'make clean'.
+CLEAN_ALL_SUBPROJECTS =
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+# To include a version string, project source must exist in a directory named
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/trsp.tproj/PB.project b/trsp.tproj/PB.project
new file mode 100644
index 0000000..26e29e4
--- /dev/null
+++ b/trsp.tproj/PB.project
@@ -0,0 +1,41 @@
+{
+    DOCICONFILES = (); 
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (trsp.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, trsp.8); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = trsp; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/trsp.tproj/trsp.8 b/trsp.tproj/trsp.8
new file mode 100644
index 0000000..19c23b4
--- /dev/null
+++ b/trsp.tproj/trsp.8
@@ -0,0 +1,141 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)trsp.8	8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt TRSP 8
+.Os BSD 4.2
+.Sh NAME
+.Nm trsp
+.Nd transliterate sequenced packet protocol trace
+.Sh SYNOPSIS
+.Nm trsp
+.Op Fl a
+.Op Fl s
+.Op Fl t
+.Op Fl j
+.Op Fl p Ar hex-address
+.Oo
+.Ar system Op Ar core
+.Oc
+.Sh DESCRIPTION
+.Xr Trpt
+interrogates the buffer of
+.Tn SPP
+trace records created
+when a socket is marked for
+.Dq debugging
+(see
+.Xr setsockopt 2 ) ,
+and prints a readable description of these records.
+When no options are supplied, 
+.Nm trsp
+prints all the trace records found in the system
+grouped according to
+.Tn SPP
+connection protocol control
+block
+.Pq Tn PCB .
+The following options may be used to
+alter this behavior.
+.Bl -tag -width Ds
+.It Fl a
+In addition to the normal output,
+print the values of the source and destination
+addresses for each packet recorded.
+.It Fl j
+Just give a list of the protocol control block
+addresses for which there are trace records.
+.It Fl p
+Show only trace records associated with the protocol
+control block at the given address,
+.Ar hex-address .
+.It Fl s
+in addition to the normal output,
+print a detailed description of the packet
+sequencing information.
+.It Fl t
+in addition to the normal output,
+print the values for all timers at each
+point in the trace,
+.El
+.Pp
+The recommended use of
+.Nm trsp
+is as follows.
+Isolate the problem and enable debugging on the
+socket(s) involved in the connection.
+Find the address of the protocol control blocks
+associated with the sockets using the 
+.Fl A
+option to 
+.Xr netstat 1 .
+Then run
+.Nm trsp
+with the
+.Fl p
+option, supplying the associated
+protocol control block addresses.  If there are
+many sockets using the debugging option, the
+.Fl j
+option may be useful in checking to see if
+any trace records are present for the socket in
+question.
+.Pp
+If debugging is being performed on a system or
+core file other than the default, the last two
+arguments may be used to supplant the defaults.
+.Sh FILES
+.Bl -tag -width /dev/kmem -compact
+.It Pa /vmunix
+.It Pa /dev/kmem
+.El
+.Sh SEE ALSO
+.Xr netstat 1 ,
+.Xr setsockopt 2
+.Sh DIAGNOSTICS
+.Bl -tag -width Ds
+.It Sy no namelist
+When the system image doesn't
+contain the proper symbols to find the trace buffer;
+others which should be self explanatory.
+.Sh BUGS
+Should also print the data for each input or output,
+but this is not saved in the race record.
+.Pp
+The output format is inscrutable and should be described
+here.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 .
diff --git a/trsp.tproj/trsp.c b/trsp.tproj/trsp.c
new file mode 100644
index 0000000..6895ff9
--- /dev/null
+++ b/trsp.tproj/trsp.c
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1985, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)trsp.c	8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#define PRUREQUESTS
+#include <sys/protosw.h>
+
+#include <net/route.h>
+#include <net/if.h>
+
+#define TCPSTATES
+#include <netinet/tcp_fsm.h>
+#define	TCPTIMERS
+#include <netinet/tcp_timer.h>
+
+#include <netns/ns.h>
+#include <netns/sp.h>
+#include <netns/idp.h>
+#include <netns/spidp.h>
+#include <netns/spp_timer.h>
+#include <netns/spp_var.h>
+#include <netns/ns_pcb.h>
+#include <netns/idp_var.h>
+#define SANAMES
+#include <netns/spp_debug.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <nlist.h>
+#include <paths.h>
+
+unsigned long	ntime;
+int	sflag;
+int	tflag;
+int	jflag;
+int	aflag;
+int	zflag;
+int	numeric();
+struct	nlist nl[] = {
+	{ "_spp_debug" },
+	{ "_spp_debx" },
+	0
+};
+struct	spp_debug spp_debug[SPP_NDEBUG];
+caddr_t	spp_pcbs[SPP_NDEBUG];
+int	spp_debx;
+
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	int i, mask = 0, npcbs = 0;
+	char *system, *core;
+
+	system = _PATH_UNIX;
+	core = _PATH_KMEM;
+
+	argc--, argv++;
+again:
+	if (argc > 0 && !strcmp(*argv, "-a")) {
+		aflag++, argc--, argv++;
+		goto again;
+	}
+	if (argc > 0 && !strcmp(*argv, "-z")) {
+		zflag++, argc--, argv++;
+		goto again;
+	}
+	if (argc > 0 && !strcmp(*argv, "-s")) {
+		sflag++, argc--, argv++;
+		goto again;
+	}
+	if (argc > 0 && !strcmp(*argv, "-t")) {
+		tflag++, argc--, argv++;
+		goto again;
+	}
+	if (argc > 0 && !strcmp(*argv, "-j")) {
+		jflag++, argc--, argv++;
+		goto again;
+	}
+	if (argc > 0 && !strcmp(*argv, "-p")) {
+		argc--, argv++;
+		if (argc < 1) {
+			fprintf(stderr, "-p: missing sppcb address\n");
+			exit(1);
+		}
+		if (npcbs >= SPP_NDEBUG) {
+			fprintf(stderr, "-p: too many pcb's specified\n");
+			exit(1);
+		}
+		sscanf(*argv, "%x", &spp_pcbs[npcbs++]);
+		argc--, argv++;
+		goto again;
+	}
+	if (argc > 0) {
+		system = *argv;
+		argc--, argv++;
+		mask++;
+		/*
+		 * Discard setgid privileges if not the running kernel so that
+		 * bad guys can't print interesting stuff from kernel memory.
+		 */
+		setgid(getgid());
+	}
+	if (argc > 0) {
+		core = *argv;
+		argc--, argv++;
+		mask++;
+		setgid(getgid());
+	}
+	(void) nlist(system, nl);
+	if (nl[0].n_value == 0) {
+		fprintf(stderr, "trsp: %s: no namelist\n", system);
+		exit(1);
+	}
+	(void) close(0);
+	if (open(core, 0) < 0) {
+		fprintf(stderr, "trsp: "); perror(core);
+		exit(2);
+	}
+	if (mask) {
+		nl[0].n_value &= 0x7fffffff;
+		nl[1].n_value &= 0x7fffffff;
+	}
+	(void) lseek(0, nl[1].n_value, 0);
+	if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
+		fprintf(stderr, "trsp: "); perror("spp_debx");
+		exit(3);
+	}
+	printf("spp_debx=%d\n", spp_debx);
+	(void) lseek(0, nl[0].n_value, 0);
+	if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
+		fprintf(stderr, "trsp: "); perror("spp_debug");
+		exit(3);
+	}
+	/*
+	 * Here, we just want to clear out the old trace data and start over.
+	 */
+	if (zflag) {
+		char *cp = (char *) spp_debug,
+		     *cplim = cp + sizeof(spp_debug);
+		(void) close(0);
+		if (open(core, 2) < 0) {
+			fprintf(stderr, "trsp: "); perror(core);
+			exit(2);
+		}
+		while(cp < cplim) *cp++ = 0;
+		(void) lseek(0, nl[0].n_value, 0);
+		if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
+			fprintf(stderr, "trsp: "); perror("spp_debug");
+			exit(3);
+		}
+		(void) lseek(0, nl[1].n_value, 0);
+		spp_debx = 0;
+		if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
+			fprintf(stderr, "trsp: "); perror("spp_debx");
+			exit(3);
+		}
+		exit(0);
+	}
+	/*
+	 * If no control blocks have been specified, figure
+	 * out how many distinct one we have and summarize
+	 * them in spp_pcbs for sorting the trace records
+	 * below.
+	 */
+	if (npcbs == 0) {
+		for (i = 0; i < SPP_NDEBUG; i++) {
+			register int j;
+			register struct spp_debug *sd = &spp_debug[i];
+
+			if (sd->sd_cb == 0)
+				continue;
+			for (j = 0; j < npcbs; j++)
+				if (spp_pcbs[j] == sd->sd_cb)
+					break;
+			if (j >= npcbs)
+				spp_pcbs[npcbs++] = sd->sd_cb;
+		}
+	}
+	qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric);
+	if (jflag) {
+		char *cp = "";
+
+		for (i = 0; i < npcbs; i++) {
+			printf("%s%x", cp, spp_pcbs[i]);
+			cp = ", ";
+		}
+		if (*cp)
+			putchar('\n');
+		exit(0);
+	}
+	for (i = 0; i < npcbs; i++) {
+		printf("\n%x:\n", spp_pcbs[i]);
+		dotrace(spp_pcbs[i]);
+	}
+	exit(0);
+}
+
+dotrace(sppcb)
+	register caddr_t sppcb;
+{
+	register int i;
+	register struct spp_debug *sd;
+
+	for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) {
+		sd = &spp_debug[i];
+		if (sppcb && sd->sd_cb != sppcb)
+			continue;
+		ntime = ntohl(sd->sd_time);
+		spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
+		    &sd->sd_si, sd->sd_req);
+	}
+	for (i = 0; i < spp_debx % SPP_NDEBUG; i++) {
+		sd = &spp_debug[i];
+		if (sppcb && sd->sd_cb != sppcb)
+			continue;
+		ntime = ntohl(sd->sd_time);
+		spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
+		    &sd->sd_si, sd->sd_req);
+	}
+}
+
+ptime(ms)
+	int ms;
+{
+
+	printf("%03d ", (ms/10) % 1000);
+}
+
+numeric(c1, c2)
+	caddr_t *c1, *c2;
+{
+	
+	return (*c1 - *c2);
+}
+
+spp_trace(act, ostate, asp, sp, si, req)
+	short act, ostate;
+	struct sppcb *asp, *sp;
+	struct spidp *si;
+	int req;
+{
+	u_short seq, ack, len, alo;
+	int flags, timer;
+	char *cp;
+
+	if(ostate >= TCP_NSTATES) ostate = 0;
+	if(act > SA_DROP) act = SA_DROP;
+	printf("\n");
+	ptime(ntime);
+	printf("%s:%s", tcpstates[ostate], sanames[act]);
+
+	if (si != 0) {
+		seq = si->si_seq;
+		ack = si->si_ack;
+		alo = si->si_alo;
+		len = si->si_len;
+		switch (act) {
+		case SA_RESPOND:
+		case SA_OUTPUT:
+				seq = ntohs(seq);
+				ack = ntohs(ack);
+				alo = ntohs(alo);
+				len = ntohs(len);
+		case SA_INPUT:
+		case SA_DROP:
+			if (aflag) {
+				printf("\n\tsna=");
+				ns_printhost(&si->si_sna);
+				printf("\tdna=");
+				ns_printhost(&si->si_dna);
+			}
+			printf("\n\t");
+#define p1(name, f) { \
+	printf("%s = %x, ", name, f); \
+ }
+			p1("seq", seq);
+			p1("ack", ack);
+			p1("alo", alo);
+			p1("len", len);
+			flags = si->si_cc;
+			printf("flags=%x", flags);
+#define pf(name, f) { \
+	if (flags & f) { \
+		printf("%s%s", cp, name); \
+		cp = ","; \
+	} \
+}
+			if (flags) {
+				char *cp = "<";
+				pf("SP_SP", SP_SP);
+				pf("SP_SA", SP_SA);
+				pf("SP_OB", SP_OB);
+				pf("SP_EM", SP_EM);
+				printf(">");
+			}
+			printf(", ");
+#define p2(name, f) { \
+	printf("%s = %x, ", name, f); \
+}
+			p2("sid", si->si_sid);
+			p2("did", si->si_did);
+			p2("dt", si->si_dt);
+			printf("\n\tsna=");
+			ns_printhost(&si->si_sna);
+			printf("\tdna=");
+			ns_printhost(&si->si_dna);
+		}
+	}
+	if(act == SA_USER) {
+		printf("\treq=%s", prurequests[req&0xff]);
+		if ((req & 0xff) == PRU_SLOWTIMO)
+			printf("<%s>", tcptimers[req>>8]);
+	}
+	printf(" -> %s", tcpstates[sp->s_state]);
+
+	/* print out internal state of sp !?! */
+	printf("\n");
+	if (sp == 0)
+		return;
+#define p3(name, f)  { \
+	printf("%s = %x, ", name, f); \
+}
+	if (sflag) {
+		printf("\t");
+		p3("rack", sp->s_rack);
+		p3("ralo", sp->s_ralo);
+		p3("smax", sp->s_smax);
+		p3("snxt", sp->s_snxt);
+		p3("flags", sp->s_flags);
+#undef pf
+#define pf(name, f) { \
+	if (flags & f) { \
+		printf("%s%s", cp, name); \
+		cp = ","; \
+	} \
+}
+		flags = sp->s_flags;
+		if (flags || sp->s_oobflags) {
+			char *cp = "<";
+			pf("ACKNOW", SF_ACKNOW);
+			pf("DELACK", SF_DELACK);
+			pf("HI", SF_HI);
+			pf("HO", SF_HO);
+			pf("PI", SF_PI);
+			pf("WIN", SF_WIN);
+			pf("RXT", SF_RXT);
+			pf("RVD", SF_RVD);
+			flags = sp->s_oobflags;
+			pf("SOOB", SF_SOOB);
+			pf("IOOB", SF_IOOB);
+			printf(">");
+		}
+	}
+	/* print out timers? */
+	if (tflag) {
+		char *cp = "\t";
+		register int i;
+
+		printf("\n\tTIMERS: ");
+		p3("idle", sp->s_idle);
+		p3("force", sp->s_force);
+		p3("rtseq", sp->s_rtseq);
+		for (i = 0; i < TCPT_NTIMERS; i++) {
+			if (sp->s_timer[i] == 0)
+				continue;
+			printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]);
+			if (i == TCPT_REXMT)
+				printf(" (s_rxtshft=%d)", sp->s_rxtshift);
+			cp = ", ";
+		}
+		if (*cp != '\t')
+			putchar('\n');
+	}
+}
+
+ns_printhost(p)
+register struct ns_addr *p;
+{
+
+	printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>",
+			p->x_net.s_net[0],
+			p->x_net.s_net[1],
+			p->x_host.s_host[0],
+			p->x_host.s_host[1],
+			p->x_host.s_host[2],
+			p->x_port);
+
+}
+
diff --git a/uucpd.tproj/Makefile b/uucpd.tproj/Makefile
new file mode 100644
index 0000000..4c25374
--- /dev/null
+++ b/uucpd.tproj/Makefile
@@ -0,0 +1,50 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = uucpd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = pathnames.h
+
+CFILES = uucpd.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+WINDOWS_INSTALLDIR = /usr/libexec
+PDO_UNIX_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/uucpd.tproj/Makefile.postamble b/uucpd.tproj/Makefile.postamble
new file mode 100644
index 0000000..7ede358
--- /dev/null
+++ b/uucpd.tproj/Makefile.postamble
@@ -0,0 +1,111 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	ENGLISH - boolean flag set iff $(LANGUAGE) = "English"
+#	JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese"
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder that output Makefile
+#	APPICON - application icon file
+#	DOCICONS - dock icon files
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
diff --git a/uucpd.tproj/Makefile.preamble b/uucpd.tproj/Makefile.preamble
new file mode 100644
index 0000000..dcbd1c8
--- /dev/null
+++ b/uucpd.tproj/Makefile.preamble
@@ -0,0 +1,119 @@
+###############################################################################
+#  NeXT Makefile.preamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS = 
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set all three of these if you want a precomp to be built as part of
+# installation.  The cc -precomp will be run in the specified dir on the
+# specified public header files with the specified additional flags.  Don't put
+# $(DSTROOT) in PUBLIC_HEADER_DIR; this is done for you.
+PUBLIC_HEADER_DIR = 
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) 
+# passed from ProjectBuilder.
+DSTROOT = 
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
+-include ../Makefile.include
diff --git a/uucpd.tproj/PB.project b/uucpd.tproj/PB.project
new file mode 100644
index 0000000..ba6c171
--- /dev/null
+++ b/uucpd.tproj/PB.project
@@ -0,0 +1,42 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (pathnames.h); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (uucpd.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    GENERATEMAIN = YES; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_DOCUMENTEXTENSIONS = (); 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/libexec; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = uucpd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/libexec; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/uucpd.tproj/pathnames.h b/uucpd.tproj/pathnames.h
new file mode 100644
index 0000000..0383391
--- /dev/null
+++ b/uucpd.tproj/pathnames.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 6/4/93
+ */
+
+#include <paths.h>
+
+#define	_PATH_UUCICO	"/usr/lib/uucp/uucico"
diff --git a/uucpd.tproj/uucpd.c b/uucpd.tproj/uucpd.c
new file mode 100644
index 0000000..4a5445c
--- /dev/null
+++ b/uucpd.tproj/uucpd.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Adams.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1985, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)uucpd.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * 4.2BSD TCP/IP server for uucico
+ * uucico's TCP channel causes this server to be run at the remote end.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <time.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pathnames.h"
+
+struct	sockaddr_in hisctladdr;
+int hisaddrlen = sizeof hisctladdr;
+struct	sockaddr_in myctladdr;
+int mypid;
+
+char Username[64];
+char *nenv[] = {
+	Username,
+	NULL,
+};
+extern char **environ;
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+#ifndef BSDINETD
+	register int s, tcp_socket;
+	struct servent *sp;
+#endif !BSDINETD
+	extern int errno;
+	int dologout();
+
+	environ = nenv;
+#ifdef BSDINETD
+	close(1); close(2);
+	dup(0); dup(0);
+	hisaddrlen = sizeof (hisctladdr);
+	if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) {
+		fprintf(stderr, "%s: ", argv[0]);
+		perror("getpeername");
+		_exit(1);
+	}
+	if (fork() == 0)
+		doit(&hisctladdr);
+	dologout();
+	exit(1);
+#else !BSDINETD
+	sp = getservbyname("uucp", "tcp");
+	if (sp == NULL){
+		perror("uucpd: getservbyname");
+		exit(1);
+	}
+	if (fork())
+		exit(0);
+	if ((s=open(_PATH_TTY, 2)) >= 0){
+		ioctl(s, TIOCNOTTY, (char *)0);
+		close(s);
+	}
+
+	bzero((char *)&myctladdr, sizeof (myctladdr));
+	myctladdr.sin_family = AF_INET;
+	myctladdr.sin_port = sp->s_port;
+#ifdef BSD4_2
+	tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
+	if (tcp_socket < 0) {
+		perror("uucpd: socket");
+		exit(1);
+	}
+	if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) {
+		perror("uucpd: bind");
+		exit(1);
+	}
+	listen(tcp_socket, 3);	/* at most 3 simultaneuos uucp connections */
+	signal(SIGCHLD, dologout);
+
+	for(;;) {
+		s = accept(tcp_socket, &hisctladdr, &hisaddrlen);
+		if (s < 0){
+			if (errno == EINTR) 
+				continue;
+			perror("uucpd: accept");
+			exit(1);
+		}
+		if (fork() == 0) {
+			close(0); close(1); close(2);
+			dup(s); dup(s); dup(s);
+			close(tcp_socket); close(s);
+			doit(&hisctladdr);
+			exit(1);
+		}
+		close(s);
+	}
+#endif BSD4_2
+
+#endif	!BSDINETD
+}
+
+doit(sinp)
+struct sockaddr_in *sinp;
+{
+	char user[64], passwd[64];
+	char *xpasswd, *crypt();
+	struct passwd *pw, *getpwnam();
+
+	alarm(60);
+	printf("login: "); fflush(stdout);
+	if (readline(user, sizeof user) < 0) {
+		fprintf(stderr, "user read\n");
+		return;
+	}
+	/* truncate username to 8 characters */
+	user[8] = '\0';
+	pw = getpwnam(user);
+	if (pw == NULL) {
+		fprintf(stderr, "user unknown\n");
+		return;
+	}
+	if (strcmp(pw->pw_shell, _PATH_UUCICO)) {
+		fprintf(stderr, "Login incorrect.");
+		return;
+	}
+	if (pw->pw_passwd && *pw->pw_passwd != '\0') {
+		printf("Password: "); fflush(stdout);
+		if (readline(passwd, sizeof passwd) < 0) {
+			fprintf(stderr, "passwd read\n");
+			return;
+		}
+		xpasswd = crypt(passwd, pw->pw_passwd);
+		if (strcmp(xpasswd, pw->pw_passwd)) {
+			fprintf(stderr, "Login incorrect.");
+			return;
+		}
+	}
+	alarm(0);
+	sprintf(Username, "USER=%s", user);
+	dologin(pw, sinp);
+	setgid(pw->pw_gid);
+#ifdef BSD4_2
+	initgroups(pw->pw_name, pw->pw_gid);
+#endif BSD4_2
+	chdir(pw->pw_dir);
+	setuid(pw->pw_uid);
+#ifdef BSD4_2
+	execl(UUCICO, "uucico", (char *)0);
+#endif BSD4_2
+	perror("uucico server: execl");
+}
+
+readline(p, n)
+register char *p;
+register int n;
+{
+	char c;
+
+	while (n-- > 0) {
+		if (read(0, &c, 1) <= 0)
+			return(-1);
+		c &= 0177;
+		if (c == '\n' || c == '\r') {
+			*p = '\0';
+			return(0);
+		}
+		*p++ = c;
+	}
+	return(-1);
+}
+
+#include <utmp.h>
+#ifdef BSD4_2
+#include <fcntl.h>
+#endif BSD4_2
+
+#define	SCPYN(a, b)	strncpy(a, b, sizeof (a))
+
+struct	utmp utmp;
+
+dologout()
+{
+	union wait status;
+	int pid, wtmp;
+
+#ifdef BSDINETD
+	while ((pid=wait((int *)&status)) > 0) {
+#else  !BSDINETD
+	while ((pid=wait3((int *)&status,WNOHANG,0)) > 0) {
+#endif !BSDINETD
+		wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND);
+		if (wtmp >= 0) {
+			sprintf(utmp.ut_line, "uucp%.4d", pid);
+			SCPYN(utmp.ut_name, "");
+			SCPYN(utmp.ut_host, "");
+			(void) time(&utmp.ut_time);
+			(void) write(wtmp, (char *)&utmp, sizeof (utmp));
+			(void) close(wtmp);
+		}
+	}
+}
+
+/*
+ * Record login in wtmp file.
+ */
+dologin(pw, sin)
+struct passwd *pw;
+struct sockaddr_in *sin;
+{
+	char line[32];
+	char remotehost[32];
+	int wtmp, f;
+	struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr,
+		sizeof (struct in_addr), AF_INET);
+
+	if (hp) {
+		strncpy(remotehost, hp->h_name, sizeof (remotehost));
+		endhostent();
+	} else
+		strncpy(remotehost, inet_ntoa(sin->sin_addr),
+		    sizeof (remotehost));
+	wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND);
+	if (wtmp >= 0) {
+		/* hack, but must be unique and no tty line */
+		sprintf(line, "uucp%.4d", getpid());
+		SCPYN(utmp.ut_line, line);
+		SCPYN(utmp.ut_name, pw->pw_name);
+		SCPYN(utmp.ut_host, remotehost);
+		time(&utmp.ut_time);
+		(void) write(wtmp, (char *)&utmp, sizeof (utmp));
+		(void) close(wtmp);
+	}
+	if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) {
+		struct lastlog ll;
+
+		time(&ll.ll_time);
+		lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0);
+		strcpy(line, remotehost);
+		SCPYN(ll.ll_line, line);
+		SCPYN(ll.ll_host, remotehost);
+		(void) write(f, (char *) &ll, sizeof ll);
+		(void) close(f);
+	}
+}
diff --git a/wall.tproj/Makefile b/wall.tproj/Makefile
new file mode 100644
index 0000000..9d20c3c
--- /dev/null
+++ b/wall.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = wall
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = ttymsg.c wall.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\
+            wall.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/wall.tproj/Makefile.dist b/wall.tproj/Makefile.dist
new file mode 100644
index 0000000..65abb61
--- /dev/null
+++ b/wall.tproj/Makefile.dist
@@ -0,0 +1,8 @@
+#	@(#)Makefile	8.1 (Berkeley) 6/6/93
+
+PROG=	wall
+SRCS=	ttymsg.c wall.c
+BINGRP=	tty
+BINMODE=2555
+
+.include <bsd.prog.mk>
diff --git a/wall.tproj/Makefile.postamble b/wall.tproj/Makefile.postamble
new file mode 100644
index 0000000..851f5b0
--- /dev/null
+++ b/wall.tproj/Makefile.postamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  NeXT Makefile.postamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES
+       # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+       # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1
+       # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       
+       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wmost
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root
+        # User/group ownership 
+INSTALL_AS_GROUP = tty
+        # (probably want to set both of these) 
+INSTALL_PERMISSIONS = 2555
+        # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S
+        # for .a archives
+#DYNAMIC_STRIP_OPTS = -S
+        # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
+# Note: on MS Windows, executables, have an extension, so rules and dependencies
+#       for generated tools should use $(EXECUTABLE_EXT) on the end.
diff --git a/wall.tproj/Makefile.preamble b/wall.tproj/Makefile.preamble
new file mode 100644
index 0000000..74ce95a
--- /dev/null
+++ b/wall.tproj/Makefile.preamble
@@ -0,0 +1,130 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES =
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
+
diff --git a/wall.tproj/PB.project b/wall.tproj/PB.project
new file mode 100644
index 0000000..d0b5d25
--- /dev/null
+++ b/wall.tproj/PB.project
@@ -0,0 +1,27 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_LINKED = (ttymsg.c, wall.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, Makefile.dist, wall.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = wall; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/wall.tproj/ttymsg.c b/wall.tproj/ttymsg.c
new file mode 100644
index 0000000..45e4d2d
--- /dev/null
+++ b/wall.tproj/ttymsg.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <paths.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/*
+ * Display the contents of a uio structure on a terminal.  Used by wall(1),
+ * syslogd(8), and talkd(8).  Forks and finishes in child if write would block,
+ * waiting up to tmout seconds.  Returns pointer to error string on unexpected
+ * error; string is not newline-terminated.  Various "normal" errors are
+ * ignored (exclusive-use, lack of permission, etc.).
+ */
+char *
+ttymsg(iov, iovcnt, line, tmout)
+	struct iovec *iov;
+	int iovcnt;
+	char *line;
+	int tmout;
+{
+	static char device[MAXNAMLEN] = _PATH_DEV;
+	static char errbuf[1024];
+	register int cnt, fd, left, wret;
+	struct iovec localiov[6];
+	int forked = 0;
+
+	if (iovcnt > sizeof(localiov) / sizeof(localiov[0]))
+		return ("too many iov's (change code in wall/ttymsg.c)");
+
+	(void) strcpy(device + sizeof(_PATH_DEV) - 1, line);
+	if (strchr(device + sizeof(_PATH_DEV) - 1, '/')) {
+		/* A slash is an attempt to break security... */
+		(void) snprintf(errbuf, sizeof(errbuf), "'/' in \"%s\"",
+		    device);
+		return (errbuf);
+	}
+
+	/*
+	 * open will fail on slip lines or exclusive-use lines
+	 * if not running as root; not an error.
+	 */
+	if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) {
+		if (errno == EBUSY || errno == EACCES)
+			return (NULL);
+		(void) snprintf(errbuf, sizeof(errbuf),
+		    "%s: %s", device, strerror(errno));
+		return (errbuf);
+	}
+
+	for (cnt = left = 0; cnt < iovcnt; ++cnt)
+		left += iov[cnt].iov_len;
+
+	for (;;) {
+		wret = writev(fd, iov, iovcnt);
+		if (wret >= left)
+			break;
+		if (wret >= 0) {
+			left -= wret;
+			if (iov != localiov) {
+				bcopy(iov, localiov,
+				    iovcnt * sizeof(struct iovec));
+				iov = localiov;
+			}
+			for (cnt = 0; wret >= iov->iov_len; ++cnt) {
+				wret -= iov->iov_len;
+				++iov;
+				--iovcnt;
+			}
+			if (wret) {
+				iov->iov_base += wret;
+				iov->iov_len -= wret;
+			}
+			continue;
+		}
+		if (errno == EWOULDBLOCK) {
+			int cpid, off = 0;
+
+			if (forked) {
+				(void) close(fd);
+				_exit(1);
+			}
+			cpid = fork();
+			if (cpid < 0) {
+				(void) snprintf(errbuf, sizeof(errbuf),
+				    "fork: %s", strerror(errno));
+				(void) close(fd);
+				return (errbuf);
+			}
+			if (cpid) {	/* parent */
+				(void) close(fd);
+				return (NULL);
+			}
+			forked++;
+			/* wait at most tmout seconds */
+			(void) signal(SIGALRM, SIG_DFL);
+			(void) signal(SIGTERM, SIG_DFL); /* XXX */
+			(void) sigsetmask(0);
+			(void) alarm((u_int)tmout);
+			(void) fcntl(fd, O_NONBLOCK, &off);
+			continue;
+		}
+		/*
+		 * We get ENODEV on a slip line if we're running as root,
+		 * and EIO if the line just went away.
+		 */
+		if (errno == ENODEV || errno == EIO)
+			break;
+		(void) close(fd);
+		if (forked)
+			_exit(1);
+		(void) snprintf(errbuf, sizeof(errbuf),
+		    "%s: %s", device, strerror(errno));
+		return (errbuf);
+	}
+
+	(void) close(fd);
+	if (forked)
+		_exit(0);
+	return (NULL);
+}
diff --git a/wall.tproj/wall.1 b/wall.tproj/wall.1
new file mode 100644
index 0000000..ed2f4c9
--- /dev/null
+++ b/wall.tproj/wall.1
@@ -0,0 +1,63 @@
+.\" Copyright (c) 1989, 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)wall.1	8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt WALL 1
+.Os BSD 4
+.Sh NAME
+.Nm wall
+.Nd write a message to users
+.Sh SYNOPSIS
+.Nm wall
+.Op Ar file
+.Sh DESCRIPTION
+.Nm Wall
+displays the contents of
+.Ar file
+or, by default, its standard input, on the terminals of all
+currently logged in users.
+.Pp
+Only the super-user can write on the
+terminals of users who have chosen
+to deny messages or are using a program which
+automatically denies messages.
+.Sh SEE ALSO
+.Xr mesg 1 ,
+.Xr talk 1 ,
+.Xr write 1 ,
+.Xr shutdown 8
+.Sh HISTORY
+A
+.Nm
+command appeared in
+.At v7 .
diff --git a/wall.tproj/wall.c b/wall.tproj/wall.c
new file mode 100644
index 0000000..e08a8dd
--- /dev/null
+++ b/wall.tproj/wall.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1988, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1990, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+/*
+ * This program is not related to David Wall, whose Stanford Ph.D. thesis
+ * is entitled "Mechanisms for Broadcast and Selective Broadcast".
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <utmp.h>
+
+void	makemsg __P((char *));
+
+#define	IGNOREUSER	"sleeper"
+
+int nobanner;
+int mbufsize;
+char *mbuf;
+
+/* ARGSUSED */
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	extern int optind;
+	int ch;
+	struct iovec iov;
+	struct utmp utmp;
+	FILE *fp;
+	char *p, *ttymsg();
+	char line[sizeof(utmp.ut_line) + 1];
+
+	while ((ch = getopt(argc, argv, "n")) != EOF)
+		switch (ch) {
+		case 'n':
+			/* undoc option for shutdown: suppress banner */
+			if (geteuid() == 0)
+				nobanner = 1;
+			break;
+		case '?':
+		default:
+usage:
+			(void)fprintf(stderr, "usage: wall [file]\n");
+			exit(1);
+		}
+	argc -= optind;
+	argv += optind;
+	if (argc > 1)
+		goto usage;
+
+	makemsg(*argv);
+
+	if (!(fp = fopen(_PATH_UTMP, "r"))) {
+		(void)fprintf(stderr, "wall: cannot read %s.\n", _PATH_UTMP);
+		exit(1);
+	}
+	iov.iov_base = mbuf;
+	iov.iov_len = mbufsize;
+	/* NOSTRICT */
+	while (fread((char *)&utmp, sizeof(utmp), 1, fp) == 1) {
+		if (!utmp.ut_name[0] ||
+		    !strncmp(utmp.ut_name, IGNOREUSER, sizeof(utmp.ut_name)))
+			continue;
+		strncpy(line, utmp.ut_line, sizeof(utmp.ut_line));
+		line[sizeof(utmp.ut_line)] = '\0';
+		if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL)
+			(void)fprintf(stderr, "wall: %s\n", p);
+	}
+	exit(0);
+}
+
+void
+makemsg(fname)
+	char *fname;
+{
+	register int ch, cnt;
+	struct tm *lt;
+	struct passwd *pw;
+	struct stat sbuf;
+	time_t now, time();
+	FILE *fp;
+	int fd;
+	char *p, *whom, hostname[MAXHOSTNAMELEN], lbuf[100], tmpname[15];
+	char *getlogin(), *strcpy(), *ttyname();
+
+	(void)strcpy(tmpname, _PATH_TMP);
+	(void)strcat(tmpname, "/wall.XXXXXX");
+	if (!(fd = mkstemp(tmpname)) || !(fp = fdopen(fd, "r+"))) {
+		(void)fprintf(stderr, "wall: can't open temporary file.\n");
+		exit(1);
+	}
+	(void)unlink(tmpname);
+
+	if (!nobanner) {
+		if (!(whom = getlogin()))
+			whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
+		(void)gethostname(hostname, sizeof(hostname));
+		(void)time(&now);
+		lt = localtime(&now);
+
+		/*
+		 * all this stuff is to blank out a square for the message;
+		 * we wrap message lines at column 79, not 80, because some
+		 * terminals wrap after 79, some do not, and we can't tell.
+		 * Which means that we may leave a non-blank character
+		 * in column 80, but that can't be helped.
+		 */
+		(void)fprintf(fp, "\r%79s\r\n", " ");
+		(void)sprintf(lbuf, "Broadcast Message from %s@%s",
+		    whom, hostname);
+		(void)fprintf(fp, "%-79.79s\007\007\r\n", lbuf);
+		(void)sprintf(lbuf, "        (%s) at %d:%02d ...", ttyname(2),
+		    lt->tm_hour, lt->tm_min);
+		(void)fprintf(fp, "%-79.79s\r\n", lbuf);
+	}
+	(void)fprintf(fp, "%79s\r\n", " ");
+
+	if (fname && !(freopen(fname, "r", stdin))) {
+		(void)fprintf(stderr, "wall: can't read %s.\n", fname);
+		exit(1);
+	}
+	while (fgets(lbuf, sizeof(lbuf), stdin))
+		for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
+			if (cnt == 79 || ch == '\n') {
+				for (; cnt < 79; ++cnt)
+					putc(' ', fp);
+				putc('\r', fp);
+				putc('\n', fp);
+				cnt = 0;
+			} else
+				putc(ch, fp);
+		}
+	(void)fprintf(fp, "%79s\r\n", " ");
+	rewind(fp);
+
+	if (fstat(fd, &sbuf)) {
+		(void)fprintf(stderr, "wall: can't stat temporary file.\n");
+		exit(1);
+	}
+	mbufsize = sbuf.st_size;
+	if (!(mbuf = malloc((u_int)mbufsize))) {
+		(void)fprintf(stderr, "wall: out of memory.\n");
+		exit(1);
+	}
+	if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) {
+		(void)fprintf(stderr, "wall: can't read temporary file.\n");
+		exit(1);
+	}
+	(void)close(fd);
+}
diff --git a/ypbind.tproj/Makefile b/ypbind.tproj/Makefile
new file mode 100644
index 0000000..548fccf
--- /dev/null
+++ b/ypbind.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ypbind
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = ypbind.c
+
+OTHERSRCS = Makefile Makefile.dist Makefile.postamble Makefile.preamble\
+            yp.x
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ypbind.tproj/Makefile.dist b/ypbind.tproj/Makefile.dist
new file mode 100644
index 0000000..901e614
--- /dev/null
+++ b/ypbind.tproj/Makefile.dist
@@ -0,0 +1,8 @@
+#	from: @(#)Makefile	5.8 (Berkeley) 7/28/90
+#	$Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:59:00 wsanchez Exp $
+
+PROG=	ypbind
+NOMAN=
+CFLAGS+=-DDAEMON -DHEURISTIC
+
+.include <bsd.prog.mk>
diff --git a/ypbind.tproj/Makefile.postamble b/ypbind.tproj/Makefile.postamble
new file mode 100644
index 0000000..cc6d6ab
--- /dev/null
+++ b/ypbind.tproj/Makefile.postamble
@@ -0,0 +1,108 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#	PRODUCT_ROOT - Name of the directory to which resources are copied.
+#	OFILE_DIR - Directory into which .o object files are generated.
+#		    (Note that this name is calculated based on the target 
+#		     architectures specified in Project Builder).
+#	DERIVED_SRC_DIR - Directory used for all other derived files
+#	ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#	NAME - name of application, bundle, subproject, palette, etc.
+#	LANGUAGE - langage in which the project is written (default "English")
+#	LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#	GLOBAL_RESOURCES - non-localized resources of project
+#	PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#	ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#	CLASSES - Class implementation files in project.
+#	HFILES - Header files in project.
+#	MFILES - Other Objective-C source files in project. 
+#	CFILES - Other C source files in project. 
+#	PSWFILES - .psw files in the project
+#	PSWMFILES - .pswm files in the project
+#	SUBPROJECTS - Subprojects of this project
+#	BUNDLES - Bundle subprojects of this project
+#	OTHERSRCS - Other miscellaneous sources of this project
+#	OTHERLINKED - Source files not matching a standard source extention
+#
+#	LIBS - Libraries to link with when making app target
+#	DEBUG_LIBS - Libraries to link with when making debug target
+#	PROF_LIBS - Libraries to link with when making profile target
+#	OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#	APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#	MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#	MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#	INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A      # This should be incremented as your API changes.
+#COMPATIBILITY_PROJECT_VERSION = 1 # This should be incremented as your API grows.
+#CURRENT_PROJECT_VERSION = 1       # Defaults to using the "vers_string" hack.
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+STRIPFLAGS =
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
diff --git a/ypbind.tproj/Makefile.preamble b/ypbind.tproj/Makefile.preamble
new file mode 100644
index 0000000..5ca4df3
--- /dev/null
+++ b/ypbind.tproj/Makefile.preamble
@@ -0,0 +1,129 @@
+###############################################################################
+#  NeXT Makefile.preamble
+#  Copyright 1996, NeXT Software, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project.  Each node in a project
+#  tree of sub-projects, tools, etc. should have its own Makefile.preamble and 
+#  Makefile.postamble.
+#
+###############################################################################
+## Configure the flags passed to $(CC) here.  These flags will also be 
+## inherited by all nested sub-projects and bundles.  Put your -I, -D, -U, and
+## -L flags in ProjectBuilder's Build Options inspector if at all possible.
+## To change the default flags that get passed to ${CC} 
+## (e.g. change -O to -O2), see Makefile.postamble.
+
+# Flags passed to compiler (in addition to -g, -O, etc)
+OTHER_CFLAGS = 
+# Flags passed to ld (in addition to -ObjC, etc.)
+OTHER_LDFLAGS =	
+# Flags passed to libtool when building libraries
+OTHER_LIBTOOL_FLAGS =
+# For ordering named sections on NEXTSTEP (see ld(1))
+SECTORDER_FLAGS =
+
+# If you do not want any headers exported before compilations begin,
+# uncomment the following line.  This can be a big time saver.
+#SKIP_EXPORTING_HEADERS = YES
+
+# Stuff related to exporting headers from this project that isn't already 
+# handled by PB.
+OTHER_PUBLIC_HEADERS =
+OTHER_PROJECT_HEADERS =
+OTHER_PRIVATE_HEADERS =
+
+# Set these two macros if you want a precomp to be built as part of
+# installation. The cc -precomp will be run in the public header directory
+# on the specified public header files with the specified additional flags.
+PUBLIC_PRECOMPILED_HEADERS =
+PUBLIC_PRECOMPILED_HEADERS_CFLAGS =
+
+# Set this for library projects if you want to publish header files.  If your 
+# app or tool project exports headers  Don't
+# include $(DSTROOT); this is added for you automatically.
+PUBLIC_HEADER_DIR =
+PRIVATE_HEADER_DIR =
+
+# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# 
+# (say, to add a subdirectory like "/sys"), you can use:
+PUBLIC_HEADER_DIR_SUFFIX = 
+PRIVATE_HEADER_DIR_SUFFIX = 
+
+# Set this for dynamic library projects on platforms where code which references
+# a dynamic library must link against an import library (i.e., Windows NT)
+# Don't include $(DSTROOT); this is added for you automatically.
+IMPORT_LIBRARY_DIR = 
+
+# Additional (non-localized) resources for this project, which can be generated
+OTHER_RESOURCES = 
+
+# Uncomment this to produce a static archive-style (.a) library
+#LIBRARY_STYLE = STATIC
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+BUILD_OFILES_LIST_ONLY = 
+
+# Additional relocatables to be linked into this project
+OTHER_OFILES = 
+# Additional libraries to link against
+OTHER_LIBS = 
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+## Configure how things get built here.  Additional dependencies, source files, 
+## derived files, and build order should be specified here.
+
+# Other dependencies of this project
+OTHER_PRODUCT_DEPENDS =	
+# Built *before* building subprojects/bundles
+OTHER_INITIAL_TARGETS = 
+# Other source files maintained by .pre/postamble
+OTHER_SOURCEFILES = 
+# Additional files to be removed by `make clean' 
+OTHER_GARBAGE = 
+
+# Targets to build before installation
+OTHER_INSTALL_DEPENDS =	
+
+# More obscure flags you might want to set for pswrap, yacc, lex, etc.
+PSWFLAGS = 
+YFLAGS = 
+LFLAGS = 
+
+## Delete this line if you want fast and loose cleans that will not remove 
+## things like precomps and user-defined OTHER_GARBAGE in subprojects.
+CLEAN_ALL_SUBPROJECTS = YES
+
+## Add more obscure source files here to cause them to be automatically 
+## processed by the appropriate tool.  Note that these files should also be
+## added to "Supporting Files" in ProjectBuilder.  The desired .o files that 
+## result from these files should also be added to OTHER_OFILES above so they
+## will be linked in.
+
+# .msg files that should have msgwrap run on them
+MSGFILES = 
+# .defs files that should have mig run on them
+DEFSFILES = 
+# .mig files (no .defs files) that should have mig run on them
+MIGFILES = 
+# .x files that should have rpcgen run on them
+RPCFILES = yp.x
+
+## Add additional Help directories here (add them to the project as "Other 
+## Resources" in Project Builder) so that they will be compressed into .store
+## files and copied into the app wrapper.  If the help directories themselves
+## need to also be in the app wrapper, then a cp command will need to be added
+## in an after_install target.
+OTHER_HELP_DIRS = 
+
+# After you have saved your project using the 4.0 PB, you will automatically 
+# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project.  If you should 
+# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to
+# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app.
+
+# Don't add more rules here unless you want the first one to be the default
+# target for make!  Put all your targets in Makefile.postamble.
diff --git a/ypbind.tproj/PB.project b/ypbind.tproj/PB.project
new file mode 100644
index 0000000..dba6980
--- /dev/null
+++ b/ypbind.tproj/PB.project
@@ -0,0 +1,36 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LINKED = (ypbind.c); 
+        OTHER_SOURCES = (Makefile, Makefile.dist, Makefile.postamble, Makefile.preamble, yp.x); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ypbind; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ypbind.tproj/yp.x b/ypbind.tproj/yp.x
new file mode 100644
index 0000000..cf2be0c
--- /dev/null
+++ b/ypbind.tproj/yp.x
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include <rpcsvc/yp.x>
diff --git a/ypbind.tproj/ypbind.c b/ypbind.tproj/ypbind.c
new file mode 100644
index 0000000..bad58c0
--- /dev/null
+++ b/ypbind.tproj/ypbind.c
@@ -0,0 +1,1289 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$Id: ypbind.c,v 1.1.1.1 1999/05/02 03:59:00 wsanchez Exp $";
+#endif
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/signal.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <netdb.h>
+#include <string.h>
+#include <err.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_rmt.h>
+#include <unistd.h>
+#include <rpcsvc/yp.h>
+// #include <rpcsvc/yp_prot.h>
+// #include <rpcsvc/ypclnt.h>
+
+#define _PATH_YPBIND_LOCK "/var/run/ypbind.lock"
+#define YPSERVERSSUFF	".ypservers"
+#define BINDINGDIR	"/var/yp/binding"
+
+#ifndef O_SHLOCK
+#define O_SHLOCK 0
+#endif
+
+#define BUFSIZE		1400
+
+struct _dom_binding
+{
+	struct _dom_binding *dom_pnext;
+	char dom_domain[YPMAXDOMAIN + 1];
+	struct sockaddr_in dom_server_addr;
+	unsigned short int dom_server_port;
+	int dom_socket;
+	CLIENT *dom_client;
+	long dom_vers;
+	time_t dom_check_t;
+	time_t dom_ask_t;
+	int dom_lockfd;
+	int dom_alive;
+	u_int32_t dom_xid;
+};
+
+static char *dname;
+
+static struct _dom_binding *ypbindlist;
+static int check;
+
+typedef enum
+{
+	YPBIND_DIRECT,
+	YPBIND_BROADCAST,
+	YPBIND_SETLOCAL,
+	YPBIND_SETALL
+} ypbind_mode_t;
+
+ypbind_mode_t ypbindmode;
+
+/*
+ * If ypbindmode is YPBIND_SETLOCAL or YPBIND_SETALL, this indicates
+ * whether or not we've been "ypset".  If we haven't, we behave like
+ * YPBIND_BROADCAST.  If we have, we behave like YPBIND_DIRECT.
+ */
+int been_ypset;
+
+static int insecure;
+static int rpcsock, pingsock;
+static struct rmtcallargs rmtca;
+static struct rmtcallres rmtcr;
+static bool_t rmtcr_outval;
+static u_long rmtcr_port;
+static SVCXPRT *udptransp, *tcptransp;
+
+int	main __P((int, char *[]));
+
+static void usage __P((void));
+static struct _dom_binding *makebinding __P((const char *));
+static int makelock __P((struct _dom_binding *));
+static void removelock __P((struct _dom_binding *));
+static void checkwork __P((void));
+static int ping __P((struct _dom_binding *));
+static int nag_servers __P((struct _dom_binding *));
+static enum clnt_stat handle_replies __P((void));
+static enum clnt_stat handle_ping __P((void));
+static void rpc_received __P((char *, struct sockaddr_in *, int));
+static struct _dom_binding *xid2ypdb __P((u_int32_t));
+static u_int32_t unique_xid __P((struct _dom_binding *));
+static int broadcast __P((char *, int));
+static int direct __P((char *, int));
+static int direct_set __P((char *, int, struct _dom_binding *));
+
+#define DEBUG_NONE 0
+#define DEBUG_STDERR 1
+#define DEBUG_SYSLOG 2
+
+static int debug;
+static char *msg_str = NULL;
+
+void
+sys_openlog(int debug, char *str, int flags, int facility)
+{
+	if (msg_str != NULL) free(msg_str);
+	msg_str = NULL;
+	if (str != NULL)
+	{
+		msg_str = malloc(strlen(str) + 1);
+		strcpy(msg_str, str);
+	}
+
+	if (debug & DEBUG_SYSLOG) openlog(msg_str, flags, facility);
+}
+
+void
+sys_msg(int debug, int priority, char *message, ...)
+{
+	va_list ap;
+
+	va_start(ap, message);
+
+	if (debug & DEBUG_SYSLOG) vsyslog(priority, message, ap);
+
+	if (debug & DEBUG_STDERR)
+	{
+		if (msg_str != NULL) fprintf(stderr, "%s: ", msg_str);
+		vfprintf(stderr, message, ap);
+		fprintf(stderr, "\n");
+		fflush(stderr);
+	}
+
+	va_end(ap);
+}
+
+static void
+usage()
+{
+	fprintf(stderr,
+	    "Usage: ypbind [-broadcast] [-insecure] [-ypset] [-ypsetme] [-d]\n");
+	exit(1);
+}
+	
+static struct _dom_binding *
+makebinding(const char *dm)
+{
+	struct _dom_binding *ypdb;
+
+	ypdb = (struct _dom_binding *)malloc(sizeof *ypdb);
+	memset(ypdb, 0, sizeof *ypdb);
+	strncpy(ypdb->dom_domain, dm, sizeof ypdb->dom_domain);
+	ypdb->dom_domain[sizeof(ypdb->dom_domain) - 1] = '\0';
+
+	return ypdb;
+}
+
+static int
+makelock(struct _dom_binding *ypdb)
+{
+	int fd;
+	char path[MAXPATHLEN];
+
+	snprintf(path, sizeof(path), "%s/%s.%ld", BINDINGDIR,
+	    ypdb->dom_domain, ypdb->dom_vers);
+
+	fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644);
+	if (fd == -1)
+	{
+		mkdir(BINDINGDIR, 0755);
+		fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644);
+		if (fd == -1) return -1;
+	}
+
+#if O_SHLOCK == 0
+	flock(fd, LOCK_SH);
+#endif
+	return fd;
+}
+
+static void
+removelock(struct _dom_binding *ypdb)
+{
+	char path[MAXPATHLEN];
+
+	snprintf(path, sizeof(path), "%s/%s.%ld",
+	    BINDINGDIR, ypdb->dom_domain, ypdb->dom_vers);
+	unlink(path);
+}
+
+static void *
+svc_ypbindproc_null_2(void *argp, SVCXPRT *transp)
+{
+	static char res;
+
+	sys_msg(debug, LOG_DEBUG, "ypbindproc_null_2");
+
+	memset(&res, 0, sizeof(res));
+	return (void *)&res;
+}
+
+static void *
+svc_ypbindproc_domain_2(void *argp, SVCXPRT *transp)
+{
+	static struct ypbind_resp res;
+	struct _dom_binding *ypdb;
+	char *arg = *(char **) argp;
+	int count;
+
+	sys_msg(debug, LOG_DEBUG, "ypbindproc_domain_2 %s", arg);
+
+	memset(&res, 0, sizeof res);
+	res.ypbind_status = YPBIND_FAIL_VAL;
+
+	for (count = 0, ypdb = ypbindlist;
+		ypdb != NULL;
+		ypdb = ypdb->dom_pnext, count++)
+	{
+		/* prevent denial of service */
+		if (count > 100) return NULL;
+		if (!strcmp(ypdb->dom_domain, arg)) break;
+	}
+
+	if (ypdb == NULL)
+	{
+		ypdb = makebinding(arg);
+		ypdb->dom_vers = YPVERS;
+		ypdb->dom_alive = 0;
+		ypdb->dom_lockfd = -1;
+		removelock(ypdb);
+		ypdb->dom_xid = unique_xid(ypdb);
+		ypdb->dom_pnext = ypbindlist;
+		ypbindlist = ypdb;
+		check++;
+		sys_msg(debug, LOG_ERR, "unknown domain %s", arg);
+		return NULL;
+	}
+
+	if (ypdb->dom_alive == 0)
+	{
+		sys_msg(debug, LOG_ERR, "dead domain %s", arg);
+		return NULL;
+	}
+
+#ifdef HEURISTIC
+	time(&now);
+	if (now < ypdb->dom_ask_t + 5)
+	{
+		/*
+		 * Hmm. More than 2 requests in 5 seconds have indicated
+		 * that my binding is possibly incorrect.
+		 * Ok, do an immediate poll of the server.
+		 */
+		if (ypdb->dom_check_t >= now)
+		{
+			/* don't flood it */
+			ypdb->dom_check_t = 0;
+			check++;
+		}
+	}
+	ypdb->dom_ask_t = now;
+#endif
+
+	res.ypbind_status = YPBIND_SUCC_VAL;
+	bcopy(&ypdb->dom_server_addr.sin_addr.s_addr,
+		res.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr, 4);
+	bcopy(&ypdb->dom_server_port,
+		res.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port, 2);
+
+	sys_msg(debug, LOG_DEBUG, "domain %s at %s/%d", ypdb->dom_domain,
+		    inet_ntoa(ypdb->dom_server_addr.sin_addr),
+		    ntohs(ypdb->dom_server_addr.sin_port));
+	return &res;
+}
+
+static void *
+svc_ypbindproc_setdom_2(void *argp, SVCXPRT *transp)
+{
+	struct ypbind_setdom *sd = argp;
+	struct sockaddr_in *fromsin, bindsin;
+	static bool_t res;
+
+	memset(&bindsin, 0, sizeof bindsin);
+	bindsin.sin_family = AF_INET;
+	bindsin.sin_len = sizeof(bindsin);
+	bcopy(&sd->ypsetdom_binding.ypbind_binding_addr,
+		&bindsin.sin_addr.s_addr, 4);
+	bcopy(&sd->ypsetdom_binding.ypbind_binding_port,
+		&bindsin.sin_port, 2);
+	fromsin = svc_getcaller(transp);
+
+	memset(&res, 0, sizeof(res));
+
+	switch (ypbindmode)
+	{
+		case YPBIND_SETLOCAL:
+			if (fromsin->sin_addr.s_addr != htonl(INADDR_LOOPBACK))
+			{
+				sys_msg(debug, LOG_ERR, "ypset from %s denied",
+					inet_ntoa(fromsin->sin_addr));
+				return NULL;
+			}
+
+		/* FALLTHROUGH */
+
+		case YPBIND_SETALL:
+			been_ypset = 1;
+			break;
+
+		case YPBIND_DIRECT:
+		case YPBIND_BROADCAST:
+		default:
+			sys_msg(debug, LOG_ERR, "ypset denied");
+			return NULL;
+	}
+
+	if (ntohs(fromsin->sin_port) >= IPPORT_RESERVED)
+	{
+		sys_msg(debug, LOG_ERR, "ypset from unpriviledged port denied");
+		return &res;
+	}
+
+	if (sd->ypsetdom_vers != YPVERS)
+	{
+		sys_msg(debug, LOG_ERR, "ypset with wrong version denied");
+		sys_msg(debug, LOG_DEBUG, "ypsetdom_vers = %lu   YPVERS = %lu",
+			sd->ypsetdom_vers, YPVERS);
+		return &res;
+	}
+
+	rpc_received(sd->ypsetdom_domain, &bindsin, 1);
+
+	sys_msg(debug, LOG_DEBUG, "ypset to %s succeeded",
+		inet_ntoa(bindsin.sin_addr));
+	res = 1;
+	return &res;
+}
+
+static void
+ypbindprog_2(struct svc_req *rqstp,	register SVCXPRT *transp)
+{
+	union
+	{
+		char ypbindproc_domain_2_arg[YPMAXDOMAIN + 1];
+		struct ypbind_setdom ypbindproc_setdom_2_arg;
+	} argument;
+	struct authunix_parms *creds;
+	char *result;
+	xdrproc_t xdr_argument, xdr_result;
+	void *(*local) __P((void *, SVCXPRT *));
+
+	switch (rqstp->rq_proc)
+	{
+		case YPBINDPROC_NULL:
+			xdr_argument = xdr_void;
+			xdr_result = xdr_void;
+			local = svc_ypbindproc_null_2;
+			break;
+
+		case YPBINDPROC_DOMAIN:
+			xdr_argument = xdr_domainname;
+			xdr_result = xdr_ypbind_resp;
+			local = svc_ypbindproc_domain_2;
+			break;
+
+		case YPBINDPROC_SETDOM:
+			switch (rqstp->rq_cred.oa_flavor)
+			{
+				case AUTH_UNIX:
+					creds = (struct authunix_parms *)rqstp->rq_clntcred;
+					if (creds->aup_uid != 0)
+					{
+						svcerr_auth(transp, AUTH_BADCRED);
+						return;
+					}
+					break;
+
+				default:
+					svcerr_auth(transp, AUTH_TOOWEAK);
+					return;
+			}
+
+			xdr_argument = xdr_ypbind_setdom;
+			xdr_result = xdr_void;
+			local = svc_ypbindproc_setdom_2;
+			break;
+
+		default:
+			svcerr_noproc(transp);
+			return;
+	}
+		
+	memset(&argument, 0, sizeof(argument));
+	if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument))
+	{
+		svcerr_decode(transp);
+		return;
+	}
+	
+	result = (*local)(&argument, transp);
+	if (result != NULL && !svc_sendreply(transp, xdr_result, result))
+	{
+		svcerr_systemerr(transp);
+	}
+
+	return;
+}
+
+int
+main(int argc, char *argv[])
+{
+	struct timeval tv;
+	fd_set fdsr;
+	int width, lockfd;
+	int evil = 0, one, i;
+	char pathname[MAXPATHLEN];
+	struct stat st;
+
+	yp_get_default_domain(&dname);
+	if (dname[0] == '\0')
+	{
+		fprintf(stderr, "Domainname not set. Aborting.\n");
+		exit(1);
+	}
+
+	debug = DEBUG_SYSLOG;
+	ypbindmode = YPBIND_DIRECT;
+	for (i = 1; i < argc; i++)
+	{
+		if (!strcmp(argv[i], "-insecure"))
+			insecure = 1;
+
+		else if (!strcmp(argv[i], "-ypset"))
+			ypbindmode = YPBIND_SETALL;
+
+		else if (!strcmp(argv[i], "-ypsetme"))
+			ypbindmode = YPBIND_SETLOCAL;
+
+		else if (!strcmp(argv[i], "-broadcast"))
+			ypbindmode = YPBIND_BROADCAST;
+
+		else if (!strcmp(argv[i], "-d"))
+			debug = DEBUG_STDERR;
+
+		else
+			usage();
+	}
+
+	sys_openlog(debug, "ypbind", LOG_NDELAY | LOG_PID, LOG_DAEMON);
+
+	/*
+	 * Per traditional ypbind(8) semantics, if a ypservers
+	 * file does not exist, we default to broadcast mode.
+	 * If the file does exist, we default to direct mode.
+	 * Note that we can still override direct mode by passing
+	 * the -broadcast flag.
+	 */
+	snprintf(pathname, sizeof(pathname), "%s/%s%s",
+		BINDINGDIR, dname, YPSERVERSSUFF);
+		
+	if ((ypbindmode == YPBIND_DIRECT) && (stat(pathname, &st) < 0))
+	{
+		sys_msg(debug, LOG_DEBUG, "%s does not exist, defaulting to broadcast.",
+			pathname);
+		ypbindmode = YPBIND_BROADCAST;
+	}
+	
+	/* blow away everything in BINDINGDIR */
+
+	lockfd = open(_PATH_YPBIND_LOCK, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644);
+	if (lockfd == -1)
+	{
+		sys_msg(debug, LOG_ERR, "Cannot create %s", _PATH_YPBIND_LOCK);
+		exit(1);
+	}
+
+#if O_SHLOCK == 0
+	flock(lockfd, LOCK_SH);
+#endif
+
+	pmap_unset(YPBINDPROG, YPBINDVERS);
+
+	udptransp = svcudp_create(RPC_ANYSOCK);
+	if (udptransp == NULL)
+	{
+		sys_msg(debug, LOG_ERR, "Cannot create udp service.");
+		exit(1);
+	}
+
+	if (!svc_register(udptransp, YPBINDPROG, YPBINDVERS, ypbindprog_2,
+	    IPPROTO_UDP))
+	{
+		sys_msg(debug, LOG_ERR,
+			"Unable to register (YPBINDPROG, YPBINDVERS, udp).");
+		exit(1);
+	}
+
+	tcptransp = svctcp_create(RPC_ANYSOCK, 0, 0);
+	if (tcptransp == NULL)
+	{
+		sys_msg(debug, LOG_ERR, "Cannot create tcp service.");
+		exit(1);
+	}
+
+	if (!svc_register(tcptransp, YPBINDPROG, YPBINDVERS, ypbindprog_2,
+	    IPPROTO_TCP))
+	{
+		sys_msg(debug, LOG_ERR,
+			"Unable to register (YPBINDPROG, YPBINDVERS, tcp).");
+		exit(1);
+	}
+
+	/* XXX use SOCK_STREAM for direct queries? */
+	rpcsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (rpcsock == -1)
+	{
+		sys_msg(debug, LOG_ERR, "rpc socket() failed.");
+		exit(1);
+	}
+
+	pingsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (pingsock == -1)
+	{
+		sys_msg(debug, LOG_ERR, "ping socket() failed.");
+		exit(1);
+	}
+	
+	fcntl(rpcsock, F_SETFL, fcntl(rpcsock, F_GETFL, 0) | FNDELAY);
+	fcntl(pingsock, F_SETFL, fcntl(pingsock, F_GETFL, 0) | FNDELAY);
+
+	one = 1;
+	setsockopt(rpcsock, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one));
+	rmtca.prog = YPPROG;
+	rmtca.vers = YPVERS;
+	rmtca.proc = YPPROC_DOMAIN_NONACK;
+	rmtca.xdr_args = NULL;		/* set at call time */
+	rmtca.args_ptr = NULL;		/* set at call time */
+	rmtcr.port_ptr = &rmtcr_port;
+	rmtcr.xdr_results = xdr_bool;
+	rmtcr.results_ptr = (caddr_t)&rmtcr_outval;
+
+	/* build initial domain binding, make it "unsuccessful" */
+	ypbindlist = makebinding(dname);
+	ypbindlist->dom_vers = YPVERS;
+	ypbindlist->dom_alive = 0;
+	ypbindlist->dom_lockfd = -1;
+	removelock(ypbindlist);
+
+	checkwork();
+
+//	width = svc_maxfd;
+	width = FD_SETSIZE;
+	width = 32;
+	if (rpcsock > width)
+		width = rpcsock;
+	if (pingsock > width)
+		width = pingsock;
+	width++;
+
+	for (;;)
+	{
+		fdsr = svc_fdset;
+		FD_SET(rpcsock, &fdsr);
+		FD_SET(pingsock, &fdsr);
+		tv.tv_sec = 1;
+		tv.tv_usec = 0;
+
+		switch (select(width, &fdsr, NULL, NULL, &tv))
+		{
+			case 0:
+				checkwork();
+				break;
+
+			case -1:
+				sys_msg(debug, LOG_WARNING, "select: %s", strerror(errno));
+				break;
+
+			default:
+				if (FD_ISSET(rpcsock, &fdsr)) handle_replies();
+				if (FD_ISSET(pingsock, &fdsr)) handle_ping();
+				svc_getreqset(&fdsr);
+				if (check) checkwork();
+				break;
+		}
+
+		if ((evil == 0) && (ypbindlist->dom_alive != 0))
+		{
+			evil = 1;
+			if (debug == DEBUG_SYSLOG) daemon(0, 0);
+		}
+	}
+}
+
+/*
+ * State transition is done like this: 
+ *
+ * STATE	EVENT		ACTION			NEWSTATE	TIMEOUT
+ * no binding	timeout		broadcast 		no binding	5 sec
+ * no binding	answer		--			binding		60 sec
+ * binding	timeout		ping server		checking	5 sec
+ * checking	timeout		ping server + broadcast	checking	5 sec
+ * checking	answer		--			binding		60 sec
+ */
+void
+checkwork()
+{
+	struct _dom_binding *ypdb;
+	time_t t;
+
+	check = 0;
+
+	time(&t);
+	for (ypdb = ypbindlist; ypdb; ypdb = ypdb->dom_pnext)
+	{
+		if (ypdb->dom_check_t < t)
+		{
+			if (ypdb->dom_alive == 1) ping(ypdb);
+			else nag_servers(ypdb);
+			time(&t);
+			ypdb->dom_check_t = t + 5;
+		}
+	}
+}
+
+int
+ping(struct _dom_binding *ypdb)
+{
+	char *dom = ypdb->dom_domain;
+	struct rpc_msg msg;
+	char buf[BUFSIZE];
+	enum clnt_stat st;
+	int outlen;
+	AUTH *rpcua;
+	XDR xdr;
+
+	memset(&xdr, 0, sizeof xdr);
+	memset(&msg, 0, sizeof msg);
+
+	rpcua = authunix_create_default();
+	if (rpcua == NULL)
+	{
+		sys_msg(debug, LOG_ERR, "ping: cannot get unix auth");
+		return RPC_SYSTEMERROR;
+	}
+
+	msg.rm_direction = CALL;
+	msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+	msg.rm_call.cb_prog = YPPROG;
+	msg.rm_call.cb_vers = YPVERS;
+	msg.rm_call.cb_proc = YPPROC_DOMAIN_NONACK;
+	msg.rm_call.cb_cred = rpcua->ah_cred;
+	msg.rm_call.cb_verf = rpcua->ah_verf;
+
+	msg.rm_xid = ypdb->dom_xid;
+	xdrmem_create(&xdr, buf, sizeof buf, XDR_ENCODE);
+	if (!xdr_callmsg(&xdr, &msg))
+	{
+		st = RPC_CANTENCODEARGS;
+		AUTH_DESTROY(rpcua);
+		return st;
+	}
+
+	if (!xdr_domainname(&xdr, (void *)&dom))
+	{
+		st = RPC_CANTENCODEARGS;
+		AUTH_DESTROY(rpcua);
+		return st;
+	}
+
+	outlen = (int)xdr_getpos(&xdr);
+	xdr_destroy(&xdr);
+	if (outlen < 1)
+	{
+		st = RPC_CANTENCODEARGS;
+		AUTH_DESTROY(rpcua);
+		return st;
+	}
+
+	AUTH_DESTROY(rpcua);
+
+	ypdb->dom_alive = 2;
+	if (sendto(pingsock, buf, outlen, 0, 
+		   (struct sockaddr *)&ypdb->dom_server_addr,
+		   sizeof ypdb->dom_server_addr) == -1)
+		sys_msg(debug, LOG_WARNING, "ping: sendto");
+	return 0;
+
+}
+
+static int
+nag_servers(struct _dom_binding *ypdb)
+{
+	char *dom = ypdb->dom_domain;
+	struct rpc_msg msg;
+	char buf[BUFSIZE];
+	enum clnt_stat st;
+	int outlen;
+	AUTH *rpcua;
+	XDR xdr;
+
+	rmtca.xdr_args = xdr_domainname;
+	rmtca.args_ptr = (char *)&dom;
+
+	memset(&xdr, 0, sizeof xdr);
+	memset(&msg, 0, sizeof msg);
+
+	rpcua = authunix_create_default();
+	if (rpcua == NULL)
+	{
+		sys_msg(debug, LOG_ERR, "ping: cannot get unix auth");
+		return RPC_SYSTEMERROR;
+	}
+
+	msg.rm_direction = CALL;
+	msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+	msg.rm_call.cb_prog = PMAPPROG;
+	msg.rm_call.cb_vers = PMAPVERS;
+	msg.rm_call.cb_proc = PMAPPROC_CALLIT;
+	msg.rm_call.cb_cred = rpcua->ah_cred;
+	msg.rm_call.cb_verf = rpcua->ah_verf;
+
+	msg.rm_xid = ypdb->dom_xid;
+	xdrmem_create(&xdr, buf, sizeof buf, XDR_ENCODE);
+	if (!xdr_callmsg(&xdr, &msg))
+	{
+		st = RPC_CANTENCODEARGS;
+		AUTH_DESTROY(rpcua);
+		return st;
+	}
+
+	if (!xdr_rmtcall_args(&xdr, &rmtca))
+	{
+		st = RPC_CANTENCODEARGS;
+		AUTH_DESTROY(rpcua);
+		return st;
+	}
+
+	outlen = (int)xdr_getpos(&xdr);
+	xdr_destroy(&xdr);
+	if (outlen < 1)
+	{
+		st = RPC_CANTENCODEARGS;
+		AUTH_DESTROY(rpcua);
+		return st;
+	}
+
+	AUTH_DESTROY(rpcua);
+
+	if (ypdb->dom_lockfd != -1)
+	{
+		close(ypdb->dom_lockfd);
+		ypdb->dom_lockfd = -1;
+		removelock(ypdb);
+	}
+
+	if (ypdb->dom_alive == 2)
+	{
+		/*
+		 * This resolves the following situation:
+		 * ypserver on other subnet was once bound,
+		 * but rebooted and is now using a different port
+		 */
+		struct sockaddr_in bindsin;
+
+		memset(&bindsin, 0, sizeof bindsin);
+		bindsin.sin_family = AF_INET;
+		bindsin.sin_len = sizeof(bindsin);
+		bindsin.sin_port = htons(PMAPPORT);
+		bindsin.sin_addr = ypdb->dom_server_addr.sin_addr;
+
+		if (sendto(rpcsock, buf, outlen, 0, (struct sockaddr *)&bindsin,
+			   sizeof bindsin) == -1)
+			sys_msg(debug, LOG_WARNING, "broadcast: sendto");
+	}
+
+	switch (ypbindmode)
+	{
+		case YPBIND_SETALL:
+		case YPBIND_SETLOCAL:
+			if (been_ypset) return direct_set(buf, outlen, ypdb);
+			/* FALLTHROUGH */
+
+		case YPBIND_BROADCAST:
+			return broadcast(buf, outlen);
+
+		case YPBIND_DIRECT:
+			return direct(buf, outlen);
+	}
+
+	return -1;
+}
+
+static int
+broadcast(char *buf, int outlen)
+{
+	struct ifconf ifc;
+	struct ifreq *ifr;
+	int offset, addrlen;
+	struct in_addr in;
+	int sock;
+	char inbuf[8192];
+	struct sockaddr_in bindsin;
+
+	/* find all networks and send the RPC packet out them all */
+	sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (sock == -1)
+	{
+		sys_msg(debug, LOG_WARNING, "broadcast: socket: %s", strerror(errno));
+		return -1;
+	}
+
+	memset(&bindsin, 0, sizeof bindsin);
+	bindsin.sin_family = AF_INET;
+	bindsin.sin_len = sizeof(bindsin);
+	bindsin.sin_port = htons(PMAPPORT);
+
+	ifc.ifc_len = sizeof inbuf;
+	ifc.ifc_buf = inbuf;
+	if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
+	{
+		close(sock);
+		sys_msg(debug, LOG_WARNING, "broadcast: ioctl(SIOCGIFCONF): %s",
+			strerror(errno));
+		return -1;
+	}
+
+	addrlen = sizeof(struct ifreq) - IFNAMSIZ;
+	offset = 0;
+
+	while (offset <= ifc.ifc_len)
+	{
+		ifr = (struct ifreq *)(ifc.ifc_buf + offset);
+		offset += IFNAMSIZ;
+		if (ifr->ifr_addr.sa_len > addrlen) offset += ifr->ifr_addr.sa_len;
+		else offset += addrlen;
+
+		if (ifr->ifr_addr.sa_family != AF_INET) continue;
+		if (ioctl(sock, SIOCGIFFLAGS, ifr) < 0) continue;
+		if ((ifr->ifr_flags & IFF_UP) == 0) continue;
+
+		if (ifr->ifr_flags & IFF_BROADCAST)
+		{
+			if (ioctl(sock, SIOCGIFBRDADDR, ifr) < 0)
+			{
+				sys_msg(debug, LOG_WARNING,
+					"broadcast: ioctl(SIOCGIFBRDADDR): %s", strerror(errno));
+				continue;
+			}
+		}
+		else if (ifr->ifr_flags & IFF_LOOPBACK)
+		{
+			if (ioctl(sock, SIOCGIFADDR, ifr) < 0)
+			{
+				sys_msg(debug, LOG_WARNING,
+					"broadcast: ioctl(SIOCGIFADDR): %s", strerror(errno));
+				continue;
+			}
+		}
+		else continue;
+
+		in = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr;
+		bindsin.sin_addr = in;
+		if (sendto(rpcsock, buf, outlen, 0, (struct sockaddr *)&bindsin,
+			   sizeof bindsin) == -1)
+			sys_msg(debug, LOG_WARNING, "broadcast: sendto: %s",
+				strerror(errno));
+	}
+
+	close(sock);
+	return 0;
+}
+
+static int
+direct(char *buf, int outlen)
+{
+	static FILE *df;
+	static char ypservers_path[MAXPATHLEN];
+	char line[_POSIX2_LINE_MAX];
+	char *p;
+	struct hostent *hp;
+	struct sockaddr_in bindsin;
+	int i, count = 0;
+
+	if (df) rewind(df);
+	else {
+		snprintf(ypservers_path, sizeof(ypservers_path),
+		    "%s/%s%s", BINDINGDIR, dname, YPSERVERSSUFF);
+		df = fopen(ypservers_path, "r");
+		if (df == NULL)
+		{
+			sys_msg(debug, LOG_ALERT, "Missing file %s, aborting.",
+				ypservers_path);
+			exit(1);
+		}
+	}
+
+	memset(&bindsin, 0, sizeof bindsin);
+	bindsin.sin_family = AF_INET;
+	bindsin.sin_len = sizeof(bindsin);
+	bindsin.sin_port = htons(PMAPPORT);
+
+	while(fgets(line, sizeof(line), df) != NULL)
+	{
+		/* skip lines that are too big */
+		p = strchr(line, '\n');
+		if (p == NULL)
+		{
+			int c;
+
+			while ((c = getc(df)) != '\n' && c != EOF);
+			continue;
+		}
+
+		*p = '\0';
+		p = line;
+		while (isspace(*p)) p++;
+		if (*p == '#') continue;
+		hp = gethostbyname(p);
+		if (hp == NULL)
+		{
+			sys_msg(debug, LOG_ERR, "Can't find host: %s", p);
+			continue;
+		}
+	
+		/* step through all addresses in case first is unavailable */
+		for (i = 0; hp->h_addr_list[i]; i++)
+		{
+			memmove(&bindsin.sin_addr, hp->h_addr_list[0],
+			    hp->h_length);
+			if (sendto(rpcsock, buf, outlen, 0,
+			    (struct sockaddr *)&bindsin, sizeof bindsin) < 0)
+			{
+				sys_msg(debug, LOG_WARNING, "direct: sendto: %s",
+					strerror(errno));
+				continue;
+			}
+			else count++;
+		}
+	}
+	
+	if (count == 0)
+	{
+		sys_msg(debug, LOG_ALERT,
+			"Can't contact any servers listed in %s.  Aborting", ypservers_path);
+		exit(1);
+	}
+
+	return 0;
+}
+
+static int
+direct_set(char *buf, int outlen, struct _dom_binding *ypdb)
+{
+	struct sockaddr_in bindsin;
+	char path[MAXPATHLEN];
+	struct iovec iov[2];
+	struct ypbind_resp ybr;
+	SVCXPRT dummy_svc;
+	int fd, bytes;
+
+	/*
+	 * Gack, we lose if binding file went away.  We reset
+	 * "been_set" if this happens, otherwise we'll never
+	 * bind again.
+	 */
+	snprintf(path, sizeof(path), "%s/%s.%ld", BINDINGDIR,
+	    ypdb->dom_domain, ypdb->dom_vers);
+
+	if ((fd = open(path, O_SHLOCK|O_RDONLY, 0644)) == -1)
+	{
+		sys_msg(debug, LOG_WARNING, "Can't open file %s", path);
+		been_ypset = 0;
+		return -1;
+	}
+
+#if O_SHLOCK == 0
+	flock(fd, LOCK_SH);
+#endif
+
+	/* Read the binding file... */
+	iov[0].iov_base = (caddr_t)&(dummy_svc.xp_port);
+	iov[0].iov_len = sizeof(dummy_svc.xp_port);
+	iov[1].iov_base = (caddr_t)&ybr;
+	iov[1].iov_len = sizeof(ybr);
+	bytes = readv(fd, iov, 2);
+	close(fd);
+
+	if (bytes != (iov[0].iov_len + iov[1].iov_len))
+	{
+		/* Binding file corrupt? */
+		sys_msg(debug, LOG_WARNING, "Can't parse file %s", path);
+		been_ypset = 0;
+		return -1;
+	}
+
+	bcopy(&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
+		&bindsin.sin_addr, 4);
+
+	if (sendto(rpcsock, buf, outlen, 0, (struct sockaddr *)&bindsin,
+	    sizeof(bindsin)) < 0)
+	{
+		sys_msg(debug, LOG_WARNING, "direct_set: sendto: %s", strerror(errno));
+		return -1;
+	}
+
+	return 0;
+}
+
+static enum clnt_stat
+handle_replies()
+{
+	char buf[BUFSIZE];
+	int fromlen, inlen;
+	struct _dom_binding *ypdb;
+	struct sockaddr_in raddr;
+	struct rpc_msg msg;
+	XDR xdr;
+
+recv_again:
+	memset(&xdr, 0, sizeof(xdr));
+	memset(&msg, 0, sizeof(msg));
+	msg.acpted_rply.ar_verf = _null_auth;
+	msg.acpted_rply.ar_results.where = (caddr_t)&rmtcr;
+	msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
+
+try_again:
+	fromlen = sizeof (struct sockaddr);
+	inlen = recvfrom(rpcsock, buf, sizeof buf, 0,
+		(struct sockaddr *)&raddr, &fromlen);
+	if (inlen < 0)
+	{
+		if (errno == EINTR) goto try_again;
+		return RPC_CANTRECV;
+	}
+
+	if (inlen < sizeof(u_int32_t)) goto recv_again;
+
+	/*
+	 * see if reply transaction id matches sent id.
+	 * If so, decode the results.
+	 */
+	xdrmem_create(&xdr, buf, (u_int)inlen, XDR_DECODE);
+	if (xdr_replymsg(&xdr, &msg))
+	{
+		if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
+		    (msg.acpted_rply.ar_stat == SUCCESS)) {
+			raddr.sin_port = htons((u_short)rmtcr_port);
+			ypdb = xid2ypdb(msg.rm_xid);
+			if (ypdb != NULL) rpc_received(ypdb->dom_domain, &raddr, 0);
+		}
+	}
+
+	xdr.x_op = XDR_FREE;
+	msg.acpted_rply.ar_results.proc = xdr_void;
+	xdr_destroy(&xdr);
+
+	return RPC_SUCCESS;
+}
+
+static enum clnt_stat
+handle_ping()
+{
+	char buf[BUFSIZE];
+	int fromlen, inlen;
+	struct _dom_binding *ypdb;
+	struct sockaddr_in raddr;
+	struct rpc_msg msg;
+	XDR xdr;
+	bool_t res;
+
+recv_again:
+	memset(&xdr, 0, sizeof(xdr));
+	memset(&msg, 0, sizeof(msg));
+	msg.acpted_rply.ar_verf = _null_auth;
+	msg.acpted_rply.ar_results.where = (caddr_t)&res;
+	msg.acpted_rply.ar_results.proc = xdr_bool;
+
+try_again:
+	fromlen = sizeof (struct sockaddr);
+	inlen = recvfrom(pingsock, buf, sizeof buf, 0,
+		(struct sockaddr *)&raddr, &fromlen);
+	if (inlen < 0)
+	{
+		if (errno == EINTR) goto try_again;
+		return RPC_CANTRECV;
+	}
+
+	if (inlen < sizeof(u_int32_t)) goto recv_again;
+
+	/*
+	 * see if reply transaction id matches sent id.
+	 * If so, decode the results.
+	 */
+	xdrmem_create(&xdr, buf, (u_int)inlen, XDR_DECODE);
+	if (xdr_replymsg(&xdr, &msg))
+	{
+		if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
+		    (msg.acpted_rply.ar_stat == SUCCESS))
+		{
+			ypdb = xid2ypdb(msg.rm_xid);
+			if (ypdb != NULL) rpc_received(ypdb->dom_domain, &raddr, 0);
+		}
+	}
+
+	xdr.x_op = XDR_FREE;
+	msg.acpted_rply.ar_results.proc = xdr_void;
+	xdr_destroy(&xdr);
+
+	return RPC_SUCCESS;
+}
+
+/*
+ * LOOPBACK IS MORE IMPORTANT: PUT IN HACK
+ */
+void
+rpc_received(char *dom, struct sockaddr_in *raddrp, int force)
+{
+	struct _dom_binding *ypdb;
+	struct iovec iov[2];
+	struct ypbind_resp ybr;
+	int fd;
+
+	sys_msg(debug, LOG_DEBUG, "returned from %s about %s",
+		inet_ntoa(raddrp->sin_addr), dom);
+
+	if (dom == NULL) return;
+
+	/* don't support insecure servers by default */
+	if (!insecure && ntohs(raddrp->sin_port) >= IPPORT_RESERVED) return;
+
+	for (ypdb = ypbindlist; ypdb; ypdb = ypdb->dom_pnext)
+	{
+		if (!strcmp(ypdb->dom_domain, dom)) break;
+	}
+
+	if (ypdb == NULL)
+	{
+		if (force == 0) return;
+		ypdb = makebinding(dom);
+		ypdb->dom_lockfd = -1;
+		ypdb->dom_pnext = ypbindlist;
+		ypbindlist = ypdb;
+	}
+
+	/* soft update, alive */
+	if (ypdb->dom_alive == 1 && force == 0)
+	{
+		if (!memcmp(&ypdb->dom_server_addr, raddrp,
+			sizeof ypdb->dom_server_addr))
+		{
+			ypdb->dom_alive = 1;
+			/* recheck binding in 60 sec */
+			ypdb->dom_check_t = time(NULL) + 60;
+		}
+		return;
+	}
+	
+	memcpy(&ypdb->dom_server_addr, raddrp, sizeof ypdb->dom_server_addr);
+	/* recheck binding in 60 seconds */
+	ypdb->dom_check_t = time(NULL) + 60;
+	ypdb->dom_vers = YPVERS;
+	ypdb->dom_alive = 1;
+
+	if (ypdb->dom_lockfd != -1) close(ypdb->dom_lockfd);
+
+	if ((fd = makelock(ypdb)) == -1) return;
+
+	/*
+	 * ok, if BINDINGDIR exists, and we can create the binding file,
+	 * then write to it..
+	 */
+	ypdb->dom_lockfd = fd;
+
+	iov[0].iov_base = (caddr_t)&(udptransp->xp_port);
+	iov[0].iov_len = sizeof udptransp->xp_port;
+	iov[1].iov_base = (caddr_t)&ybr;
+	iov[1].iov_len = sizeof ybr;
+
+	memset(&ybr, 0, sizeof ybr);
+	ybr.ypbind_status = YPBIND_SUCC_VAL;
+	bcopy(&raddrp->sin_addr.s_addr,
+		ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr, 4);
+	bcopy(&raddrp->sin_port,
+		ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port, 2);
+	
+	if (writev(ypdb->dom_lockfd, iov, 2) !=
+	    iov[0].iov_len + iov[1].iov_len)
+	{
+		sys_msg(debug, LOG_WARNING, "writev: %s", strerror(errno));
+		close(ypdb->dom_lockfd);
+		removelock(ypdb);
+		ypdb->dom_lockfd = -1;
+	}
+}
+
+static struct _dom_binding *
+xid2ypdb(u_int32_t xid)
+{
+	struct _dom_binding *ypdb;
+
+	for (ypdb = ypbindlist; ypdb; ypdb = ypdb->dom_pnext)
+	{
+		if (ypdb->dom_xid == xid) break;
+	}
+
+	return (ypdb);
+}
+
+static u_int32_t
+unique_xid(struct _dom_binding *ypdb)
+{
+	u_int32_t tmp_xid;
+
+	tmp_xid = (u_int32_t)(((u_long)ypdb) & 0xffffffff);
+	while (xid2ypdb(tmp_xid) != NULL) tmp_xid++;
+
+	return tmp_xid;
+}
diff --git a/ypcat.tproj/Makefile b/ypcat.tproj/Makefile
new file mode 100644
index 0000000..e3a8242
--- /dev/null
+++ b/ypcat.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ypcat
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = ypcat.c
+
+OTHERSRCS = Makefile.dist Makefile.preamble ypcat.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ypcat.tproj/Makefile.dist b/ypcat.tproj/Makefile.dist
new file mode 100644
index 0000000..55b8f72
--- /dev/null
+++ b/ypcat.tproj/Makefile.dist
@@ -0,0 +1,6 @@
+#	from: @(#)Makefile	5.8 (Berkeley) 7/28/90
+#	$Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:59:01 wsanchez Exp $
+
+PROG=	ypcat
+
+.include <bsd.prog.mk>
diff --git a/ypcat.tproj/Makefile.preamble b/ypcat.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/ypcat.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/ypcat.tproj/PB.project b/ypcat.tproj/PB.project
new file mode 100644
index 0000000..fc90efc
--- /dev/null
+++ b/ypcat.tproj/PB.project
@@ -0,0 +1,36 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LINKED = (ypcat.c); 
+        OTHER_SOURCES = (Makefile.dist, Makefile.preamble, ypcat.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ypcat; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ypcat.tproj/ypcat.1 b/ypcat.tproj/ypcat.1
new file mode 100644
index 0000000..529b3ee
--- /dev/null
+++ b/ypcat.tproj/ypcat.1
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1993 Winning Strategies, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"      This product includes software developed by Winning Strategies, Inc.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\"	$Id: ypcat.1,v 1.1.1.1 1999/05/02 03:59:01 wsanchez Exp $
+.\"
+.Dd December 3, 1993
+.Dt YPCAT 1
+.Os
+.Sh NAME
+.Nm ypcat
+.Nd "print the values of all keys in a YP database"
+.Sh SYNOPSIS
+.Nm ypcat
+.Op Fl kt
+.Op Fl d Ar domainname
+.Ar mapname
+.Nm ypcat 
+.Fl x
+.Sh DESCRIPTION
+.Nm Ypcat
+prints out the values of all keys from the 
+.Tn YP
+database specified by
+.Ar mapname,
+which may be a map name or a map nickname.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl d Ar domainname
+Specify a domain other than the default domain.
+.It Fl k
+Display map keys.
+This option is useful with maps in which the values are null or the key
+is not part of the value.
+.It Fl t
+Inhibit translation of map nicknames
+to their corresponding map names.
+.It Fl x
+Display the map nickname table.
+.El
+.Sh SEE ALSO
+.Xr ypmatch 1 ,
+.Xr yp 8
+.Sh AUTHOR
+Theo De Raadt
diff --git a/ypcat.tproj/ypcat.c b/ypcat.tproj/ypcat.c
new file mode 100644
index 0000000..72e4e45
--- /dev/null
+++ b/ypcat.tproj/ypcat.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$Id: ypcat.c,v 1.1.1.1 1999/05/02 03:59:01 wsanchez Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+
+struct ypalias {
+	char *alias, *name;
+} ypaliases[] = {
+	{ "passwd", "passwd.byname" },
+	{ "group", "group.byname" },
+	{ "networks", "networks.byaddr" },
+	{ "hosts", "hosts.byaddr" },
+	{ "protocols", "protocols.bynumber" },
+	{ "services", "services.byname" },
+	{ "aliases", "mail.aliases" },
+	{ "ethers", "ethers.byname" },
+};
+
+int key;
+
+usage()
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\typcat [-k] [-d domainname] [-t] mapname\n");
+	fprintf(stderr, "\typcat -x\n");
+	exit(1);
+}
+
+printit(instatus, inkey, inkeylen, inval, invallen, indata)
+int instatus;
+char *inkey;
+int inkeylen;
+char *inval;
+int invallen;
+char *indata;
+{
+	if(instatus != YP_TRUE)
+		return instatus;
+	if(key)
+		printf("%*.*s ", inkeylen, inkeylen, inkey);
+	printf("%*.*s\n", invallen, invallen, inval);
+	return 0;
+}
+
+int
+main(argc, argv)
+char **argv;
+{
+	char *domainname;
+	struct ypall_callback ypcb;
+	char *inmap;
+	extern char *optarg;
+	extern int optind;
+	int notrans;
+	int c, r, i;
+
+	notrans = key = 0;
+	yp_get_default_domain(&domainname);
+
+	while( (c=getopt(argc, argv, "xd:kt")) != -1)
+		switch(c) {
+		case 'x':
+			for(i=0; i<sizeof ypaliases/sizeof ypaliases[0]; i++)
+				printf("Use \"%s\" for \"%s\"\n",
+					ypaliases[i].alias,
+					ypaliases[i].name);
+			exit(0);
+		case 'd':
+			domainname = optarg;
+			break;
+		case 't':
+			notrans++;
+			break;
+		case 'k':
+			key++;
+			break;
+		default:
+			usage();
+		}
+
+	if(optind + 1 != argc )
+		usage();
+
+	inmap = argv[optind];
+	for(i=0; (!notrans) && i<sizeof ypaliases/sizeof ypaliases[0]; i++)
+		if( strcmp(inmap, ypaliases[i].alias) == 0)
+			inmap = ypaliases[i].name;
+	ypcb.foreach = printit;
+	ypcb.data = NULL;
+
+	r = yp_all(domainname, inmap, &ypcb);
+	switch(r) {
+	case 0:
+		break;
+	case YPERR_YPBIND:
+		fprintf(stderr, "ypcat: not running ypbind\n");
+		exit(1);
+	default:
+		fprintf(stderr, "No such map %s. Reason: %s\n",
+			inmap, yperr_string(r));
+		exit(1);
+	}
+	exit(0);
+}
diff --git a/ypinit.tproj/Makefile b/ypinit.tproj/Makefile
new file mode 100644
index 0000000..4720077
--- /dev/null
+++ b/ypinit.tproj/Makefile
@@ -0,0 +1,46 @@
+#
+# RC Makefile for ypinit scripts on Rhapsody.
+#
+# $Id: Makefile,v 1.1.1.1 1999/05/02 03:59:01 wsanchez Exp $
+#
+
+VARYP=$(DSTROOT)/private/var/yp
+USRSBIN=$(DSTROOT)/usr/sbin
+
+PROJECT=ypinit.tproj
+
+.PHONY: all install installhdrs installsrc build clean recurse
+
+all: build
+
+##
+# Targets
+##
+	
+build: build_init
+
+build_init:
+	@echo "Building $(PROJECT)..."
+
+installsrc:
+	-mkdir -p $(SRCROOT)$(SRCPATH)
+	cp Makefile Makefile.yp Makefile.main ypinit.sh $(SRCROOT)$(SRCPATH)
+
+installhdrs:
+
+clean:
+
+install: install_makefiles install_binaries
+
+install_makefiles:
+	-mkdir -p $(VARYP)
+	install -c -m 644 Makefile.yp $(VARYP)
+	-chown root.wheel $(VARYP)/Makefile.yp
+	install -c -m 644 Makefile.main $(VARYP)
+	-chown root.wheel $(VARYP)/Makefile.main
+	
+install_binaries:
+	-mkdir -p $(USRSBIN)
+	install -c -m 755 ypinit.sh $(USRSBIN)
+	-chown root.wheel $(USRSBIN)/ypinit
+
diff --git a/ypinit.tproj/Makefile.main b/ypinit.tproj/Makefile.main
new file mode 100644
index 0000000..f691cd8
--- /dev/null
+++ b/ypinit.tproj/Makefile.main
@@ -0,0 +1,6 @@
+
+SUBDIR=	
+
+all:
+	cd $(SUBDIR) && make all
+
diff --git a/ypinit.tproj/Makefile.yp b/ypinit.tproj/Makefile.yp
new file mode 100644
index 0000000..bed83a7
--- /dev/null
+++ b/ypinit.tproj/Makefile.yp
@@ -0,0 +1,327 @@
+YPDBDIR=/private/var/yp
+DIR=/etc
+AMDDIR=/etc/amd
+NOPUSH=""
+#
+AWK=/usr/bin/awk
+CAT=/bin/cat
+CP=/bin/cp
+RM=/bin/rm
+CUT=/usr/bin/cut
+ECHO=/bin/echo
+MAKEDBM=/usr/sbin/makedbm
+SED=/usr/bin/sed
+SENDMAIL=/usr/sbin/sendmail
+STDHOSTS=/usr/sbin/stdhosts
+STDETHERS=/usr/sbin/stdethers
+MKALIAS=/usr/sbin/mkalias
+MKNETID=/usr/sbin/mknetid
+REVNETGROUP=/usr/sbin/revnetgroup
+TOUCH=/usr/bin/touch
+PWD:=$(shell /bin/pwd)
+DOMAIN:=$(shell /usr/bin/basename $(PWD))
+YPPUSH=/usr/sbin/yppush
+
+# Password maps in standard YP is unsecure. This is due to the fact that
+# passwords are accessable for anyone.
+# As a solution, maps can be secure (makedbm -s). If a map is secure only
+# a privileged user can access it.
+MAKEDBM-S=$(MAKEDBM) -s
+UNSECURE="True"
+
+all: passwd group hosts ethers networks rpc services protocols netid netgroup aliases
+
+passwd.time: $(DIR)/master.passwd
+	-@if [ -f $(>) ]; then \
+		if [ ! $(UNSECURE) ]; then \
+			$(CAT) $(>) | $(CUT) -d: -f1-4,8-10 | \
+			$(AWK) 'BEGIN { FS=":"; OFS="\t"; } /^[a-zA-Z0-9_]/ \
+			{ print $$1, $$1":*:"$$3":"$$4":"$$5":"$$6":"$$7 }' -|\
+			$(MAKEDBM) - passwd.byname; \
+			$(CAT) $(>) | $(CUT) -d: -f1-4,8-10 |\
+			$(AWK) 'BEGIN { FS=":"; OFS="\t"; } /^[a-zA-Z0-9_]/ \
+			{ print $$3, $$1":*:"$$3":"$$4":"$$5":"$$6":"$$7 }' -|\
+			$(MAKEDBM) - passwd.byuid; \
+		else \
+			$(CAT) $(>) | $(CUT) -d: -f1-4,8-10 | \
+			$(AWK) 'BEGIN { FS=":"; OFS="\t"; } /^[a-zA-Z0-9_]/ \
+			{ print $$1, $$0 }' - | $(MAKEDBM) - passwd.byname; \
+			$(CAT) $(>) | $(CUT) -d: -f1-4,8-10 |\
+			$(AWK) 'BEGIN { FS=":"; OFS="\t"; } /^[a-zA-Z0-9_]/ \
+			{ print $$3, $$0 }' - | $(MAKEDBM) - passwd.byuid; \
+		fi; \
+		$(CAT) $(>) | \
+		$(AWK) 'BEGIN { FS=":"; OFS="\t"; } /^[a-zA-Z0-9_]/ \
+		{ print $$1, $$0 }' - | $(MAKEDBM-S) - master.passwd.byname; \
+		$(CAT) $(>) | \
+		$(AWK) 'BEGIN { FS=":"; OFS="\t"; } /^[a-zA-Z0-9_]/ \
+		{ print $$3, $$0 }' - | $(MAKEDBM-S) - master.passwd.byuid; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated passwd"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) passwd.byname; \
+			$(YPPUSH) -d $(DOMAIN) passwd.byuid; \
+			$(YPPUSH) -d $(DOMAIN) master.passwd.byname; \
+			$(YPPUSH) -d $(DOMAIN) master.passwd.byuid; \
+			$(ECHO) "pushed passwd"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+
+group.time: $(DIR)/group
+	-@if [ -f $(>) ]; then \
+		$(AWK) 'BEGIN { FS=":"; OFS="\t"; } /^[a-zA-Z0-9_]/ \
+		{ print $$1, $$0 }' $(>) | \
+		$(MAKEDBM) - group.byname; \
+		$(AWK) 'BEGIN { FS=":"; OFS="\t"; } /^[a-zA-Z0-9_]/ \
+		{ print $$3, $$0 }' $(>) | \
+		$(MAKEDBM) - group.bygid; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated group"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) group.byname; \
+			$(YPPUSH) -d $(DOMAIN) group.bygid; \
+			$(ECHO) "pushed group"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+hosts.time: $(DIR)/hosts
+	-@if [ -f $(DIR)/hosts ]; then \
+		$(STDHOSTS) $(>) | $(SED) -e s/#.*$$// | \
+		$(AWK) '{for (i = 2; i <= NF; i++) print $$i, $$0 }' | \
+		$(MAKEDBM) - hosts.byname; \
+		$(STDHOSTS) $(>) | \
+		$(AWK) 'BEGIN { OFS="\t"; } { print $$1, $$0 }' | \
+		$(MAKEDBM) - hosts.byaddr; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated hosts"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) hosts.byname; \
+			$(YPPUSH) -d $(DOMAIN) hosts.byaddr; \
+			$(ECHO) "pushed hosts"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+ethers.time: $(DIR)/ethers
+	-@if [ -f $(DIR)/ethers ]; then \
+		$(STDETHERS) $(>) | $(SED) -e s/#.*$$// | \
+		$(AWK) 'BEGIN { FS="\t"; OFS="\t"; } { print $$1, $$0 }' | \
+		$(MAKEDBM) - ethers.byaddr; \
+		$(STDETHERS) $(>) | \
+		$(AWK) 'BEGIN { FS="\t"; OFS="\t"; } { print $$2, $$0 }' | \
+		$(MAKEDBM) - ethers.byname; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated ethers"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) ethers.byaddr; \
+			$(YPPUSH) -d $(DOMAIN) ethers.byname; \
+			$(ECHO) "pushed ethers"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+networks.time: $(DIR)/networks
+	-@if [ -f $(>) ]; then \
+		$(SED) -e "/^#/d" -e s/#.*$$// $(>) | \
+		$(AWK) '{print $$1, $$0; for (i = 3;i <= NF;i++) print $$i,$$0}' | \
+		$(MAKEDBM) - networks.byname; \
+		$(AWK) 'BEGIN { OFS="\t"; } $$1 !~ /^#/ { print $$2, $$0 }' $(>) | \
+		$(MAKEDBM) - networks.byaddr; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated networks"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) networks.byname; \
+			$(YPPUSH) -d $(DOMAIN) networks.byaddr; \
+			$(ECHO) "pushed networks"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+rpc.time: $(DIR)/rpc
+	-@if [ -f $(>) ]; then \
+		$(AWK) 'BEGIN { OFS="\t"; } $$1 !~ /^#/ { print $$2, $$0 }' $(>) | \
+		$(MAKEDBM) - rpc.bynumber; \
+		$(SED) -e "/^#/d" -e s/#.*$$// $(>) | \
+		$(AWK) '{print $$1, $$0; for (i = 3;i <= NF;i++) print $$i,$$0}' | \
+		$(MAKEDBM) - rpc.byname; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated rpc"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) rpc.bynumber; \
+			$(YPPUSH) -d $(DOMAIN) rpc.byname; \
+			$(ECHO) "pushed rpc"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+
+services.time: $(DIR)/services
+	-@if [ -f $(>) ]; then \
+		$(AWK) 'BEGIN { OFS="\t"; } $$1 !~ /^#/ { print $$2, $$0 }' $(>) | \
+		$(MAKEDBM) - services.byname; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated services"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) services.byname; \
+			$(ECHO) "pushed services"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+
+protocols.time: $(DIR)/protocols
+	-@if [ -f $(>) ]; then \
+		$(AWK) 'BEGIN { OFS="\t"; } $$1 !~ /^#/ { print $$2, $$0 }' $(>) | \
+		$(MAKEDBM) - protocols.bynumber; \
+		$(SED) -e "/^#/d" -e s/#.*$$// $(>) | \
+		$(AWK) '{print $$1, $$0; for (i = 3;i <= NF;i++) print $$i,$$0}' | \
+		$(MAKEDBM) - protocols.byname; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated protocols"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) protocols.bynumber; \
+			$(YPPUSH) -d $(DOMAIN) protocols.byname; \
+			$(ECHO) "pushed protocols"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+
+netid.time: $(DIR)/passwd $(DIR)/group $(DIR)/hosts $(DIR)/netid
+	-@$(MKNETID) -q -d $(DOMAIN) -p $(DIR)/passwd -g $(DIR)/group -h $(DIR)/hosts -m $(DIR)/netid | \
+	  $(MAKEDBM) - netid.byname; \
+	  $(TOUCH) $(@); \
+	  $(ECHO) "updated netid"; \
+	  if [ ! $(NOPUSH) ]; then \
+		$(YPPUSH) -d $(DOMAIN) netid.byname; \
+		$(ECHO) "pushed netid"; \
+	  else \
+		: ; \
+	  fi
+
+
+netgroup.time: $(DIR)/netgroup
+	-@if [ -f $(>) ]; then \
+		$(CAT) $(>) | $(MAKEDBM) - netgroup; \
+		$(CAT) $(>) | $(REVNETGROUP) -u -f - | \
+		$(MAKEDBM) - netgroup.byuser; \
+		$(CAT) $(>) | $(REVNETGROUP) -h -f - | \
+		$(MAKEDBM) - netgroup.byhost; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated netgroup"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) netgroup; \
+			$(YPPUSH) -d $(DOMAIN) netgroup.byuser; \
+			$(YPPUSH) -d $(DOMAIN) netgroup.byhost; \
+			$(ECHO) "pushed netgroup"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+
+amd.home.time: $(AMDDIR)/amd.home
+	-@if [ -f $(>) ]; then \
+		$(SED) -e "s/#.*$$//" -e "/^$$/d" $(>) | \
+		$(AWK) '{ \
+			    for (i = 1; i <= NF; i++) \
+				if (i == NF) { \
+				    if (substr($$i, length($$i), 1) == "\\") { \
+					printf("%s", substr($$i, 1, length($$i) - 1)); \
+				    } \
+				    else \
+					printf("%s\n", $$i); \
+				} \
+				else \
+				    printf("%s ", $$i); \
+			}' | \
+		$(MAKEDBM) - amd.home; \
+		$(TOUCH) $(@); \
+		$(ECHO) "updated amd.home"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) amd.home; \
+			$(ECHO) "pushed amd.home"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+
+aliases.time: $(DIR)/aliases
+	-@if [ -f $(>) ]; then \
+		$(CP) -p $(>) $(DOMAIN)-aliases; \
+		$(SENDMAIL) -bi -oA$(PWD)/$(DOMAIN)-aliases; \
+		$(MAKEDBM) -U $(DOMAIN)-aliases | $(MAKEDBM) - mail.aliases; \
+		$(MKALIAS) mail.aliases mail.byaddr; \
+		$(TOUCH) $(@); \
+		$(RM) $(DOMAIN)-aliases.db $(DOMAIN)-aliases; \
+		$(ECHO) "updated aliases"; \
+		if [ ! $(NOPUSH) ]; then \
+			$(YPPUSH) -d $(DOMAIN) mail.aliases; \
+			$(YPPUSH) -d $(DOMAIN) mail.byaddr; \
+			$(ECHO) "pushed aliases"; \
+		else \
+			: ; \
+		fi \
+	else \
+		$(ECHO) "couldn't find $(>)"; \
+	fi
+
+
+
+passwd: passwd.time
+group: group.time
+hosts: hosts.time
+ethers: ethers.time
+networks: networks.time
+rpc: rpc.time
+services: services.time
+protocols: protocols.time
+netid: netid.time
+netgroup: netgroup.time
+amd.home: amd.home.time
+aliases: aliases.time
+$(DIR)/passwd:
+$(DIR)/group:
+$(DIR)/hosts:
+$(DIR)/ethers:
+$(DIR)/networks:
+$(DIR)/rpc:
+$(DIR)/services:
+$(DIR)/protocols:
+$(DIR)/netid:
+$(DIR)/master.passwd:
+$(DIR)/netgroup:
+$(DIR)/aliases:
+$(AMDDIR)/amd.home:
diff --git a/ypinit.tproj/ypinit.sh b/ypinit.tproj/ypinit.sh
new file mode 100644
index 0000000..8c21e36
--- /dev/null
+++ b/ypinit.tproj/ypinit.sh
@@ -0,0 +1,402 @@
+#!/bin/sh
+#	$Id: ypinit.sh,v 1.1.1.1 1999/05/02 03:59:02 wsanchez Exp $
+#
+# ypinit.sh - setup an master or slave server.
+#
+DOMAINNAME=/bin/domainname
+HOSTNAME=/bin/hostname
+YPWHICH=/usr/bin/ypwhich
+YPXFR=/usr/sbin/ypxfr
+YP_DIR=/var/yp
+MAKEDBM=/usr/sbin/makedbm
+ERROR_EXISTS="NO"
+MAKE=make
+umask 077
+
+#set -xv
+
+ERROR=USAGE				# assume usage error
+
+if [ $# -eq 1 ]
+then
+	if [ $1 = "-m" ]		# ypinit -m
+	then
+		DOMAIN=`${DOMAINNAME}`
+		SERVERTYPE=MASTER
+		ERROR=
+	fi
+
+	if [ $1 = "-u" ]		# ypinit -u
+	then
+		DOMAIN=`${DOMAINNAME}`
+		SERVERTYPE=UPDATE
+		ERROR=
+	fi
+fi
+
+if [ $# -eq 2 ]
+then
+	if [ $1 = "-m" ]		# ypinit -m domainname
+	then
+		DOMAIN=${2}
+		SERVERTYPE=MASTER
+		ERROR=
+	fi
+
+	if [ $1 = "-s" ]		# ypinit -s master_server
+	then
+		DOMAIN=`${DOMAINNAME}`
+		SERVERTYPE=SLAVE
+		MASTER=${2}
+		ERROR=
+	fi
+
+	if [ $1 = "-u" ]		# ypinit -u domainname
+	then
+		DOMAIN=${2}
+		SERVERTYPE=UPDATE
+		ERROR=
+	fi
+fi
+
+if [ $# -eq 3 ]
+then
+	if [ $1 = "-s" ]		# ypinit -s master_server domainname
+	then
+		DOMAIN=${3}
+		SERVERTYPE=SLAVE
+		MASTER=${2}
+		ERROR=
+	fi
+fi
+
+if [ "${ERROR}" = "USAGE" ]; then
+	cat << \__usage 1>&2
+usage: ypinit -m [domainname]
+       ypinit -s master_server [domainname]
+       ypinit -u [domainname]
+
+The `-m' flag builds a master YP server, and the `-s' flag builds
+a slave YP server.  When building a slave YP server, `master_server'
+must be an existing, reachable YP server.
+The `-u' is for updating the ypservers map on a master server.
+__usage
+
+	exit 1
+fi
+
+# Check if domainname is set, don't accept an empty domainname
+if [ -z "${DOMAIN}" ]; then
+	cat << \__no_domain 1>&2
+The local host's YP domain name has not been set.  Please set it with
+the domainname(8) command or pass the domain as an argument to ypinit(8).
+__no_domain
+
+	exit 1
+fi
+
+# Check if hostname is set, don't accept an empty hostname
+HOST=`${HOSTNAME}`
+if [ -z "${HOST}" ]; then
+	cat << \__no_hostname 1>&2
+The local host's hostname has not been set.  Please set it with the
+hostname(8) command.
+__no_hostname
+
+	exit 1
+fi
+
+# Check if we have contact with master.
+if [ "${SERVERTYPE}" = "SLAVE" ];
+then
+	COUNT=`${YPWHICH} -d ${DOMAIN} -m 2>/dev/null | grep -i ${MASTER} | wc -l | tr -d " "`
+	if [ "$COUNT" = "0" ]
+	then
+		echo "Can't enumerate maps from ${MASTER}. Please check that it is running." 1>&2
+		exit 1
+	fi
+fi
+
+# Check if user is root
+ID=`id -u`
+if [ "${ID}" != "0" ]; then
+	echo "You have to be the superuser to run this.  Please login as root." 1>&2
+	exit 1
+fi
+
+# Check if the YP directory exists.
+
+if [ ! -d ${YP_DIR} -o -f ${YP_DIR} ]
+then
+	echo "The directory ${YP_DIR} doesn't exist.  Restore it from the distribution." 1>&2
+	exit 1
+
+fi
+
+echo -n "Server Type: ${SERVERTYPE} Domain: ${DOMAIN}"
+if [ "${SERVERTYPE}" = "SLAVE" ]; then
+	echo -n " Master: ${MASTER}"
+fi
+echo ""
+
+if [ "${SERVERTYPE}" != "UPDATE" ];
+then
+	cat << \__notice1
+
+Creating an YP server will require that you answer a few questions.
+Questions will all be asked at the beginning of the procedure.
+
+__notice1
+
+	echo -n "Do you want this procedure to quit on non-fatal errors? [y/n: n]  "
+	read DOEXIT
+
+	case ${DOEXIT} in
+	y*|Y*)
+		ERROR_EXIT="YES"
+		;;
+
+	*)	ERROR_EXIT="NO"
+		echo ""
+		echo "Ok, please remember to go back and redo manually whatever fails."
+		echo "If you don't, something might not work. "
+		;;
+	esac
+
+	if [ -d "${YP_DIR}/${DOMAIN}" ]; then
+		echo ""	
+		echo -n "Can we destroy the existing ${YP_DIR}/${DOMAIN} and its contents? [y/n: n]  "
+		read KILL
+
+		ERROR=
+		case ${KILL} in
+		y*|Y*)
+			ERROR="DELETE"
+			;;
+
+		*)	ERROR=
+			;;
+		esac
+
+		if [ "${ERROR}" = "DELETE" ]; then
+			if ! rm -rf ${YP_DIR}/${DOMAIN}; then
+				echo "Can't clean up old directory ${YP_DIR}/${DOMAIN}." 1>&2
+				exit 1
+			fi
+		else
+			echo "OK, please clean it up by hand and start again.  Bye"
+			exit 0
+		fi
+	
+	fi
+
+	if ! mkdir "${YP_DIR}/${DOMAIN}"; then
+		echo "Can't make new directory ${YP_DIR}/${DOMAIN}." 1>&2
+		exit 1
+	fi
+fi
+
+if [ "${SERVERTYPE}" = "MASTER" ];
+then
+
+	if [ ! -f ${YP_DIR}/Makefile ]
+	then
+		if [ ! -f ${YP_DIR}/Makefile.main ]
+		then
+			echo "Can't find ${YP_DIR}/Makefile.main. " 1>&2
+			exit 1
+		fi
+		cp ${YP_DIR}/Makefile.main ${YP_DIR}/Makefile
+	fi
+
+	SUBDIR=`grep "^SUBDIR=" ${YP_DIR}/Makefile`
+	
+	if [ -z "${SUBDIR}" ]
+	then
+		echo "Can't find line starting with 'SUBDIR=' in ${YP_DIR}/Makefile. " 1>&2
+		exit 1
+	fi
+
+	NEWSUBDIR="SUBDIR="
+	for DIR in `echo ${SUBDIR} | cut -c8-255`; do
+		if [ ${DIR} != ${DOMAIN} ]; then
+			NEWSUBDIR="${NEWSUBDIR} ${DIR}"
+		fi
+	done
+	NEWSUBDIR="${NEWSUBDIR} ${DOMAIN}"
+
+	if [ -f ${YP_DIR}/Makefile.tmp ]; then 
+		rm ${YP_DIR}/Makefile.tmp
+	fi
+
+	mv ${YP_DIR}/Makefile ${YP_DIR}/Makefile.tmp
+	sed -e "s/^${SUBDIR}/${NEWSUBDIR}/" ${YP_DIR}/Makefile.tmp > \
+	    ${YP_DIR}/Makefile
+	rm ${YP_DIR}/Makefile.tmp
+
+	if [ ! -f ${YP_DIR}/Makefile.yp ]; then
+		echo "Can't find ${YP_DIR}/Makefile.yp. " 1>&2
+		exit 1
+	fi
+
+	cp ${YP_DIR}/Makefile.yp ${YP_DIR}/${DOMAIN}/Makefile
+
+fi
+
+if [ "${SERVERTYPE}" = "SLAVE" ];
+then
+
+	echo "There will be no further questions. The remainder of the procedure"
+	echo "should take a few minutes, to copy the databases from ${MASTER}."
+
+	for MAP in `${YPWHICH} -d ${DOMAIN} -m | cut -d\  -f1`
+	do
+		echo "Transfering ${MAP}..."
+		if ! ${YPXFR} -h ${MASTER} -c -d ${DOMAIN} ${MAP}; then
+			echo "Can't transfer map ${MAP}." 1>&2
+			ERROR_EXISTS="YES"
+			if [ "${ERROR_EXIT}" = "YES" ]; then
+				exit 1
+			fi
+		fi
+	done
+
+	echo ""
+	if [ "${ERROR_EXISTS}" = "YES"  ]; then
+		echo "${HOST} has been setup as an YP slave server with errors. " 1>&2
+		echo "Please remember fix any problem that occurred." 1>&2
+	else
+		echo "${HOST} has been setup as an YP slave server without any errors. "
+	fi
+
+	echo "Don't forget to update map ypservers on ${MASTER}."
+	exit 0
+fi
+
+LIST_OK="NO"
+
+while [ "${LIST_OK}" = "NO" ];
+do
+	
+	if [ "${SERVERTYPE}" = "MASTER" ];
+	then
+		HOST_LIST="${HOST}"
+		echo ""
+		echo "At this point, we have to construct a list of this domains YP servers."
+		echo "${HOST} is already known as master server."
+		echo "Please continue to add any slave servers, one per line. When you are"
+		echo "done with the list, type a <control D>."
+		echo "	master server   :  ${HOST}"
+	fi
+
+	if [ "${SERVERTYPE}" = "UPDATE" ];
+	then
+		HOST_LIST="${HOST}"
+		NEW_LIST=""
+		MASTER_NAME=""
+		SHORT_HOST=`echo ${HOST} | cut -d. -f1`
+		if [ -f ${YP_DIR}/${DOMAIN}/ypservers.db ];
+		then
+			for srv in `${MAKEDBM} -u ${YP_DIR}/${DOMAIN}/ypservers | grep -v "^YP" | tr "\t" " " | cut -d\  -f1`;
+			do
+				short_srv=`echo ${srv} | cut -d. -f1`
+				if [ "${SHORT_HOST}" != "${short_srv}" ]
+				then
+					if [ "${NEW_LIST}" = "" ];
+					then
+						NEW_LIST="${srv}"
+					else
+						NEW_LIST="${NEW_LIST} ${srv}"
+					fi
+				fi
+			done;
+			MASTER_NAME=`${MAKEDBM} -u ${YP_DIR}/${DOMAIN}/ypservers | grep "^YP_MASTER_NAME" | tr "\t" " " | cut -d\  -f2`
+		fi
+		echo ""
+		echo "Update the list of hosts running YP servers in domain ${DOMAIN}."
+		echo "Master for this domain is ${MASTER_NAME}."
+		echo ""
+		echo "First verify old servers, type \\ to remove a server." 
+		echo "Then add new servers, one per line. When done type a <control D>." 
+		echo ""
+		echo "	master server   :  ${HOST}"
+		if [ "${NEW_LIST}" != "" ]; then
+			for node in $NEW_LIST; do
+				echo -n "	verify host     : [${node}] "
+				read verify
+				if [ "${verify}" != "\\" ]; then
+					HOST_LIST="${HOST_LIST} ${node}"
+				fi
+			done;
+		fi
+	fi
+
+	echo -n "	next host to add:  "
+
+	while read h
+	do
+		echo -n "	next host to add:  "
+		HOST_LIST="${HOST_LIST} ${h}"
+	done
+
+	echo ""
+	echo "The current list of NIS servers looks like this:"
+	echo ""
+
+	for h in `echo ${HOST_LIST}`;
+	do
+		echo ${h}
+	done
+
+	echo ""
+	echo -n "Is this correct?  [y/n: y]  "
+	read hlist_ok
+
+	case $hlist_ok in
+	n*)	echo "Let's try the whole thing again...";;
+	N*)	echo "Let's try the whole thing again...";;
+	*)	LIST_OK="YES";;
+	esac
+
+done
+
+echo "Building ${YP_DIR}/${DOMAIN}/ypservers..."
+for host in ${HOST_LIST};
+do
+	echo "${host} ${host}"
+done | ${MAKEDBM} - ${YP_DIR}/${DOMAIN}/ypservers
+
+if [ $? -ne 0 ]; then
+	echo "" 1>&2
+	echo "Couldn't build yp data base ${YP_DIR}/${DOMAIN}/ypservers." 1>&2
+	ERROR_EXISTS="YES"
+	if [ "${ERROR_EXIT}" = "YES" ]; then 
+		exit 1
+	fi
+fi
+
+if [ "${SERVERTYPE}" = "MASTER" ]; then
+	
+	CUR_PWD=`pwd`
+	cd ${YP_DIR}/${DOMAIN}
+	echo "Running ${YP_DIR}/${DOMAIN}/Makefile..."
+	if ! ${MAKE} NOPUSH=1; then
+		echo "" 1>&2
+		echo "Error running Makefile." 1>&2
+		ERROR_EXISTS="YES"
+		if [ "${ERROR_EXIT}" = "YES" ]; then 
+			exit 1
+		fi
+	fi
+
+	cd ${CUR_PWD}
+
+	echo ""
+	if [ "${ERROR_EXISTS}" = "YES" ]; then
+		echo "${HOST} has been setup as an YP master server with errors. " 1>&2
+		echo "Please remember fix any problem that occurred." 1>&2
+	else
+		echo "${HOST} has been setup as an YP master server without any errors. "
+	fi
+
+fi
diff --git a/ypmatch.tproj/Makefile b/ypmatch.tproj/Makefile
new file mode 100644
index 0000000..283ee4c
--- /dev/null
+++ b/ypmatch.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ypmatch
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = ypmatch.c
+
+OTHERSRCS = Makefile.dist Makefile.preamble ypmatch.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ypmatch.tproj/Makefile.dist b/ypmatch.tproj/Makefile.dist
new file mode 100644
index 0000000..fa9c3ba
--- /dev/null
+++ b/ypmatch.tproj/Makefile.dist
@@ -0,0 +1,6 @@
+#	from: @(#)Makefile	5.8 (Berkeley) 7/28/90
+#	$Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:59:02 wsanchez Exp $
+
+PROG=	ypmatch
+
+.include <bsd.prog.mk>
diff --git a/ypmatch.tproj/Makefile.preamble b/ypmatch.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/ypmatch.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/ypmatch.tproj/PB.project b/ypmatch.tproj/PB.project
new file mode 100644
index 0000000..2b3516c
--- /dev/null
+++ b/ypmatch.tproj/PB.project
@@ -0,0 +1,36 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LINKED = (ypmatch.c); 
+        OTHER_SOURCES = (Makefile.dist, Makefile.preamble, ypmatch.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ypmatch; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ypmatch.tproj/ypmatch.1 b/ypmatch.tproj/ypmatch.1
new file mode 100644
index 0000000..f5e76ec
--- /dev/null
+++ b/ypmatch.tproj/ypmatch.1
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1993 Winning Strategies, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"      This product includes software developed by Winning Strategies, Inc.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\"	$Id: ypmatch.1,v 1.1.1.1 1999/05/02 03:59:02 wsanchez Exp $
+.\"
+.Dd December 3, 1993
+.Dt YPMATCH 1
+.Os
+.Sh NAME
+.Nm ypmatch
+.Nd "print the values of one or more keys in a YP database"
+.Sh SYNOPSIS
+.Nm ypmatch
+.Op Fl kt
+.Op Fl d Ar domainname
+.Ar key ...
+.Ar mapname
+.Nm ypmatch 
+.Fl x
+.Sh DESCRIPTION
+.Nm Ypmatch
+prints out the values of one or more keys from the 
+.Tn YP
+database specified by
+.Ar mapname,
+which may be a map name or a map nickname.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl d Ar domainname
+Specify a domain other than the default domain.
+.It Fl k
+Display map keys.
+This option is useful with maps in which the values are null or the key
+is not part of the value.
+.It Fl t
+Inhibit translation of map nicknames
+to their corresponding map names.
+.It Fl x
+Display the map nickname table.
+.El
+.Sh SEE ALSO
+.Xr ypcat 1 ,
+.Xr yp 8
+.Sh AUTHOR
+Theo De Raadt
diff --git a/ypmatch.tproj/ypmatch.c b/ypmatch.tproj/ypmatch.c
new file mode 100644
index 0000000..5f78260
--- /dev/null
+++ b/ypmatch.tproj/ypmatch.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$Id: ypmatch.c,v 1.1.1.1 1999/05/02 03:59:02 wsanchez Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+
+struct ypalias {
+	char *alias, *name;
+} ypaliases[] = {
+	{ "passwd", "passwd.byname" },
+	{ "group", "group.byname" },
+	{ "networks", "networks.byaddr" },
+	{ "hosts", "hosts.byname" },
+	{ "protocols", "protocols.bynumber" },
+	{ "services", "services.byname" },
+	{ "aliases", "mail.aliases" },
+	{ "ethers", "ethers.byname" },
+};
+
+usage()
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\typmatch [-d domain] [-t] [-k] key [key ...] mname\n");
+	fprintf(stderr, "\typmatch -x\n");
+	fprintf(stderr, "where\n");
+	fprintf(stderr, "\tmname may be either a mapname or a nickname for a map\n");
+	fprintf(stderr, "\t-t inhibits map nickname translation\n");
+	fprintf(stderr, "\t-k prints keys as well as values.\n");
+	fprintf(stderr, "\t-x dumps the map nickname translation table.\n");
+	exit(1);
+}
+
+int
+main(argc, argv)
+char **argv;
+{
+	char *domainname;
+	char *inkey, *inmap, *outbuf;
+	extern char *optarg;
+	extern int optind;
+	int outbuflen, key, notrans;
+	int c, r, i;
+
+	notrans = key = 0;
+	yp_get_default_domain(&domainname);
+
+	while( (c=getopt(argc, argv, "xd:kt")) != -1)
+		switch(c) {
+		case 'x':
+			for(i=0; i<sizeof ypaliases/sizeof ypaliases[0]; i++)
+				printf("Use \"%s\" for \"%s\"\n",
+					ypaliases[i].alias,
+					ypaliases[i].name);
+			exit(0);
+		case 'd':
+			domainname = optarg;
+			break;
+		case 't':
+			notrans++;
+			break;
+		case 'k':
+			key++;
+			break;
+		default:
+			usage();
+		}
+
+	if( (argc-optind) < 2 )
+		usage();
+
+	inmap = argv[argc-1];
+	for(i=0; (!notrans) && i<sizeof ypaliases/sizeof ypaliases[0]; i++)
+		if( strcmp(inmap, ypaliases[i].alias) == 0)
+			inmap = ypaliases[i].name;
+	for(; optind < argc-1; optind++) {
+		inkey = argv[optind];
+
+		r = yp_match(domainname, inmap, inkey,
+			strlen(inkey), &outbuf, &outbuflen);
+		switch(r) {
+		case 0:
+			if(key)
+				printf("%s ", inkey);
+			printf("%*.*s\n", outbuflen, outbuflen, outbuf);
+			break;
+		case YPERR_YPBIND:
+			fprintf(stderr, "yp_match: not running ypbind\n");
+			exit(1);
+		default:
+			fprintf(stderr, "Can't match key %s in map %s. Reason: %s\n",
+				inkey, inmap, yperr_string(r));
+			break;
+		}
+	}
+	exit(0);
+}
diff --git a/yppoll.tproj/Makefile b/yppoll.tproj/Makefile
new file mode 100644
index 0000000..38f2ae4
--- /dev/null
+++ b/yppoll.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = yppoll
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = yppoll.c
+
+OTHERSRCS = Makefile.dist Makefile.preamble yppoll.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/yppoll.tproj/Makefile.dist b/yppoll.tproj/Makefile.dist
new file mode 100644
index 0000000..2274b91
--- /dev/null
+++ b/yppoll.tproj/Makefile.dist
@@ -0,0 +1,7 @@
+#	from: @(#)Makefile	5.8 (Berkeley) 7/28/90
+#	$Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:59:02 wsanchez Exp $
+
+PROG=	yppoll
+MAN8=	yppoll.0
+
+.include <bsd.prog.mk>
diff --git a/yppoll.tproj/Makefile.preamble b/yppoll.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/yppoll.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/yppoll.tproj/PB.project b/yppoll.tproj/PB.project
new file mode 100644
index 0000000..d763e38
--- /dev/null
+++ b/yppoll.tproj/PB.project
@@ -0,0 +1,36 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LINKED = (yppoll.c); 
+        OTHER_SOURCES = (Makefile.dist, Makefile.preamble, yppoll.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = yppoll; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/yppoll.tproj/yppoll.8 b/yppoll.tproj/yppoll.8
new file mode 100644
index 0000000..db17f7b
--- /dev/null
+++ b/yppoll.tproj/yppoll.8
@@ -0,0 +1,63 @@
+.\" Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote
+.\"    products derived from this software without specific prior written
+.\"    permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	$Id: yppoll.8,v 1.1.1.1 1999/05/02 03:59:03 wsanchez Exp $
+.\"
+.Dd August 18, 1994
+.Dt YPPOLL 8
+.Os NetBSD
+.Sh NAME
+.Nm yppoll
+.Nd get version of a YP map from YP server
+.Sh SYNOPSIS
+.Nm yppoll
+.Op Fl h Ar host
+.Op Fl d Ar domainname
+.Ar mapname
+.Sh DESCRIPTION
+.Nm yppoll 
+is used to get information of a maps order number and master server.
+This utility is useful when determining if different servers have the
+same version of a map.
+.Nm yppoll
+normally talks with the default
+.Xr ypserv 8
+process, but by using the 
+.Fl h
+option it is possible to talk with a specific server.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl d Ar domain
+Don't use default domain, use the specified domain.
+.It Fl h Ar host
+Get map information from host instead of the default YP server.
+.El
+.Sh SEE ALSO
+.Xr ypserv 8 
+.Sh AUTHOR
+Theo de Raadt, John Brezak and Mats O Jansson
diff --git a/yppoll.tproj/yppoll.c b/yppoll.tproj/yppoll.c
new file mode 100644
index 0000000..5f1ddc5
--- /dev/null
+++ b/yppoll.tproj/yppoll.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
+ * Copyright (c) 1992, 1993 John Brezak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt and
+ *	John Brezak.
+ * 4. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$Id: yppoll.c,v 1.1.1.1 1999/05/02 03:59:03 wsanchez Exp $";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <time.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+
+void
+usage()
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\typpoll [-h host] [-d domainname] mapname\n");
+	exit(1);
+}
+
+int
+get_remote_info(indomain, inmap, server, outorder, outname)
+	char *indomain;
+	char *inmap;
+	char *server;
+	int *outorder;
+	char **outname;
+{
+	struct ypresp_order ypro;
+	struct ypresp_master yprm;
+	struct ypreq_nokey yprnk;
+	struct timeval tv;
+	int r;
+	struct sockaddr_in rsrv_sin;
+	int rsrv_sock;
+	CLIENT *client;
+	struct hostent *h;
+
+	bzero((char *)&rsrv_sin, sizeof rsrv_sin);
+	rsrv_sin.sin_len = sizeof rsrv_sin;
+	rsrv_sin.sin_family = AF_INET;
+	rsrv_sock = RPC_ANYSOCK;
+
+	h = gethostbyname(server);
+	if (h == NULL) {
+		if (inet_aton(server, &rsrv_sin.sin_addr) == 0) {
+			fprintf(stderr, "unknown host %s\n", server);
+			exit(1);
+		}
+	} else {
+		rsrv_sin.sin_addr.s_addr = *(u_long *)h->h_addr;
+	}
+
+	tv.tv_sec = 10;
+	tv.tv_usec = 0;
+
+	client = clntudp_create(&rsrv_sin, YPPROG, YPVERS, tv, &rsrv_sock);
+	if (client == NULL) {
+		fprintf(stderr, "clntudp_create: no contact with host %s.\n",
+		    server);
+		exit(1);
+	}
+	
+	yprnk.domain = indomain;
+	yprnk.map = inmap;
+
+	bzero((char *)(char *)&ypro, sizeof ypro);
+
+	r = clnt_call(client, YPPROC_ORDER, xdr_ypreq_nokey, &yprnk,
+	    xdr_ypresp_order, &ypro, tv);
+	if (r != RPC_SUCCESS)
+		clnt_perror(client, "yp_order: clnt_call");
+
+	*outorder = ypro.ordernum;
+	xdr_free(xdr_ypresp_order, (char *)&ypro);
+
+	r = ypprot_err(ypro.status);
+	if (r == RPC_SUCCESS) {
+		bzero((char *)&yprm, sizeof yprm);
+
+		r = clnt_call(client, YPPROC_MASTER, xdr_ypreq_nokey,
+		    &yprnk, xdr_ypresp_master, &yprm, tv);
+		if (r != RPC_SUCCESS)
+			clnt_perror(client, "yp_master: clnt_call");
+		r = ypprot_err(yprm.status);
+		if (r==0)
+			*outname = (char *)strdup(yprm.master);
+		xdr_free(xdr_ypresp_master, (char *)&yprm);
+	}
+	clnt_destroy(client);
+	return r;
+}
+
+int
+main(argc, argv)
+	int  argc;
+	char **argv;
+{
+	char *domainname;
+	char *hostname = NULL;
+	char *inmap, *master;
+	int order;
+	extern char *optarg;
+	extern int optind;
+	int c, r;
+
+	yp_get_default_domain(&domainname);
+
+	while ((c=getopt(argc, argv, "h:d:?")) != -1)
+		switch (c) {
+		case 'd':
+			domainname = optarg;
+			break;
+		case 'h':
+			hostname = optarg;
+			break;
+		default:
+			usage();
+			/*NOTREACHED*/
+		}
+
+	if (optind + 1 != argc )
+		usage();
+	inmap = argv[optind];
+
+	if (hostname != NULL) {
+		r = get_remote_info(domainname, inmap, hostname,
+		    &order, &master);
+	} else {
+		r = yp_order(domainname, inmap, &order);
+		if (r == 0)
+			r = yp_master(domainname, inmap, &master);
+	}
+
+	if (r != 0) {
+		fprintf(stderr, "No such map %s. Reason: %s\n",
+		    inmap, yperr_string(r));
+		exit(1);
+	}
+
+	printf("Map %s has order number %d. %s", inmap, order,
+	    ctime((time_t *)&order));
+	printf("The master server is %s.\n", master);
+	exit(0);
+}
diff --git a/yppush.tproj/Makefile b/yppush.tproj/Makefile
new file mode 100644
index 0000000..ed8971f
--- /dev/null
+++ b/yppush.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = yppush
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = yppush.h ypdb.h yplib_host.h ypdef.h
+
+CFILES = ypdb.c yplib_host.c yppush.c yppush_err.c yppush_proc.c\
+         yppush_svc.c yppush_xdr.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble yppush.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/yppush.tproj/Makefile.postamble b/yppush.tproj/Makefile.postamble
new file mode 100644
index 0000000..509e7f5
--- /dev/null
+++ b/yppush.tproj/Makefile.postamble
@@ -0,0 +1,101 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGE: langage in which the project is written (default "English")
+#  LOCAL_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/yppush.tproj/Makefile.preamble b/yppush.tproj/Makefile.preamble
new file mode 100644
index 0000000..83f25c7
--- /dev/null
+++ b/yppush.tproj/Makefile.preamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. <<default?>>
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSION: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
diff --git a/yppush.tproj/PB.project b/yppush.tproj/PB.project
new file mode 100644
index 0000000..f91db95
--- /dev/null
+++ b/yppush.tproj/PB.project
@@ -0,0 +1,35 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (yppush.h, ypdb.h, yplib_host.h, ypdef.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (
+            ypdb.c, 
+            yplib_host.c, 
+            yppush.c, 
+            yppush_err.c, 
+            yppush_proc.c, 
+            yppush_svc.c, 
+            yppush_xdr.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, yppush.8); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = yppush; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/yppush.tproj/ypdb.c b/yppush.tproj/ypdb.c
new file mode 100644
index 0000000..c9bd178
--- /dev/null
+++ b/yppush.tproj/ypdb.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdb.c,v 1.5 1997/02/09 09:49:36 maja Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * This code is derived from ndbm module of BSD4.4 db (hash) by
+ * Mats O Jansson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ypdb.h"
+
+#ifdef YPDB_PATCH
+extern DBM *__hash_open();
+#else
+extern DBM *__bt_open();
+#endif
+
+/*
+ * Returns:
+ * 	*DBM on success
+ *	 NULL on failure
+ */
+
+extern DBM *
+ypdb_open(file, flags, mode)
+	const char *file;
+	int flags, mode;
+{
+#ifdef YPDB_PATCH
+	HASHINFO info;
+	char path[MAXPATHLEN];
+
+	info.bsize = 4096;
+	info.ffactor = 40;
+	info.nelem = 1;
+	info.cachesize = NULL;
+	info.hash = NULL;
+	info.lorder = 0;
+	snprintf(path, sizeof(path), "%s%s", file, YPDB_SUFFIX);
+	return ((DBM *)__hash_open(path, flags, mode, &info, 0));
+#else
+	BTREEINFO info;
+	char path[MAXPATHLEN];
+	DBM *db;
+
+	info.flags = 0;
+	info.cachesize = 0;
+	info.maxkeypage = 0;
+	info.minkeypage = 0;
+	info.psize = 0;
+	info.compare = NULL;
+	info.prefix = NULL;
+	info.lorder = 0;
+	snprintf(path, sizeof(path), "%s%s", file, YPDB_SUFFIX);
+	db = (DBM *)__bt_open(path, flags, mode, &info, 0);
+	return (db);
+#endif
+}
+
+/*
+ * Returns:
+ * 	*DBM on success
+ *	 NULL on failure
+ */
+
+extern DBM *
+ypdb_open_suf(file, flags, mode)
+	const char *file;
+	int flags, mode;
+{
+#ifdef YPDB_PATCH
+	HASHINFO info;
+
+	info.bsize = 4096;
+	info.ffactor = 40;
+	info.nelem = 1;
+	info.cachesize = NULL;
+	info.hash = NULL;
+	info.lorder = 0;
+	return ((DBM *)__hash_open(file, flags, mode, &info, 0));
+#else
+	BTREEINFO info;
+	DBM *db;
+
+	info.flags = 0;
+	info.cachesize = 0;
+	info.maxkeypage = 0;
+	info.minkeypage = 0;
+	info.psize = 0;
+	info.compare = NULL;
+	info.prefix = NULL;
+	info.lorder = 0;
+	db = (DBM *)__bt_open(file, flags, mode, &info, 0);
+	return (db);
+#endif
+}
+
+extern void
+ypdb_close(db)
+	DBM *db;
+{
+	(void)(db->close)(db);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_fetch(db, key)
+	DBM *db;
+	datum key;
+{
+	datum retval;
+	int status;
+
+	status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
+	if (status) {
+		retval.dptr = NULL;
+		retval.dsize = 0;
+	}
+	return (retval);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_firstkey(db)
+	DBM *db;
+{
+	int status;
+	datum retdata, retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+	if (status)
+		retkey.dptr = NULL;
+	return (retkey);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_nextkey(db)
+	DBM *db;
+{
+	int status;
+	datum retdata, retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+	if (status)
+		retkey.dptr = NULL;
+	return (retkey);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_setkey(db, key)
+	DBM *db;
+        datum key;
+{
+	int status;
+	datum retdata;
+#ifdef YPDB_PATCH
+	datum retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+	if (status)
+		retkey.dptr = NULL;
+	while ((retkey.dptr != NULL) &&
+	       ((retkey.dsize != key.dsize) ||
+		(strncmp(key.dptr,retkey.dptr,retkey.dsize) != 0))) {
+	  status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+	  if (status)
+	  	retkey.dptr = NULL;
+	};
+	return (retkey);
+#else
+	status = (db->seq)(db, (DBT *)&key, (DBT *)&retdata, R_CURSOR);
+	if (status)
+		key.dptr = NULL;
+	return (key);
+#endif
+}
+
+/*
+ * Returns:
+ *	 0 on success
+ *	<0 failure
+ */
+
+int
+ypdb_delete(db, key)
+	DBM *db;
+	datum key;
+{
+	int status;
+
+	status = (db->del)(db, (DBT *)&key, 0);
+	if (status)
+		return (-1);
+	else
+		return (0);
+}
+
+/*
+ * Returns:
+ *	 0 on success
+ *	<0 failure
+ *	 1 if YPDB_INSERT and entry exists
+ */
+
+int
+ypdb_store(db, key, content, flags)
+	DBM *db;
+	datum key, content;
+	int flags;
+{
+	return ((db->put)(db, (DBT *)&key, (DBT *)&content,
+	    (flags == YPDB_INSERT) ? R_NOOVERWRITE : 0));
+}
+
diff --git a/yppush.tproj/ypdb.h b/yppush.tproj/ypdb.h
new file mode 100644
index 0000000..9afbad5
--- /dev/null
+++ b/yppush.tproj/ypdb.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdb.h,v 1.5 1997/02/09 09:49:37 maja Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * This code is derived from ndbm module of BSD4.4 db (hash) by
+ * Mats O Jansson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPDB_H_
+#define _YPDB_H_
+
+#ifndef _DB_H_
+#include <bsd/db.h>
+#endif
+
+#define YPDB_SUFFIX	".db"
+
+/* Flags to ypdb_store(). */
+#define YPDB_INSERT      0
+#define YPDB_REPLACE     1
+
+#ifndef DATUM
+typedef struct {
+	char	*dptr;
+	int	dsize;
+} datum;
+#define DATUM
+#endif
+
+typedef DB DBM;
+
+__BEGIN_DECLS
+void	 ypdb_close __P((DBM *));
+datum	 ypdb_fetch __P((DBM *, datum));
+datum	 ypdb_firstkey __P((DBM *));
+datum	 ypdb_nextkey __P((DBM *));
+datum	 ypdb_setkey __P((DBM *, datum));
+DBM     *ypdb_open __P((const char *, int, int));
+DBM     *ypdb_open_suf __P((const char *, int, int));
+int	 ypdb_store __P((DBM *, datum, datum, int));
+__END_DECLS
+
+#endif /* !_YPDB_H_ */
diff --git a/yppush.tproj/ypdef.h b/yppush.tproj/ypdef.h
new file mode 100644
index 0000000..89970d7
--- /dev/null
+++ b/yppush.tproj/ypdef.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdef.h,v 1.6 1997/03/30 20:51:14 maja Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPDEF_H_
+#define _YPDEF_H_
+
+#define YP_DB_PATH "/var/yp"
+#define YP_LAST_KEY        "YP_LAST_MODIFIED"
+#define YP_LAST_LEN	   (sizeof(YP_LAST_KEY)-1)
+#define YP_INPUT_KEY       "YP_INPUT_FILE"
+#define YP_INPUT_LEN	   (sizeof(YP_INPUT_KEY)-1)
+#define YP_OUTPUT_KEY      "YP_OUTPUT_FILE"
+#define YP_OUTPUT_LEN	   (sizeof(YP_OUTPUT_KEY)-1)
+#define YP_MASTER_KEY      "YP_MASTER_NAME"
+#define YP_MASTER_LEN	   (sizeof(YP_MASTER_KEY)-1)
+#define YP_DOMAIN_KEY      "YP_DOMAIN_NAME"
+#define YP_DOMAIN_LEN	   (sizeof(YP_DOMAIN_KEY)-1)
+#define YP_INTERDOMAIN_KEY "YP_INTERDOMAIN"
+#define YP_INTERDOMAIN_LEN (sizeof(YP_INTERDOMAIN_KEY)-1)
+#define YP_SECURE_KEY      "YP_SECURE"
+#define YP_SECURE_LEN      (sizeof(YP_SECURE_KEY)-1)
+
+#define MAX_LAST_LEN 10
+#define MAX_MASTER_LEN 255
+#define YP_HOSTNAME "hosts.byname"
+#define YP_HOSTADDR "hosts.byaddr"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define YPXFR_PROC "/usr/sbin/ypxfr"
+#define YPPUSH_PROC "/usr/sbin/yppush"
+#define YPSERV_PID_PATH "/var/run/ypserv.pid"
+#define YP_SECURENET_FILE "/var/yp/securenet"
+
+#endif /* !_YPDEF_H_ */
diff --git a/yppush.tproj/yplib_host.c b/yppush.tproj/yplib_host.c
new file mode 100644
index 0000000..70b914b
--- /dev/null
+++ b/yppush.tproj/yplib_host.c
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yplib_host.c,v 1.7 1997/06/23 01:11:12 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char *rcsid = "$OpenBSD: yplib_host.c,v 1.7 1997/06/23 01:11:12 deraadt Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+extern bool_t xdr_domainname(), xdr_ypbind_resp();
+extern bool_t xdr_ypreq_key(), xdr_ypresp_val();
+extern bool_t xdr_ypreq_nokey(), xdr_ypresp_key_val();
+extern bool_t xdr_ypresp_all(), xdr_ypresp_all_seq();
+extern bool_t xdr_ypresp_master();
+
+extern int (*ypresp_allfn)();
+extern void *ypresp_data;
+
+int _yplib_host_timeout = 10;
+
+CLIENT *
+yp_bind_host(server,program,version,port,usetcp)
+char *server;
+u_long	program,version;
+u_short port;
+int usetcp;
+{
+	struct sockaddr_in rsrv_sin;
+	int rsrv_sock;
+	struct hostent *h;
+	struct timeval tv;
+	static CLIENT *client;
+
+	memset(&rsrv_sin, 0, sizeof rsrv_sin);
+	rsrv_sin.sin_len = sizeof rsrv_sin;
+	rsrv_sin.sin_family = AF_INET;
+	rsrv_sock = RPC_ANYSOCK;
+	if (port != 0) {
+		rsrv_sin.sin_port = htons(port);
+	}
+
+	if ((*server >= '0') && (*server <= '9')) {
+		if(inet_aton(server,&rsrv_sin.sin_addr) == 0) {
+			fprintf(stderr, "inet_aton: invalid address %s.\n",
+				server);
+	                exit(1);
+		}
+	} else {
+		h = gethostbyname(server);
+		if(h == NULL) {
+			fprintf(stderr, "gethostbyname: unknown host %s.\n",
+				server);
+	                exit(1);
+		}
+		rsrv_sin.sin_addr.s_addr = *(u_int32_t *)h->h_addr;
+	}
+
+	tv.tv_sec = 10;
+	tv.tv_usec = 0;
+
+	if (usetcp) {
+		client = clnttcp_create(&rsrv_sin, program, version,
+					&rsrv_sock, 0, 0);
+	} else {
+		client = clntudp_create(&rsrv_sin, program, version, tv,
+					&rsrv_sock);
+	}
+
+	if (client == NULL) {
+		fprintf(stderr, "clntudp_create: no contact with host %s.\n",
+			server);
+	        exit(1);
+	}
+
+	return(client);
+	
+}
+
+CLIENT *
+yp_bind_local(program,version)
+u_long	program,version;
+{
+	struct sockaddr_in rsrv_sin;
+	int rsrv_sock;
+	struct timeval tv;
+	static CLIENT *client;
+
+	memset(&rsrv_sin, 0, sizeof rsrv_sin);
+	rsrv_sin.sin_len = sizeof rsrv_sin;
+	rsrv_sin.sin_family = AF_INET;
+	rsrv_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+	rsrv_sock = RPC_ANYSOCK;
+
+	tv.tv_sec = 10;
+	tv.tv_usec = 0;
+
+	client = clntudp_create(&rsrv_sin, program, version, tv, &rsrv_sock);
+	if (client == NULL) {
+		fprintf(stderr,"clntudp_create: no contact with localhost.\n");
+	        exit(1);
+	}
+
+	return(client);
+	
+}
+
+int
+yp_match_host(client, indomain, inmap, inkey, inkeylen, outval, outvallen)
+CLIENT *client;
+char *indomain;
+char *inmap;
+const char *inkey;
+int inkeylen;
+char **outval;
+int *outvallen;
+{
+	struct ypresp_val yprv;
+	struct timeval tv;
+	struct ypreq_key yprk;
+	int r;
+
+	*outval = NULL;
+	*outvallen = 0;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprk.domain = indomain;
+	yprk.map = inmap;
+	yprk.key.keydat_val = (char *)inkey;
+	yprk.key.keydat_len = inkeylen;
+
+	memset(&yprv, 0, sizeof yprv);
+
+	r = clnt_call(client, YPPROC_MATCH,
+		xdr_ypreq_key, &yprk, xdr_ypresp_val, &yprv, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_match_host: clnt_call");
+	}
+	if( !(r=ypprot_err(yprv.stat)) ) {
+		*outvallen = yprv.val.valdat_len;
+		*outval = (char *)malloc(*outvallen+1);
+		memcpy(*outval, yprv.val.valdat_val, *outvallen);
+		(*outval)[*outvallen] = '\0';
+	}
+	xdr_free(xdr_ypresp_val, (char *)&yprv);
+	return r;
+}
+
+int
+yp_first_host(client, indomain, inmap, outkey, outkeylen, outval, outvallen)
+CLIENT *client;
+char *indomain;
+char *inmap;
+char **outkey;
+int *outkeylen;
+char **outval;
+int *outvallen;
+{
+	struct ypresp_key_val yprkv;
+	struct ypreq_nokey yprnk;
+	struct timeval tv;
+	int r;
+
+	*outkey = *outval = NULL;
+	*outkeylen = *outvallen = 0;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprnk.domain = indomain;
+	yprnk.map = inmap;
+	memset(&yprkv, 0, sizeof yprkv);
+
+	r = clnt_call(client, YPPROC_FIRST,
+		xdr_ypreq_nokey, &yprnk, xdr_ypresp_key_val, &yprkv, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_first_host: clnt_call");
+	}
+	if( !(r=ypprot_err(yprkv.stat)) ) {
+		*outkeylen = yprkv.key.keydat_len;
+		*outkey = (char *)malloc(*outkeylen+1);
+		memcpy(*outkey, yprkv.key.keydat_val, *outkeylen);
+		(*outkey)[*outkeylen] = '\0';
+		*outvallen = yprkv.val.valdat_len;
+		*outval = (char *)malloc(*outvallen+1);
+		memcpy(*outval, yprkv.val.valdat_val, *outvallen);
+		(*outval)[*outvallen] = '\0';
+	}
+	xdr_free(xdr_ypresp_key_val, (char *)&yprkv);
+	return r;
+}
+
+int
+yp_next_host(client, indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen)
+CLIENT *client;
+char *indomain;
+char *inmap;
+char *inkey;
+int inkeylen;
+char **outkey;
+int *outkeylen;
+char **outval;
+int *outvallen;
+{
+	struct ypresp_key_val yprkv;
+	struct ypreq_key yprk;
+	struct timeval tv;
+	int r;
+
+	*outkey = *outval = NULL;
+	*outkeylen = *outvallen = 0;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprk.domain = indomain;
+	yprk.map = inmap;
+	yprk.key.keydat_val = inkey;
+	yprk.key.keydat_len = inkeylen;
+	memset(&yprkv, 0, sizeof yprkv);
+
+	r = clnt_call(client, YPPROC_NEXT,
+		xdr_ypreq_key, &yprk, xdr_ypresp_key_val, &yprkv, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_next_host: clnt_call");
+	}
+	if( !(r=ypprot_err(yprkv.stat)) ) {
+		*outkeylen = yprkv.key.keydat_len;
+		*outkey = (char *)malloc(*outkeylen+1);
+		memcpy(*outkey, yprkv.key.keydat_val, *outkeylen);
+		(*outkey)[*outkeylen] = '\0';
+		*outvallen = yprkv.val.valdat_len;
+		*outval = (char *)malloc(*outvallen+1);
+		memcpy(*outval, yprkv.val.valdat_val, *outvallen);
+		(*outval)[*outvallen] = '\0';
+	}
+	xdr_free(xdr_ypresp_key_val, (char *)&yprkv);
+	return r;
+}
+
+int
+yp_all_host(client, indomain, inmap, incallback)
+CLIENT *client;
+char *indomain;
+char *inmap;
+struct ypall_callback *incallback;
+{
+	struct ypreq_nokey yprnk;
+	struct timeval tv;
+	u_long status;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprnk.domain = indomain;
+	yprnk.map = inmap;
+	ypresp_allfn = incallback->foreach;
+	ypresp_data = (void *)incallback->data;
+
+	(void) clnt_call(client, YPPROC_ALL,
+		xdr_ypreq_nokey, &yprnk, xdr_ypresp_all_seq, &status, tv);
+	xdr_free(xdr_ypresp_all_seq, (char *)&status);	/* not really needed... */
+
+	if(status != YP_FALSE)
+		return ypprot_err(status);
+	return 0;
+}
+
+int
+yp_order_host(client, indomain, inmap, outorder)
+CLIENT *client;
+char *indomain;
+char *inmap;
+u_int32_t *outorder;
+{
+	struct ypresp_order ypro;
+	struct ypreq_nokey yprnk;
+	struct timeval tv;
+	int r;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprnk.domain = indomain;
+	yprnk.map = inmap;
+
+	memset(&ypro, 0, sizeof ypro);
+
+	r = clnt_call(client, YPPROC_ORDER,
+		xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_order_host: clnt_call");
+	}
+
+	*outorder = ypro.ordernum;
+	xdr_free(xdr_ypresp_order, (char *)&ypro);
+	return ypprot_err(ypro.stat);
+}
+
+int
+yp_master_host(client, indomain, inmap, outname)
+CLIENT *client;
+char *indomain;
+char *inmap;
+char **outname;
+{
+	struct ypresp_master yprm;
+	struct ypreq_nokey yprnk;
+	struct timeval tv;
+	int r;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprnk.domain = indomain;
+	yprnk.map = inmap;
+
+	memset(&yprm, 0, sizeof yprm);
+
+	r = clnt_call(client, YPPROC_MASTER,
+		xdr_ypreq_nokey, &yprnk, xdr_ypresp_master, &yprm, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_master: clnt_call");
+	}
+	if( !(r=ypprot_err(yprm.stat)) ) {
+		*outname = (char *)strdup(yprm.peer);
+	}
+	xdr_free(xdr_ypresp_master, (char *)&yprm);
+	return r;
+}
+
+int
+yp_maplist_host(client, indomain, outmaplist)
+CLIENT *client;
+char *indomain;
+struct ypmaplist **outmaplist;
+{
+	struct ypresp_maplist ypml;
+	struct timeval tv;
+	int r;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	memset(&ypml, 0, sizeof ypml);
+
+	r = clnt_call(client, YPPROC_MAPLIST,
+		xdr_domainname, &indomain, xdr_ypresp_maplist, &ypml, tv);
+	if (r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_maplist: clnt_call");
+	}
+	*outmaplist = ypml.maps;
+	/* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/
+	return ypprot_err(ypml.stat);
+}
+
diff --git a/yppush.tproj/yplib_host.h b/yppush.tproj/yplib_host.h
new file mode 100644
index 0000000..038fb68
--- /dev/null
+++ b/yppush.tproj/yplib_host.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yplib_host.h,v 1.4 1997/05/01 22:14:45 niklas Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPLIB_HOST_H_
+#define _YPLIB_HOST_H_
+
+int	yp_match_host 	__P((CLIENT *client, char *indomain, char *inmap,
+			    const char *inkey, int inkeylen, char **outval,
+			    int *outvallen));
+int	yp_first_host	__P((CLIENT *client, char *indomain, char *inmap,
+			    char **outkey, int *outkeylen, char **outval,
+			    int *outvallen));
+int	yp_next_host	__P((CLIENT *client, char *indomain, char *inmap,
+			    char *inkey, int inkeylen, char **outkey,
+			    int *outkeylen, char **outval, int *outvallen));
+int	yp_master_host	__P((CLIENT *client,
+			    char *indomain, char *inmap, char **outname));
+int	yp_order_host	__P((CLIENT *client,
+			    char *indomain, char *inmap, u_int32_t *outorder));
+int	yp_all_host	__P((CLIENT *client, char *indomain, char *inmap,
+			    struct ypall_callback *incallback));
+int	yp_maplist_host	__P((CLIENT *client, char *indomain,
+			    struct ypmaplist **outmaplist));
+CLIENT *yp_bind_local	__P((u_long program, u_long version));
+CLIENT *yp_bind_host	__P((char *server, u_long program, u_long version,
+			    u_short port, int usetcp));
+
+#endif /* _YPLIB_HOST_H_ */
+
diff --git a/yppush.tproj/yppush.8 b/yppush.tproj/yppush.8
new file mode 100644
index 0000000..2777199
--- /dev/null
+++ b/yppush.tproj/yppush.8
@@ -0,0 +1,68 @@
+.\"	$OpenBSD: yppush.8,v 1.4 1997/05/01 21:08:49 niklas Exp $
+.\" Copyright (c) 1995 Mats O Jansson <moj@stacken.kth.se>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"      This product includes software developed by Mats O Jansson
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd January 29, 1995
+.Dt YPPUSH 8
+.Os
+.Sh NAME
+.Nm yppush
+.Nd force distribution of YP map
+.Sh SYNOPSIS
+.Nm yppush
+.Op Fl d Ar domainname
+.Op Fl h Ar hostname
+.\" .Op Fl p Ar paralleljobs
+.\" .Op Fl t Ar timeout
+.Op Fl v
+.Ar mapname
+.Sh DESCRIPTION
+.Nm yppush
+is used to distribute an YP map from a master server to any
+slave server in the domain. All servers of the domain is fetched from the YP
+map ypservers.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl d Ar domainname
+Don't use default domain, use the specified domain.
+.It Fl h Ar hostname
+Distribute map only to one host and not to the hosts in the ypserver map.
+.\" .It Fl p Ar paralleljobs
+.\"Set the number of parallel transfers.
+.\".It Fl t Ar timeout
+.\"Set the amount of time to elapse before a timeout is registered.
+.It Fl v
+Verbose. Announce what the program is doing.
+.El
+.Sh SEE ALSO
+.Xr yp 8 ,
+.Xr ypserv 8 
+.Sh AUTHOR
+Mats O Jansson
diff --git a/yppush.tproj/yppush.c b/yppush.tproj/yppush.c
new file mode 100644
index 0000000..5ddd82c
--- /dev/null
+++ b/yppush.tproj/yppush.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppush.c,v 1.10 1997/11/10 05:49:17 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1995 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: yppush.c,v 1.10 1997/11/10 05:49:17 deraadt Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/signal.h>
+#include <sys/wait.h>
+#include <netdb.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "yplib_host.h"
+#include "ypdef.h"
+#include "ypdb.h"
+
+int  Verbose = 0;
+char Domain[MAXHOSTNAMELEN], Map[255];
+u_int32_t OrderNum;
+char *master;
+
+extern void yppush_xfrrespprog_1(struct svc_req *request, SVCXPRT *xprt);
+extern bool_t xdr_ypreq_xfr(XDR *, struct ypreq_xfr *);
+
+void
+usage()
+{
+	fprintf(stderr, "Usage:\n");
+/*
+	fprintf(stderr, "\typpush [-d domainname] [-t seconds] [-p #paralleljobs] [-h host] [-v] mapname\n");
+*/
+	fprintf(stderr, "\typpush [-d domainname] [-h host] [-v] mapname\n");
+	exit(1);
+}
+
+void
+_svc_run()
+{
+	fd_set readfds;
+	struct timeval timeout;
+
+	timeout.tv_sec=60; timeout.tv_usec=0;
+
+	for(;;) {
+		readfds = svc_fdset;
+		switch (select(_rpc_dtablesize(), &readfds, (void *) 0,
+			       (void *) 0, &timeout)) {
+		case -1:
+			if (errno == EINTR) {
+				continue;
+			}
+			perror("yppush: _svc_run: select failed");
+			return;
+		case 0:
+			fprintf(stderr, "yppush: Callback timed out.\n");
+			exit(0);
+		default:
+			svc_getreqset(&readfds);
+		}
+	}
+	
+}
+
+void
+req_xfr(pid, prog, transp, host, client)
+pid_t pid;
+u_int prog;
+SVCXPRT *transp;
+char *host;
+CLIENT *client;
+{
+	struct ypreq_xfr request;
+	struct timeval tv;
+
+	tv.tv_sec=0; tv.tv_usec=0;
+
+	request.map_parms.domain=(char *)&Domain;
+	request.map_parms.map=(char *)&Map;
+	request.map_parms.peer=master;
+	request.map_parms.ordernum=OrderNum;
+	request.transid=(u_int)pid;
+	request.prog=prog;
+	request.port=transp->xp_port;
+
+	if (Verbose)
+		printf("%d: %s(%u@%s) -> %s@%s\n",
+		       request.transid,
+		       request.map_parms.map,
+		       request.map_parms.ordernum,
+		       host,
+		       request.map_parms.peer,
+		       request.map_parms.domain);
+	switch (clnt_call(client, YPPROC_XFR, xdr_ypreq_xfr, &request,
+			  xdr_void, NULL, tv)) {
+	case RPC_SUCCESS:
+	case RPC_TIMEDOUT:
+		break;
+	default:
+		clnt_perror(client, "yppush: Cannot call YPPROC_XFR");
+		kill(pid, SIGTERM);
+	}
+}
+
+void
+push(inlen, indata)
+int inlen;
+char *indata;
+{
+	char host[MAXHOSTNAMELEN];
+	CLIENT *client;
+	SVCXPRT *transp;
+	int sock = RPC_ANYSOCK;
+	u_int prog;
+	bool_t sts;
+	pid_t pid;
+	int status;
+	struct rusage res;
+
+	snprintf(host,sizeof host,"%*.*s" ,inlen ,inlen, indata);
+
+	client = clnt_create(host, YPPROG, YPVERS, "tcp");
+	if (client == NULL) {
+		if (Verbose)
+			fprintf(stderr,"Target Host: %s\n",host);
+		clnt_pcreateerror("yppush: Cannot create client");
+		return;
+	}
+
+	transp = svcudp_create(sock);
+	if (transp == NULL) {
+		fprintf(stderr, "yppush: Cannot create callback transport.\n");
+		return;
+	}
+	if (transp->xp_port >= IPPORT_RESERVED) {
+		SVC_DESTROY(transp);
+		fprintf(stderr, "yppush: Cannot allocate reserved port.\n");
+		return;
+	}
+
+	for (prog=0x40000000; prog<0x5fffffff; prog++) {
+		if (sts = svc_register(transp, prog, 1,
+		    yppush_xfrrespprog_1, IPPROTO_UDP))
+			break;
+	}
+
+	if (!sts) {
+		fprintf(stderr, "yppush: Cannot register callback.\n");
+		return;
+	}
+
+	switch(pid=fork()) {
+	case -1:
+		fprintf(stderr, "yppush: Cannot fork.\n");
+		exit(1);
+	case 0:
+		_svc_run();
+		exit(0);
+	default:
+		close(transp->xp_sock);
+		transp->xp_sock = -1;
+		req_xfr(pid, prog, transp, host, client);
+		wait4(pid, &status, 0, &res);
+		svc_unregister(prog, 1);
+		if (client != NULL)
+			clnt_destroy(client);
+		/* XXX transp leak? */
+	}
+
+}
+
+int
+pushit(instatus, inkey, inkeylen, inval, invallen, indata)
+int instatus;
+char *inkey;
+int inkeylen;
+char *inval;
+int invallen;
+char *indata;
+{
+	if(instatus != YP_TRUE)
+		return instatus;
+	push(invallen, inval);
+	return 0;
+}
+
+int
+main(argc, argv)
+int  argc;
+char **argv;
+{
+	struct ypall_callback ypcb;
+	extern char *optarg;
+	extern int optind;
+	char	*domain,*map,*hostname,*parallel,*timeout;
+	int c, r, i;
+	char *ypmap = "ypservers";
+	CLIENT *client;
+	static char map_path[MAXPATHLEN];
+	struct stat finfo;
+	DBM *yp_databas;
+	char order_key[YP_LAST_LEN] = YP_LAST_KEY;
+	datum o;
+
+        yp_get_default_domain(&domain);
+	hostname = NULL;
+/*
+	while( (c=getopt(argc, argv, "d:h:p:t:v?")) != -1)
+*/
+	while( (c=getopt(argc, argv, "d:h:v?")) != -1)
+		switch(c) {
+		case 'd':
+                        domain = optarg;
+			break;
+		case 'h':
+			hostname = optarg;
+			break;
+		case 'p':
+			parallel = optarg;
+			break;
+		case 't':
+			timeout = optarg;
+			break;
+                case 'v':
+                        Verbose = 1;
+                        break;
+                case '?':
+                        usage();
+                        /*NOTREACHED*/
+		}
+
+	if(optind + 1 != argc )
+		usage();
+
+	map = argv[optind];
+
+	strncpy(Domain,domain,sizeof(Domain)-1);
+	Domain[sizeof(Domain)-1] = '\0';
+	strncpy(Map,map,sizeof(Map)-1);
+	Map[sizeof(Map)-1] = '\0';
+
+	/* Check domain */
+	snprintf(map_path,sizeof map_path,"%s/%s",YP_DB_PATH,domain);
+	if (!((stat(map_path, &finfo) == 0) &&
+	      ((finfo.st_mode & S_IFMT) == S_IFDIR))) {
+	  	fprintf(stderr,"yppush: Map does not exist.\n");
+		exit(1);
+	}
+		
+	
+	/* Check map */
+	snprintf(map_path,sizeof map_path,"%s/%s/%s%s",
+	    YP_DB_PATH,domain,Map,YPDB_SUFFIX);
+	if (!(stat(map_path, &finfo) == 0)) {
+		fprintf(stderr,"yppush: Map does not exist.\n");
+		exit(1);
+	}
+		
+	snprintf(map_path,sizeof map_path,"%s/%s/%s",YP_DB_PATH,domain,Map);
+	yp_databas = ypdb_open(map_path,0,O_RDONLY);
+	OrderNum=0xffffffff;
+	if (yp_databas == 0) {
+		fprintf(stderr, "yppush: %s%s: Cannot open database\n",
+			map_path, YPDB_SUFFIX);
+	} else {
+		o.dptr = (char *) &order_key;
+		o.dsize = YP_LAST_LEN;
+		o=ypdb_fetch(yp_databas,o);
+		if (o.dptr == NULL) {
+			fprintf(stderr,
+				"yppush: %s: Cannot determine order number\n",
+				Map);
+		} else {
+			OrderNum=0;
+			for(i=0; i<o.dsize-1; i++) {
+				if (!isdigit(o.dptr[i])) {
+					OrderNum=0xffffffff;
+				}
+			}
+			if (OrderNum != 0) {
+				fprintf(stderr,
+					"yppush: %s: Invalid order number '%s'\n",
+					Map,
+					o.dptr);
+			} else {
+				OrderNum = atoi(o.dptr);
+			}
+		}
+        }
+	
+
+	yp_bind(Domain);
+
+	r = yp_master(Domain, ypmap, &master);
+        if (r != 0) {
+		fprintf(stderr, "yppush: could not get ypservers map\n");
+		exit(1);
+	}
+
+	if (hostname != NULL) {
+	  push(strlen(hostname), hostname);
+	} else {
+	  
+	  if (Verbose) {
+		printf("Contacting master for ypservers (%s).\n", master);
+	  }
+
+	  client = yp_bind_host(master, YPPROG, YPVERS, 0, 1);
+
+	  ypcb.foreach = pushit;
+	  ypcb.data = NULL;
+
+	  r = yp_all_host(client,Domain, ypmap, &ypcb);
+	}
+        
+        exit(0);
+}
+
diff --git a/yppush.tproj/yppush.h b/yppush.tproj/yppush.h
new file mode 100644
index 0000000..9aa8dc5
--- /dev/null
+++ b/yppush.tproj/yppush.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppush.h,v 1.3 1997/07/25 20:12:32 mickey Exp $ */
+
+/*
+ * Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPPUSH_H_RPCGEN
+#define _YPPUSH_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+enum yppush_status {
+	YPPUSH_SUCC = 1,
+	YPPUSH_AGE = 2,
+	YPPUSH_NOMAP = -1,
+	YPPUSH_NODOM = -2,
+	YPPUSH_RSRC = -3,
+	YPPUSH_RPC = -4,
+	YPPUSH_MADDR = -5,
+	YPPUSH_YPERR = -6,
+	YPPUSH_BADARGS = -7,
+	YPPUSH_DBM = -8,
+	YPPUSH_FILE = -9,
+	YPPUSH_SKEW = -10,
+	YPPUSH_CLEAR = -11,
+	YPPUSH_FORCE = -12,
+	YPPUSH_XFRERR = -13,
+	YPPUSH_REFUSED = -14,
+};
+typedef enum yppush_status yppush_status;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_yppush_status(XDR *, yppush_status*);
+#elif defined(__STDC__)
+extern  bool_t xdr_yppush_status(XDR *, yppush_status*);
+#else /* Old Style C */ 
+bool_t xdr_yppush_status();
+#endif /* Old Style C */ 
+
+
+struct yppushresp_xfr {
+	u_int transid;
+	yppush_status status;
+};
+typedef struct yppushresp_xfr yppushresp_xfr;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_yppushresp_xfr(XDR *, yppushresp_xfr*);
+#elif defined(__STDC__)
+extern  bool_t xdr_yppushresp_xfr(XDR *, yppushresp_xfr*);
+#else /* Old Style C */ 
+bool_t xdr_yppushresp_xfr();
+#endif /* Old Style C */ 
+
+
+#define YPPUSH_XFRRESPPROG ((u_long)0x40000000)
+#define YPPUSH_XFRRESPVERS ((u_long)1)
+
+#ifdef __cplusplus
+#define YPPUSHPROC_NULL ((u_long)0)
+extern "C" void * yppushproc_null_1(void *, CLIENT *);
+extern "C" void * yppushproc_null_1_svc(void *, struct svc_req *);
+#define YPPUSHPROC_XFRRESP ((u_long)1)
+extern "C" void * yppushproc_xfrresp_1(yppushresp_xfr *, CLIENT *);
+extern "C" void * yppushproc_xfrresp_1_svc(yppushresp_xfr *, struct svc_req *);
+
+#elif defined(__STDC__)
+#define YPPUSHPROC_NULL ((u_long)0)
+extern  void * yppushproc_null_1(void *, CLIENT *);
+extern  void * yppushproc_null_1_svc(void *, struct svc_req *);
+#define YPPUSHPROC_XFRRESP ((u_long)1)
+extern  void * yppushproc_xfrresp_1(yppushresp_xfr *, CLIENT *);
+extern  void * yppushproc_xfrresp_1_svc(yppushresp_xfr *, struct svc_req *);
+
+#else /* Old Style C */ 
+#define YPPUSHPROC_NULL ((u_long)0)
+extern  void * yppushproc_null_1();
+extern  void * yppushproc_null_1_svc();
+#define YPPUSHPROC_XFRRESP ((u_long)1)
+extern  void * yppushproc_xfrresp_1();
+extern  void * yppushproc_xfrresp_1_svc();
+#endif /* Old Style C */ 
+
+#endif /* !_YPPUSH_H_RPCGEN */
diff --git a/yppush.tproj/yppush_err.c b/yppush.tproj/yppush_err.c
new file mode 100644
index 0000000..31f74e8
--- /dev/null
+++ b/yppush.tproj/yppush_err.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppush_err.c,v 1.2 1996/05/30 09:53:20 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: yppush_err.c,v 1.2 1996/05/30 09:53:20 deraadt Exp $";
+#endif /* not lint */
+
+#include <rpc/rpc.h>
+#include <rpcsvc/yp.h>
+
+char *
+yppush_err_string(enum yppush_status y) {
+	switch(y) {
+	case YPPUSH_SUCC:
+			return "Success";
+	case YPPUSH_AGE:
+			return "Master's version not newer";
+	case YPPUSH_NOMAP:
+			return "Can't find server for map";
+	case YPPUSH_NODOM:
+			return "Domain not supported";
+	case YPPUSH_RSRC:
+			return "Local resource alloc failure";
+	case YPPUSH_RPC:
+			return "RPC failure talking to server";
+	case YPPUSH_MADDR:
+			return "Can't get master address";
+	case YPPUSH_YPERR:
+			return "YP server/map db error";
+	case YPPUSH_BADARGS:
+			return "Request arguments bad";
+	case YPPUSH_DBM:
+			return "Local dbm operation failed";
+	case YPPUSH_FILE:
+			return "Local file I/O operation failed";
+	case YPPUSH_SKEW:
+			return "Map version skew during transfer";
+	case YPPUSH_CLEAR:
+			return "Can't send \"Clear\" req to local ypserv";
+	case YPPUSH_FORCE:
+			return "No local order number in map  use -f flag.";
+	case YPPUSH_XFRERR:
+			return "ypxfr error";
+	case YPPUSH_REFUSED:
+			return "Transfer request refused by ypserv";
+        }
+};
diff --git a/yppush.tproj/yppush_proc.c b/yppush.tproj/yppush_proc.c
new file mode 100644
index 0000000..601a7cb
--- /dev/null
+++ b/yppush.tproj/yppush_proc.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppush_proc.c,v 1.3 1997/08/21 12:52:08 maja Exp $ */
+
+/*
+ * Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: yppush_proc.c,v 1.3 1997/08/21 12:52:08 maja Exp $";
+#endif /* not lint */
+
+#include <stdio.h>
+#include "yppush.h"
+
+extern int Verbose;
+
+void * 
+yppushproc_null_1_svc(argp, rqstp)
+	void *argp;
+	struct svc_req *rqstp;
+{
+
+	static char* result;
+
+	/*
+	 * insert server code here
+	 */
+	return((void*) &result);
+}
+
+void * 
+yppushproc_xfrresp_1_svc(argp, rqstp)
+	yppushresp_xfr *argp;
+	struct svc_req *rqstp;
+{
+
+	static char* result;
+
+	/*
+	 * insert server code here
+	 */
+	if ((argp->status<YPPUSH_SUCC) || Verbose)
+		fprintf(stderr,"yppush: %s\n",
+				yppush_err_string(argp->status));
+
+	return((void*) &result);
+}
diff --git a/yppush.tproj/yppush_svc.c b/yppush.tproj/yppush_svc.c
new file mode 100644
index 0000000..f3c19dc
--- /dev/null
+++ b/yppush.tproj/yppush_svc.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppush_svc.c,v 1.2 1996/05/30 09:53:22 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: yppush_svc.c,v 1.2 1996/05/30 09:53:22 deraadt Exp $";
+#endif /* not lint */
+
+#include "yppush.h"
+#include <stdio.h>
+#include <stdlib.h>/* getenv, exit */
+#include <netdb.h>
+#include <signal.h>
+#include <sys/ttycom.h>/* TIOCNOTTY */
+#include <memory.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#ifdef SYSLOG
+#include <syslog.h>
+#else
+#define LOG_ERR 1
+#define openlog(a, b, c)
+#endif
+
+#ifdef __STDC__
+#define SIG_PF void(*)(int)
+#endif
+
+#ifdef DEBUG
+#define RPC_SVC_FG
+#endif
+
+#define _RPCSVC_CLOSEDOWN 120
+int _rpcpmstart;		/* Started by a port monitor ? */
+int _rpcfdtype;			/* Whether Stream or Datagram ? */
+int _rpcsvcdirty;		/* Still serving ? */
+
+static
+void _msgout(msg)
+	char *msg;
+{
+#ifdef RPC_SVC_FG
+	if (_rpcpmstart)
+		syslog(LOG_ERR, msg);
+	else
+		(void) fprintf(stderr, "%s\n", msg);
+#else
+	syslog(LOG_ERR, msg);
+#endif
+}
+
+void
+yppush_xfrrespprog_1(rqstp, transp)
+	struct svc_req *rqstp;
+	register SVCXPRT *transp;
+{
+	union {
+		int fill;
+	} argument;
+	char *result;
+	bool_t (*xdr_argument)(), (*xdr_result)();
+	char *(*local)();
+
+	_rpcsvcdirty = 1;
+	switch (rqstp->rq_proc) {
+	case YPPUSHPROC_NULL:
+		xdr_argument = xdr_void;
+		xdr_result = xdr_void;
+		local = (char *(*)()) yppushproc_null_1_svc;
+		break;
+
+	case YPPUSHPROC_XFRRESP:
+		xdr_argument = xdr_yppushresp_xfr;
+		xdr_result = xdr_void;
+		local = (char *(*)()) yppushproc_xfrresp_1_svc;
+		break;
+
+	default:
+		svcerr_noproc(transp);
+		_rpcsvcdirty = 0;
+		exit(1);
+		return;
+	}
+	(void) memset((char *)&argument, 0, sizeof (argument));
+	if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) {
+		svcerr_decode(transp);
+		_rpcsvcdirty = 0;
+		exit(1);
+		return;
+	}
+	result = (*local)(&argument, rqstp);
+	if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
+		svcerr_systemerr(transp);
+	}
+	if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) {
+		_msgout("unable to free arguments");
+		exit(1);
+	}
+	_rpcsvcdirty = 0;
+	if (rqstp->rq_proc!=YPPUSHPROC_NULL)
+		exit(0);
+	return;
+}
diff --git a/yppush.tproj/yppush_xdr.c b/yppush.tproj/yppush_xdr.c
new file mode 100644
index 0000000..d8ad787
--- /dev/null
+++ b/yppush.tproj/yppush_xdr.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppush_xdr.c,v 1.2 1996/05/30 09:53:22 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: yppush_xdr.c,v 1.2 1996/05/30 09:53:22 deraadt Exp $";
+#endif
+
+#include <rpc/rpc.h>
+#include <rpcsvc/yp.h>
+
+__private_extern__
+bool_t
+xdr_domainname(xdrs, objp)
+	XDR *xdrs;
+	domainname *objp;
+{
+	if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_mapname(xdrs, objp)
+	XDR *xdrs;
+	mapname *objp;
+{
+	if (!xdr_string(xdrs, objp, YPMAXMAP)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_peername(xdrs, objp)
+	XDR *xdrs;
+	peername *objp;
+{
+	if (!xdr_string(xdrs, objp, YPMAXPEER)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_ypmap_parms(xdrs, objp)
+	XDR *xdrs;
+	ypmap_parms *objp;
+{
+	if (!xdr_domainname(xdrs, &objp->domain)) {
+		return (FALSE);
+	}
+	if (!xdr_mapname(xdrs, &objp->map)) {
+		return (FALSE);
+	}
+	if (!xdr_u_int(xdrs, &objp->ordernum)) {
+		return (FALSE);
+	}
+	if (!xdr_peername(xdrs, &objp->peer)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_ypreq_xfr(xdrs, objp)
+	XDR *xdrs;
+	ypreq_xfr *objp;
+{
+	if (!xdr_ypmap_parms(xdrs, &objp->map_parms)) {
+		return (FALSE);
+	}
+	if (!xdr_u_int(xdrs, &objp->transid)) {
+		return (FALSE);
+	}
+	if (!xdr_u_int(xdrs, &objp->prog)) {
+		return (FALSE);
+	}
+	if (!xdr_u_int(xdrs, &objp->port)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_yppush_status(xdrs, objp)
+	XDR *xdrs;
+	yppush_status *objp;
+{
+	 register long *buf;
+
+	 if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+bool_t
+xdr_yppushresp_xfr(xdrs, objp)
+	XDR *xdrs;
+	yppushresp_xfr *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_u_int(xdrs, &objp->transid)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_yppush_status(xdrs, &objp->status)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+
+
diff --git a/ypserv.tproj/Makefile b/ypserv.tproj/Makefile
new file mode 100644
index 0000000..626fbef
--- /dev/null
+++ b/ypserv.tproj/Makefile
@@ -0,0 +1,52 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ypserv
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = acl.h yp.h ypv1.h ypdb.h yplog.h ypdef.h
+
+CFILES = acl.c ypdb.c yplog.c ypserv.c ypserv_db.c ypserv_proc.c\
+         ypserv_xdr.c ypserv_xdr_v1.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble securenet\
+            securenet.5 ypserv.acl ypserv.acl.5
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/libexec
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/$(USER)/BUILD
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ypserv.tproj/Makefile.postamble b/ypserv.tproj/Makefile.postamble
new file mode 100644
index 0000000..509e7f5
--- /dev/null
+++ b/ypserv.tproj/Makefile.postamble
@@ -0,0 +1,101 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGE: langage in which the project is written (default "English")
+#  LOCAL_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/ypserv.tproj/Makefile.preamble b/ypserv.tproj/Makefile.preamble
new file mode 100644
index 0000000..83f25c7
--- /dev/null
+++ b/ypserv.tproj/Makefile.preamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. <<default?>>
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSION: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
diff --git a/ypserv.tproj/PB.project b/ypserv.tproj/PB.project
new file mode 100644
index 0000000..c7cbbbb
--- /dev/null
+++ b/ypserv.tproj/PB.project
@@ -0,0 +1,45 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (acl.h, yp.h, ypv1.h, ypdb.h, yplog.h, ypdef.h); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (
+            acl.c, 
+            ypdb.c, 
+            yplog.c, 
+            ypserv.c, 
+            ypserv_db.c, 
+            ypserv_proc.c, 
+            ypserv_xdr.c, 
+            ypserv_xdr_v1.c
+        ); 
+        OTHER_SOURCES = (
+            Makefile.preamble, 
+            Makefile, 
+            Makefile.postamble, 
+            securenet, 
+            securenet.5, 
+            ypserv.acl, 
+            ypserv.acl.5
+        ); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDDIR = "/tmp/$(USER)/BUILD"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/libexec; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ypserv; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ypserv.tproj/acl.c b/ypserv.tproj/acl.c
new file mode 100644
index 0000000..14e767f
--- /dev/null
+++ b/ypserv.tproj/acl.c
@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: acl.c,v 1.5 1997/08/05 09:26:55 maja Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: acl.c,v 1.5 1997/08/05 09:26:55 maja Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <netdb.h>
+#include "acl.h"
+
+#define TRUE 1
+#define FALSE 0
+
+static	struct aclent *acl_root = NULL;
+
+static int acl_read_line(fp, buf, size)
+FILE *fp;
+char *buf;
+int size;
+{
+  int   len = 0;
+  char *c,*p,l;
+
+  /* Read a line, and remove any comment, trim space */
+
+  do {
+    while (fgets(buf, size, fp)) {
+      c = buf;
+      while(*c != '\0') {
+	if ((*c == '#') || (*c == '\n')) {
+	  *c = '\0';
+	} else {
+	  c++;
+	}
+      }
+
+      c = p = buf; l = ' ';
+      while(*c != '\0') {
+	if ((isspace(l) != 0) && (isspace(*c) != 0)) {
+	  c++;
+	} else {
+	  l = *c++; *p = l; p++;
+	}
+      }
+      *p = '\0';
+      
+      if (p != buf) {
+	--p;
+	if (isspace(*p) != 0) {
+	  *p = '\0';
+	}
+      }
+
+      len = strlen(buf);
+      return len + 1;
+    }
+  } while (size > 0 && !feof(fp));
+  
+  return len;
+}
+
+int
+acl_check_host(addr)
+struct in_addr *addr;
+{
+  struct aclent *p;
+  
+  p = acl_root;
+  while (p != NULL) {
+    if ((addr->s_addr & p->s_mask) == p->s_addr) {
+      return(p->allow);
+    }
+    p = p->next;
+  }
+  return(TRUE);
+}
+
+void
+acl_add_net(allow,addr,mask)
+int	allow;
+struct in_addr *addr,*mask;
+{
+  
+  struct aclent *acl,*p;
+  
+  acl = (struct aclent *) malloc((unsigned) sizeof(struct aclent));
+  
+  acl->next   = NULL;
+  acl->allow  = allow;
+  acl->s_addr = addr->s_addr;
+  acl->s_mask = mask->s_addr;
+  
+  if (acl_root == NULL) {
+    acl_root = acl;
+  } else {
+    p = acl_root;
+    while (p->next != NULL)
+      p = p->next;
+    p->next = acl;
+  }
+  
+} 
+
+void
+acl_add_host(allow,addr)
+int	allow;
+struct in_addr *addr;
+{
+  	struct in_addr mask;
+
+	mask.s_addr = htonl(0xffffffff);
+	
+	acl_add_net(allow,addr,&mask);
+}
+
+int
+acl_init(file)
+char *file;
+{
+  char	 data_line[1024];
+  int	 line_no = 0;
+  int	 len,i;
+  int	 allow = TRUE;
+  int	 error_cnt = 0;
+  char	*p,*k;
+  int	 state;
+  struct in_addr addr,mask,*host_addr;
+  struct hostent *host;
+  struct netent  *net;
+  FILE  *data_file = NULL;
+  
+  if (file != NULL) {
+    data_file = fopen(file,"r");
+  };
+
+  while ((data_file != NULL) &&
+	 (acl_read_line(data_file,data_line,sizeof(data_line)))) {
+    
+    line_no++;
+    
+    len = strlen(data_line);
+    if (len == 0) {
+      continue;
+    }
+
+    p = (char *) &data_line;
+
+    /* State 1: Initial State */
+
+    state = ACLS_INIT;
+    addr.s_addr = mask.s_addr = 0;
+
+    k = p; i = 0;				/* save start of verb */
+    while ((*p != '\0') &&
+	   (!isspace(*p = tolower(*p)))) {
+      p++; i++;
+    };
+
+    if (*p != '\0') {
+      *p++ = '\0';
+    }
+
+    if (strcmp(k,"allow") == 0) {
+      allow = TRUE;
+      state = ACLS_ALLOW;
+    }
+
+    if (strcmp(k,"deny") == 0) {
+      allow = FALSE;
+      state = ACLS_DENY;
+    }
+
+    if (state == ACLS_INIT) {
+      state = ACLE_UVERB;
+    }
+
+    /* State 2: allow row */
+    /* State 3: deny row */
+
+    if ((*p != '\0') &&
+	((state == ACLS_ALLOW) || (state == ACLS_DENY))) {
+      
+      k = p; i = 0;				/* save start of verb */
+      while ((*p != '\0') &&
+	     (!isspace(*p = tolower(*p)))) {
+	p++; i++;
+      };
+      
+      if (*p != '\0') {
+	*p++ = '\0';
+      }
+
+      if (strcmp(k,"all") == 0) {
+	state = state + ACLD_ALL;
+      }
+
+      if (strcmp(k,"host") == 0) {
+	state = state + ACLD_HOST;
+      }
+
+      if (strcmp(k,"net") == 0) {
+	state = state + ACLD_NET;
+      }
+
+      if ((state == ACLS_ALLOW) || (state == ACLS_DENY)) {
+	state = ACLE_U2VERB;
+      }
+      
+    }
+
+    if ((state == ACLS_ALLOW) || (state == ACLS_DENY)) {
+      state = ACLE_UEOL;
+    }
+
+    /* State 4 & 5: all state, remove any comment */
+
+    if ((*p == '\0') &&
+	((state == ACLS_ALLOW_ALL) || (state == ACLS_DENY_ALL))) {
+      acl_add_net(allow,&addr,&mask);
+      state = ACLE_OK;
+    }
+      
+    /* State 6 & 7: host line */
+    /* State 8 & 9: net line */
+
+    if ((*p != '\0') &&
+	(state >= ACLS_ALLOW_HOST) && (state <= ACLS_DENY_NET)) {
+      
+      k = p; i = 0;				/* save start of verb */
+      while ((*p != '\0') &&
+	     (!isspace(*p = tolower(*p)))) {
+	p++; i++;
+      };
+      
+      if (*p != '\0') {
+	*p++ = '\0';
+      }
+      
+      if ((state == ACLS_ALLOW_HOST) || (state == ACLS_DENY_HOST)) {
+	if ((*k >= '0') && (*k <= '9')) {
+	  (void)inet_aton(k,&addr);
+	  acl_add_host(allow,&addr);
+	  state = state + ACLD_HOST_DONE;
+        } else {
+	  host = gethostbyname(k);
+	  if (host == NULL) {
+	    state = ACLE_NOHOST;
+	  } else {
+	    if (host->h_addrtype == AF_INET) {
+	      while ((host_addr = (struct in_addr *) *host->h_addr_list++)
+		     != NULL)
+		acl_add_host(allow,host_addr);
+	    }
+	    state = state + ACLD_HOST_DONE;
+	  }
+	}
+      }
+
+      if ((state == ACLS_ALLOW_NET) || (state == ACLS_DENY_NET)) {
+	if ((*k >= '0') && (*k <= '9')) {
+	  (void)inet_aton(k,&addr);
+	  state = state + ACLD_NET_DONE;
+        } else {
+	  net = getnetbyname(k);
+	  if (net == NULL) {
+	    state = ACLE_NONET;
+	  } else {
+	    addr.s_addr = ntohl(net->n_net);
+	    state = state + ACLD_NET_DONE;
+	  }
+	}
+      }
+
+    }
+
+    if ((state >= ACLS_ALLOW_HOST) && (state <= ACLS_DENY_NET)) {
+      state = ACLE_UEOL;
+    }
+
+    /* State 10 & 11: allow/deny host line */
+
+    if ((*p == '\0') &&
+	((state == ACLS_ALLOW_HOST_DONE) || (state == ACLS_DENY_HOST_DONE))) {
+      state = ACLE_OK;
+    }
+      
+    /* State 12 & 13: allow/deny net line */
+
+    if ((*p == '\0') &&
+	((state == ACLS_ALLOW_NET_DONE) || (state == ACLS_DENY_NET_DONE))) {
+      mask.s_addr = htonl(0xffffff00);
+      if (ntohl(addr.s_addr) < 0xc0000000) {
+	mask.s_addr = htonl(0xffff0000);
+      }
+      if (ntohl(addr.s_addr) < 0x80000000) {
+	mask.s_addr = htonl(0xff000000);
+      }
+      acl_add_net(allow,&addr,&mask);
+      state = ACLE_OK;
+    }
+
+    if ((*p != '\0') &&
+	((state == ACLS_ALLOW_NET_DONE) || (state == ACLS_DENY_NET_DONE))) {
+      
+      k = p; i = 0;				/* save start of verb */
+      while ((*p != '\0') &&
+	     (!isspace(*p = tolower(*p)))) {
+	p++; i++;
+      };
+      
+      if (*p != '\0') {
+	*p++ = '\0';
+      }
+
+      if (strcmp(k,"netmask") == 0) {
+	state = state + ACLD_NET_MASK;
+      }
+
+      if ((state == ACLS_ALLOW_NET_DONE) || (state == ACLS_DENY_NET_DONE)) {
+	state = ACLE_NONETMASK;
+      }
+      
+    }
+
+    /* State 14 & 15: allow/deny net netmask line */
+
+    if ((*p != '\0') &&
+	((state == ACLS_ALLOW_NET_MASK) || (state == ACLS_DENY_NET_MASK))) {
+      
+      k = p; i = 0;				/* save start of verb */
+      while ((*p != '\0') &&
+	     (!isspace(*p = tolower(*p)))) {
+	p++; i++;
+      };
+      
+      if (*p != '\0') {
+	*p++ = '\0';
+      }
+
+      if ((state == ACLS_ALLOW_NET_MASK) || (state == ACLS_DENY_NET_MASK)) {
+	if ((*k >= '0') && (*k <= '9')) {
+	  (void)inet_aton(k,&mask);
+	  state = state + ACLD_NET_EOL;
+        } else {
+	  net = getnetbyname(k);
+	  if (net == NULL) {
+	    state = ACLE_NONET;
+	  } else {
+	    mask.s_addr = ntohl(net->n_net);
+	    state = state + ACLD_NET_EOL;
+	  }
+	}
+      }
+
+    }
+
+    if ((state == ACLS_ALLOW_NET_MASK) || (state == ACLS_DENY_NET_MASK)) {
+      state = ACLE_UEOL;
+    }
+
+    /* State 16 & 17: allow/deny host line */
+
+    if ((*p == '\0') &&
+	((state == ACLS_ALLOW_NET_EOL) || (state == ACLS_DENY_NET_EOL))) {
+      acl_add_net(allow,&addr,&mask);
+      state = ACLE_OK;
+    }
+      
+    switch (state) {
+    case  ACLE_NONETMASK:
+      fprintf(stderr,"acl: excpected \"netmask\" missing at line %d\n",line_no);
+      break;
+    case  ACLE_NONET:
+      error_cnt++;
+      fprintf(stderr,"acl: unknown network at line %d\n",line_no);
+      break;
+    case  ACLE_NOHOST:
+      error_cnt++;
+      fprintf(stderr,"acl: unknown host at line %d\n",line_no);
+      break;
+    case  ACLE_UVERB:
+      error_cnt++;
+      fprintf(stderr,"acl: unknown verb at line %d\n",line_no);
+      break;
+    case ACLE_U2VERB:
+      error_cnt++;
+      fprintf(stderr,"acl: unknown secondary verb at line %d\n",line_no);
+      break;
+    case ACLE_UEOL:
+      error_cnt++;
+      fprintf(stderr,"acl: unexpected end of line at line %d\n",line_no);
+      break;
+    case ACLE_OK:
+      break;
+    default:
+      error_cnt++;
+      fprintf(stderr,"acl: unexpected state %d %s\n",state,k);
+    }
+
+  }
+
+  if (data_file != NULL) {
+    (void)fflush(stderr);
+    (void)fclose(data_file);
+  }
+
+  /* Always add a last allow all if file don't exists or */
+  /* the file doesn't cover all cases.                   */
+  
+  addr.s_addr = mask.s_addr = 0;
+  allow = TRUE;
+  acl_add_net(allow,&addr,&mask);
+
+  return(error_cnt);
+
+}
+
+int
+acl_securenet(file)
+char *file;
+{
+  char	 data_line[1024];
+  int	 line_no = 0;
+  int	 len,i;
+  int	 allow = TRUE;
+  int	 error_cnt = 0;
+  char	*p,*k;
+  int	 state;
+  struct in_addr addr,mask;
+  struct netent  *net;
+  FILE  *data_file = NULL;
+  
+  if (file != NULL) {
+    data_file = fopen(file,"r");
+  };
+
+  /* Always add a localhost allow first, to be compatable with sun */
+  
+  addr.s_addr = htonl(0x7f000001);
+  mask.s_addr = htonl(0xffffffff);
+  allow = TRUE;
+  acl_add_net(allow,&addr,&mask);
+
+  while ((data_file != NULL) &&
+	 (acl_read_line(data_file,data_line,sizeof(data_line)))) {
+    
+    line_no++;
+    
+    len = strlen(data_line);
+    if (len == 0) {
+      continue;
+    }
+
+    p = (char *) &data_line;
+
+    /* State 1: Initial State */
+
+    state = ACLS_INIT;
+    addr.s_addr = mask.s_addr = 0;
+
+    k = p; i = 0;				/* save start of verb */
+    while ((*p != '\0') &&
+	   (!isspace(*p = tolower(*p)))) {
+      p++; i++;
+    };
+    
+    if (*p != '\0') {
+      *p++ = '\0';
+      state = ACLS_ALLOW_NET_MASK;
+    }
+    
+    if (state == ACLS_INIT) {
+      state = ACLE_UEOL;
+    }
+
+    if (state == ACLS_ALLOW_NET_MASK) {
+      
+      if ((*k >= '0') && (*k <= '9')) {
+	(void)inet_aton(k,&mask);
+	state = ACLS_ALLOW_NET;
+      } else {
+	net = getnetbyname(k);
+	if (net == NULL) {
+	  state = ACLE_NONET;
+	} else {
+	  mask.s_addr = ntohl(net->n_net);
+	  state = ACLS_ALLOW_NET;
+	}
+      }
+      
+      k = p; i = 0;				/* save start of verb */
+      while ((*p != '\0') &&
+	     (!isspace(*p = tolower(*p)))) {
+	p++; i++;
+      };
+      
+      if (*p != '\0') {
+	*p++ = '\0';
+      }
+    }
+    
+    if ((state == ACLS_ALLOW_NET_MASK)) {
+      state = ACLE_UEOL;
+    }
+
+    if (state == ACLS_ALLOW_NET) {
+      
+      if ((*k >= '0') && (*k <= '9')) {
+	(void)inet_aton(k,&addr);
+	state = ACLS_ALLOW_NET_EOL;
+      } else {
+	net = getnetbyname(k);
+	if (net == NULL) {
+	  state = ACLE_NONET;
+	} else {
+	  addr.s_addr = ntohl(net->n_net);
+	  state = ACLS_ALLOW_NET_EOL;
+	}
+      }
+    }
+      
+    if ((state == ACLS_ALLOW_NET)) {
+      state = ACLE_UEOL;
+    }
+
+    if ((*p == '\0') &&	(state == ACLS_ALLOW_NET_EOL)) {
+      acl_add_net(allow,&addr,&mask);
+      state = ACLE_OK;
+    }
+      
+    switch (state) {
+    case  ACLE_NONET:
+      error_cnt++;
+      fprintf(stderr,"securenet: unknown network at line %d\n",line_no);
+      break;
+    case ACLE_UEOL:
+      error_cnt++;
+      fprintf(stderr,"securenet: unexpected end of line at line %d\n",line_no);
+      break;
+    case ACLE_OK:
+      break;
+    default:
+      error_cnt++;
+      fprintf(stderr,"securenet: unexpected state %d %s\n",state,k);
+    }
+
+  }
+
+  if (data_file != NULL) {
+    (void)fflush(stderr);
+    (void)fclose(data_file);
+    
+    /* Always add a last deny all if file exists */
+    
+    addr.s_addr = mask.s_addr = 0;
+    allow = FALSE;
+    acl_add_net(allow,&addr,&mask);
+
+  }
+
+  /* Always add a last allow all if file don't exists */
+  
+  addr.s_addr = mask.s_addr = 0;
+  allow = TRUE;
+  acl_add_net(allow,&addr,&mask);
+
+  return(error_cnt);
+
+}
+
+void
+acl_reset()
+{
+	struct aclent *p;
+
+	while (acl_root != NULL) {
+		p = acl_root->next;
+		free(acl_root);
+		acl_root = p;
+	}
+}
diff --git a/ypserv.tproj/acl.h b/ypserv.tproj/acl.h
new file mode 100644
index 0000000..cb10663
--- /dev/null
+++ b/ypserv.tproj/acl.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: acl.h,v 1.4 1996/06/30 19:46:05 maja Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ACL_H_
+#define _ACL_H_
+
+#define ACLD_ALL		2
+#define ACLD_HOST		4
+#define ACLD_NET		6
+#define ACLD_HOST_DONE		4
+#define ACLD_NET_DONE		4
+#define ACLD_NET_MASK		2
+#define ACLD_NET_EOL		2
+
+#define ACLS_INIT		1
+#define ACLS_ALLOW		2
+#define ACLS_DENY		3
+#define ACLS_ALLOW_ALL		ACLS_ALLOW+ACLD_ALL		  /*  4 */
+#define ACLS_DENY_ALL		ACLS_DENY+ACLD_ALL		  /*  5 */
+#define ACLS_ALLOW_HOST		ACLS_ALLOW+ACLD_HOST		  /*  6 */
+#define ACLS_DENY_HOST		ACLS_DENY+ACLD_HOST		  /*  7 */
+#define ACLS_ALLOW_NET		ACLS_ALLOW+ACLD_NET		  /*  8 */
+#define ACLS_DENY_NET		ACLS_DENY+ACLD_NET		  /*  9 */
+#define ACLS_ALLOW_HOST_DONE	ACLS_ALLOW_HOST+ACLD_HOST_DONE	  /* 10 */
+#define ACLS_DENY_HOST_DONE	ACLS_DENY_HOST+ACLD_HOST_DONE	  /* 11 */
+#define ACLS_ALLOW_NET_DONE	ACLS_ALLOW_NET+ACLD_NET_DONE	  /* 12 */
+#define ACLS_DENY_NET_DONE	ACLS_DENY_NET+ACLD_NET_DONE	  /* 13 */
+#define ACLS_ALLOW_NET_MASK	ACLS_ALLOW_NET_DONE+ACLD_NET_MASK /* 14 */
+#define ACLS_DENY_NET_MASK	ACLS_DENY_NET_DONE+ACLD_NET_MASK  /* 15 */
+#define ACLS_ALLOW_NET_EOL	ACLS_ALLOW_NET_MASK+ACLD_NET_EOL  /* 16 */
+#define ACLS_DENY_NET_EOL	ACLS_DENY_NET_MASK+ACLD_NET_EOL   /* 17 */
+
+#define ACLE_NONETMASK		18
+#define ACLE_NONET		19
+#define ACLE_NOHOST		20
+#define ACLE_UVERB		21
+#define ACLE_U2VERB		22
+#define ACLE_UEOL		23
+#define ACLE_OK			24
+
+struct	aclent {
+struct	aclent	*next;
+	int	allow;
+	u_long	s_addr;
+	u_long	s_mask;
+};
+
+__BEGIN_DECLS
+int		acl_check_host __P((struct in_addr *));
+int		acl_init __P((char *));
+int		acl_securenet __P((char *));
+void		acl_reset __P((void));
+__END_DECLS
+
+#endif /* !_ACL_H_ */
+
+
diff --git a/ypserv.tproj/securenet b/ypserv.tproj/securenet
new file mode 100644
index 0000000..a136cfb
--- /dev/null
+++ b/ypserv.tproj/securenet
@@ -0,0 +1,4 @@
+#
+# Only my local net is secure. 
+#
+255.255.255.0 139.58.253.0
diff --git a/ypserv.tproj/securenet.5 b/ypserv.tproj/securenet.5
new file mode 100644
index 0000000..bb14ae7
--- /dev/null
+++ b/ypserv.tproj/securenet.5
@@ -0,0 +1,74 @@
+.\"	$OpenBSD: securenet.5,v 1.4 1996/06/26 21:26:37 maja Exp $
+.\" Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by Mats O Jansson
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd June 27, 1994
+.Dt SECURENET 5
+.Os
+.Sh NAME
+.Nm securenet
+.Nd 
+.Xr ypserv 8
+configuration file for secure networks
+.Sh DESCRIPTION
+The 
+.Nm securenet
+file controls which hosts can connect to the
+.Nm YP
+server.
+.Pp
+The format is rather simple. Each row consists of two items. The first item
+is the network mask. The second item is the network.
+.Sh EXAMPLES
+.Pp
+A configuration file might appear as follows:
+.Bd -literal
+#
+# Only my local net is secure. 
+#
+255.255.255.0 139.58.253.0
+.Ed
+.Sh FILES
+.Bl -tag -width /var/yp/securenet -compact
+.It Pa /var/yp/securenet
+A
+.Xr ypserv 8
+configuration file.
+.El
+.Sh SEE ALSO
+.Xr yp 8 ,
+.Xr ypserv 8 ,
+.Xr ypserv.acl 5
+.Sh HISTORY
+The
+.Nm securenet
+was added to
+.Nm NIS
+by Sun Microsystems, Inc. as a bugfix for weak security.
+
diff --git a/ypserv.tproj/yp.h b/ypserv.tproj/yp.h
new file mode 100644
index 0000000..cfe590b
--- /dev/null
+++ b/ypserv.tproj/yp.h
@@ -0,0 +1,612 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: yp.h,v 1.5 1997/07/25 20:12:31 mickey Exp $ */
+
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _YP_H_RPCGEN
+#define _YP_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+#define YPMAXRECORD 1024
+#define YPMAXDOMAIN 64
+#define YPMAXMAP 64
+#define YPMAXPEER 64
+
+enum ypstat {
+	YP_TRUE = 1,
+	YP_NOMORE = 2,
+	YP_FALSE = 0,
+	YP_NOMAP = -1,
+	YP_NODOM = -2,
+	YP_NOKEY = -3,
+	YP_BADOP = -4,
+	YP_BADDB = -5,
+	YP_YPERR = -6,
+	YP_BADARGS = -7,
+	YP_VERS = -8,
+};
+typedef enum ypstat ypstat;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypstat(XDR *, ypstat*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypstat(XDR *, ypstat*);
+#else /* Old Style C */ 
+bool_t xdr_ypstat();
+#endif /* Old Style C */ 
+
+
+enum ypxfrstat {
+	YPXFR_SUCC = 1,
+	YPXFR_AGE = 2,
+	YPXFR_NOMAP = -1,
+	YPXFR_NODOM = -2,
+	YPXFR_RSRC = -3,
+	YPXFR_RPC = -4,
+	YPXFR_MADDR = -5,
+	YPXFR_YPERR = -6,
+	YPXFR_BADARGS = -7,
+	YPXFR_DBM = -8,
+	YPXFR_FILE = -9,
+	YPXFR_SKEW = -10,
+	YPXFR_CLEAR = -11,
+	YPXFR_FORCE = -12,
+	YPXFR_XFRERR = -13,
+	YPXFR_REFUSED = -14,
+};
+typedef enum ypxfrstat ypxfrstat;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypxfrstat(XDR *, ypxfrstat*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypxfrstat(XDR *, ypxfrstat*);
+#else /* Old Style C */ 
+bool_t xdr_ypxfrstat();
+#endif /* Old Style C */ 
+
+
+typedef char *domainname;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_domainname(XDR *, domainname*);
+#elif defined(__STDC__)
+extern  bool_t xdr_domainname(XDR *, domainname*);
+#else /* Old Style C */ 
+bool_t xdr_domainname();
+#endif /* Old Style C */ 
+
+
+typedef char *mapname;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_mapname(XDR *, mapname*);
+#elif defined(__STDC__)
+extern  bool_t xdr_mapname(XDR *, mapname*);
+#else /* Old Style C */ 
+bool_t xdr_mapname();
+#endif /* Old Style C */ 
+
+
+typedef char *peername;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_peername(XDR *, peername*);
+#elif defined(__STDC__)
+extern  bool_t xdr_peername(XDR *, peername*);
+#else /* Old Style C */ 
+bool_t xdr_peername();
+#endif /* Old Style C */ 
+
+
+typedef struct {
+	u_int keydat_len;
+	char *keydat_val;
+} keydat;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_keydat(XDR *, keydat*);
+#elif defined(__STDC__)
+extern  bool_t xdr_keydat(XDR *, keydat*);
+#else /* Old Style C */ 
+bool_t xdr_keydat();
+#endif /* Old Style C */ 
+
+
+typedef struct {
+	u_int valdat_len;
+	char *valdat_val;
+} valdat;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_valdat(XDR *, valdat*);
+#elif defined(__STDC__)
+extern  bool_t xdr_valdat(XDR *, valdat*);
+#else /* Old Style C */ 
+bool_t xdr_valdat();
+#endif /* Old Style C */ 
+
+
+struct ypmap_parms {
+	domainname domain;
+	mapname map;
+	u_int32_t ordernum;
+	peername peer;
+};
+typedef struct ypmap_parms ypmap_parms;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypmap_parms(XDR *, ypmap_parms*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypmap_parms(XDR *, ypmap_parms*);
+#else /* Old Style C */ 
+bool_t xdr_ypmap_parms();
+#endif /* Old Style C */ 
+
+
+struct ypreq_key {
+	domainname domain;
+	mapname map;
+	keydat key;
+};
+typedef struct ypreq_key ypreq_key;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypreq_key(XDR *, ypreq_key*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypreq_key(XDR *, ypreq_key*);
+#else /* Old Style C */ 
+bool_t xdr_ypreq_key();
+#endif /* Old Style C */ 
+
+
+struct ypreq_nokey {
+	domainname domain;
+	mapname map;
+};
+typedef struct ypreq_nokey ypreq_nokey;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypreq_nokey(XDR *, ypreq_nokey*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypreq_nokey(XDR *, ypreq_nokey*);
+#else /* Old Style C */ 
+bool_t xdr_ypreq_nokey();
+#endif /* Old Style C */ 
+
+
+struct ypreq_xfr {
+	ypmap_parms map_parms;
+	u_int transid;
+	u_int prog;
+	u_int port;
+};
+typedef struct ypreq_xfr ypreq_xfr;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypreq_xfr(XDR *, ypreq_xfr*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypreq_xfr(XDR *, ypreq_xfr*);
+#else /* Old Style C */ 
+bool_t xdr_ypreq_xfr();
+#endif /* Old Style C */ 
+
+
+struct ypresp_val {
+	ypstat stat;
+	valdat val;
+};
+typedef struct ypresp_val ypresp_val;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypresp_val(XDR *, ypresp_val*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypresp_val(XDR *, ypresp_val*);
+#else /* Old Style C */ 
+bool_t xdr_ypresp_val();
+#endif /* Old Style C */ 
+
+
+struct ypresp_key_val {
+	ypstat stat;
+	keydat key;
+	valdat val;
+};
+typedef struct ypresp_key_val ypresp_key_val;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypresp_key_val(XDR *, ypresp_key_val*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypresp_key_val(XDR *, ypresp_key_val*);
+#else /* Old Style C */ 
+bool_t xdr_ypresp_key_val();
+#endif /* Old Style C */ 
+
+
+struct ypresp_master {
+	ypstat stat;
+	peername peer;
+};
+typedef struct ypresp_master ypresp_master;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypresp_master(XDR *, ypresp_master*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypresp_master(XDR *, ypresp_master*);
+#else /* Old Style C */ 
+bool_t xdr_ypresp_master();
+#endif /* Old Style C */ 
+
+
+struct ypresp_order {
+	ypstat stat;
+	u_int32_t ordernum;
+};
+typedef struct ypresp_order ypresp_order;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypresp_order(XDR *, ypresp_order*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypresp_order(XDR *, ypresp_order*);
+#else /* Old Style C */ 
+bool_t xdr_ypresp_order();
+#endif /* Old Style C */ 
+
+
+struct ypresp_all {
+	bool_t more;
+	union {
+		ypresp_key_val val;
+	} ypresp_all_u;
+};
+typedef struct ypresp_all ypresp_all;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypresp_all(XDR *, ypresp_all*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypresp_all(XDR *, ypresp_all*);
+#else /* Old Style C */ 
+bool_t xdr_ypresp_all();
+#endif /* Old Style C */ 
+
+
+struct ypresp_xfr {
+	u_int transid;
+	ypxfrstat xfrstat;
+};
+typedef struct ypresp_xfr ypresp_xfr;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypresp_xfr(XDR *, ypresp_xfr*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypresp_xfr(XDR *, ypresp_xfr*);
+#else /* Old Style C */ 
+bool_t xdr_ypresp_xfr();
+#endif /* Old Style C */ 
+
+
+struct ypmaplist {
+	mapname map;
+	struct ypmaplist *next;
+};
+typedef struct ypmaplist ypmaplist;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypmaplist(XDR *, ypmaplist*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypmaplist(XDR *, ypmaplist*);
+#else /* Old Style C */ 
+bool_t xdr_ypmaplist();
+#endif /* Old Style C */ 
+
+
+struct ypresp_maplist {
+	ypstat stat;
+	ypmaplist *maps;
+};
+typedef struct ypresp_maplist ypresp_maplist;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypresp_maplist(XDR *, ypresp_maplist*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypresp_maplist(XDR *, ypresp_maplist*);
+#else /* Old Style C */ 
+bool_t xdr_ypresp_maplist();
+#endif /* Old Style C */ 
+
+
+enum yppush_status {
+	YPPUSH_SUCC = 1,
+	YPPUSH_AGE = 2,
+	YPPUSH_NOMAP = -1,
+	YPPUSH_NODOM = -2,
+	YPPUSH_RSRC = -3,
+	YPPUSH_RPC = -4,
+	YPPUSH_MADDR = -5,
+	YPPUSH_YPERR = -6,
+	YPPUSH_BADARGS = -7,
+	YPPUSH_DBM = -8,
+	YPPUSH_FILE = -9,
+	YPPUSH_SKEW = -10,
+	YPPUSH_CLEAR = -11,
+	YPPUSH_FORCE = -12,
+	YPPUSH_XFRERR = -13,
+	YPPUSH_REFUSED = -14,
+};
+typedef enum yppush_status yppush_status;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_yppush_status(XDR *, yppush_status*);
+#elif defined(__STDC__)
+extern  bool_t xdr_yppush_status(XDR *, yppush_status*);
+#else /* Old Style C */ 
+bool_t xdr_yppush_status();
+#endif /* Old Style C */ 
+
+
+struct yppushresp_xfr {
+	u_int transid;
+	yppush_status status;
+};
+typedef struct yppushresp_xfr yppushresp_xfr;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_yppushresp_xfr(XDR *, yppushresp_xfr*);
+#elif defined(__STDC__)
+extern  bool_t xdr_yppushresp_xfr(XDR *, yppushresp_xfr*);
+#else /* Old Style C */ 
+bool_t xdr_yppushresp_xfr();
+#endif /* Old Style C */ 
+
+
+enum ypbind_resptype {
+	YPBIND_SUCC_VAL = 1,
+	YPBIND_FAIL_VAL = 2,
+};
+typedef enum ypbind_resptype ypbind_resptype;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypbind_resptype(XDR *, ypbind_resptype*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypbind_resptype(XDR *, ypbind_resptype*);
+#else /* Old Style C */ 
+bool_t xdr_ypbind_resptype();
+#endif /* Old Style C */ 
+
+
+struct ypbind_binding {
+	char ypbind_binding_addr[4];
+	char ypbind_binding_port[2];
+};
+typedef struct ypbind_binding ypbind_binding;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypbind_binding(XDR *, ypbind_binding*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypbind_binding(XDR *, ypbind_binding*);
+#else /* Old Style C */ 
+bool_t xdr_ypbind_binding();
+#endif /* Old Style C */ 
+
+
+struct ypbind_resp {
+	ypbind_resptype ypbind_status;
+	union {
+		u_int ypbind_error;
+		ypbind_binding ypbind_bindinfo;
+	} ypbind_resp_u;
+};
+typedef struct ypbind_resp ypbind_resp;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypbind_resp(XDR *, ypbind_resp*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypbind_resp(XDR *, ypbind_resp*);
+#else /* Old Style C */ 
+bool_t xdr_ypbind_resp();
+#endif /* Old Style C */ 
+
+#define YPBIND_ERR_ERR 1
+#define YPBIND_ERR_NOSERV 2
+#define YPBIND_ERR_RESC 3
+
+struct ypbind_setdom {
+	domainname ypsetdom_domain;
+	ypbind_binding ypsetdom_binding;
+	u_int ypsetdom_vers;
+};
+typedef struct ypbind_setdom ypbind_setdom;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypbind_setdom(XDR *, ypbind_setdom*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypbind_setdom(XDR *, ypbind_setdom*);
+#else /* Old Style C */ 
+bool_t xdr_ypbind_setdom();
+#endif /* Old Style C */ 
+
+
+#define YPPROG ((u_long)100004)
+#define YPVERS ((u_long)2)
+
+#ifdef __cplusplus
+#define YPPROC_NULL ((u_long)0)
+extern "C" void * ypproc_null_2(void *, CLIENT *);
+extern "C" void * ypproc_null_2_svc(void *, struct svc_req *);
+#define YPPROC_DOMAIN ((u_long)1)
+extern "C" bool_t * ypproc_domain_2(domainname *, CLIENT *);
+extern "C" bool_t * ypproc_domain_2_svc(domainname *, struct svc_req *);
+#define YPPROC_DOMAIN_NONACK ((u_long)2)
+extern "C" bool_t * ypproc_domain_nonack_2(domainname *, CLIENT *);
+extern "C" bool_t * ypproc_domain_nonack_2_svc(domainname *, struct svc_req *);
+#define YPPROC_MATCH ((u_long)3)
+extern "C" ypresp_val * ypproc_match_2(ypreq_key *, CLIENT *);
+extern "C" ypresp_val * ypproc_match_2_svc(ypreq_key *, struct svc_req *);
+#define YPPROC_FIRST ((u_long)4)
+extern "C" ypresp_key_val * ypproc_first_2(ypreq_nokey *, CLIENT *);
+extern "C" ypresp_key_val * ypproc_first_2_svc(ypreq_nokey *, struct svc_req *);
+#define YPPROC_NEXT ((u_long)5)
+extern "C" ypresp_key_val * ypproc_next_2(ypreq_key *, CLIENT *);
+extern "C" ypresp_key_val * ypproc_next_2_svc(ypreq_key *, struct svc_req *);
+#define YPPROC_XFR ((u_long)6)
+extern "C" ypresp_xfr * ypproc_xfr_2(ypreq_xfr *, CLIENT *);
+extern "C" ypresp_xfr * ypproc_xfr_2_svc(ypreq_xfr *, struct svc_req *);
+#define YPPROC_CLEAR ((u_long)7)
+extern "C" void * ypproc_clear_2(void *, CLIENT *);
+extern "C" void * ypproc_clear_2_svc(void *, struct svc_req *);
+#define YPPROC_ALL ((u_long)8)
+extern "C" ypresp_all * ypproc_all_2(ypreq_nokey *, CLIENT *);
+extern "C" ypresp_all * ypproc_all_2_svc(ypreq_nokey *, struct svc_req *);
+#define YPPROC_MASTER ((u_long)9)
+extern "C" ypresp_master * ypproc_master_2(ypreq_nokey *, CLIENT *);
+extern "C" ypresp_master * ypproc_master_2_svc(ypreq_nokey *, struct svc_req *);
+#define YPPROC_ORDER ((u_long)10)
+extern "C" ypresp_order * ypproc_order_2(ypreq_nokey *, CLIENT *);
+extern "C" ypresp_order * ypproc_order_2_svc(ypreq_nokey *, struct svc_req *);
+#define YPPROC_MAPLIST ((u_long)11)
+extern "C" ypresp_maplist * ypproc_maplist_2(domainname *, CLIENT *);
+extern "C" ypresp_maplist * ypproc_maplist_2_svc(domainname *, struct svc_req *);
+
+#elif defined(__STDC__)
+#define YPPROC_NULL ((u_long)0)
+extern  void * ypproc_null_2(void *, CLIENT *);
+extern  void * ypproc_null_2_svc(void *, struct svc_req *);
+#define YPPROC_DOMAIN ((u_long)1)
+extern  bool_t * ypproc_domain_2(domainname *, CLIENT *);
+extern  bool_t * ypproc_domain_2_svc(domainname *, struct svc_req *);
+#define YPPROC_DOMAIN_NONACK ((u_long)2)
+extern  bool_t * ypproc_domain_nonack_2(domainname *, CLIENT *);
+extern  bool_t * ypproc_domain_nonack_2_svc(domainname *, struct svc_req *);
+#define YPPROC_MATCH ((u_long)3)
+extern  ypresp_val * ypproc_match_2(ypreq_key *, CLIENT *);
+extern  ypresp_val * ypproc_match_2_svc(ypreq_key *, struct svc_req *);
+#define YPPROC_FIRST ((u_long)4)
+extern  ypresp_key_val * ypproc_first_2(ypreq_nokey *, CLIENT *);
+extern  ypresp_key_val * ypproc_first_2_svc(ypreq_nokey *, struct svc_req *);
+#define YPPROC_NEXT ((u_long)5)
+extern  ypresp_key_val * ypproc_next_2(ypreq_key *, CLIENT *);
+extern  ypresp_key_val * ypproc_next_2_svc(ypreq_key *, struct svc_req *);
+#define YPPROC_XFR ((u_long)6)
+extern  ypresp_xfr * ypproc_xfr_2(ypreq_xfr *, CLIENT *);
+extern  ypresp_xfr * ypproc_xfr_2_svc(ypreq_xfr *, struct svc_req *);
+#define YPPROC_CLEAR ((u_long)7)
+extern  void * ypproc_clear_2(void *, CLIENT *);
+extern  void * ypproc_clear_2_svc(void *, struct svc_req *);
+#define YPPROC_ALL ((u_long)8)
+extern  ypresp_all * ypproc_all_2(ypreq_nokey *, CLIENT *);
+extern  ypresp_all * ypproc_all_2_svc(ypreq_nokey *, struct svc_req *);
+#define YPPROC_MASTER ((u_long)9)
+extern  ypresp_master * ypproc_master_2(ypreq_nokey *, CLIENT *);
+extern  ypresp_master * ypproc_master_2_svc(ypreq_nokey *, struct svc_req *);
+#define YPPROC_ORDER ((u_long)10)
+extern  ypresp_order * ypproc_order_2(ypreq_nokey *, CLIENT *);
+extern  ypresp_order * ypproc_order_2_svc(ypreq_nokey *, struct svc_req *);
+#define YPPROC_MAPLIST ((u_long)11)
+extern  ypresp_maplist * ypproc_maplist_2(domainname *, CLIENT *);
+extern  ypresp_maplist * ypproc_maplist_2_svc(domainname *, struct svc_req *);
+
+#else /* Old Style C */ 
+#define YPPROC_NULL ((u_long)0)
+extern  void * ypproc_null_2();
+extern  void * ypproc_null_2_svc();
+#define YPPROC_DOMAIN ((u_long)1)
+extern  bool_t * ypproc_domain_2();
+extern  bool_t * ypproc_domain_2_svc();
+#define YPPROC_DOMAIN_NONACK ((u_long)2)
+extern  bool_t * ypproc_domain_nonack_2();
+extern  bool_t * ypproc_domain_nonack_2_svc();
+#define YPPROC_MATCH ((u_long)3)
+extern  ypresp_val * ypproc_match_2();
+extern  ypresp_val * ypproc_match_2_svc();
+#define YPPROC_FIRST ((u_long)4)
+extern  ypresp_key_val * ypproc_first_2();
+extern  ypresp_key_val * ypproc_first_2_svc();
+#define YPPROC_NEXT ((u_long)5)
+extern  ypresp_key_val * ypproc_next_2();
+extern  ypresp_key_val * ypproc_next_2_svc();
+#define YPPROC_XFR ((u_long)6)
+extern  ypresp_xfr * ypproc_xfr_2();
+extern  ypresp_xfr * ypproc_xfr_2_svc();
+#define YPPROC_CLEAR ((u_long)7)
+extern  void * ypproc_clear_2();
+extern  void * ypproc_clear_2_svc();
+#define YPPROC_ALL ((u_long)8)
+extern  ypresp_all * ypproc_all_2();
+extern  ypresp_all * ypproc_all_2_svc();
+#define YPPROC_MASTER ((u_long)9)
+extern  ypresp_master * ypproc_master_2();
+extern  ypresp_master * ypproc_master_2_svc();
+#define YPPROC_ORDER ((u_long)10)
+extern  ypresp_order * ypproc_order_2();
+extern  ypresp_order * ypproc_order_2_svc();
+#define YPPROC_MAPLIST ((u_long)11)
+extern  ypresp_maplist * ypproc_maplist_2();
+extern  ypresp_maplist * ypproc_maplist_2_svc();
+#endif /* Old Style C */ 
+
+#define YPPUSH_XFRRESPPROG ((u_long)0x40000000)
+#define YPPUSH_XFRRESPVERS ((u_long)1)
+
+#ifdef __cplusplus
+#define YPPUSHPROC_NULL ((u_long)0)
+extern "C" void * yppushproc_null_1(void *, CLIENT *);
+extern "C" void * yppushproc_null_1_svc(void *, struct svc_req *);
+#define YPPUSHPROC_XFRRESP ((u_long)1)
+extern "C" yppushresp_xfr * yppushproc_xfrresp_1(void *, CLIENT *);
+extern "C" yppushresp_xfr * yppushproc_xfrresp_1_svc(void *, struct svc_req *);
+
+#elif defined(__STDC__)
+#define YPPUSHPROC_NULL ((u_long)0)
+extern  void * yppushproc_null_1(void *, CLIENT *);
+extern  void * yppushproc_null_1_svc(void *, struct svc_req *);
+#define YPPUSHPROC_XFRRESP ((u_long)1)
+extern  yppushresp_xfr * yppushproc_xfrresp_1(void *, CLIENT *);
+extern  yppushresp_xfr * yppushproc_xfrresp_1_svc(void *, struct svc_req *);
+
+#else /* Old Style C */ 
+#define YPPUSHPROC_NULL ((u_long)0)
+extern  void * yppushproc_null_1();
+extern  void * yppushproc_null_1_svc();
+#define YPPUSHPROC_XFRRESP ((u_long)1)
+extern  yppushresp_xfr * yppushproc_xfrresp_1();
+extern  yppushresp_xfr * yppushproc_xfrresp_1_svc();
+#endif /* Old Style C */ 
+
+#define YPBINDPROG ((u_long)100007)
+#define YPBINDVERS ((u_long)2)
+
+#ifdef __cplusplus
+#define YPBINDPROC_NULL ((u_long)0)
+extern "C" void * ypbindproc_null_2(void *, CLIENT *);
+extern "C" void * ypbindproc_null_2_svc(void *, struct svc_req *);
+#define YPBINDPROC_DOMAIN ((u_long)1)
+extern "C" ypbind_resp * ypbindproc_domain_2(domainname *, CLIENT *);
+extern "C" ypbind_resp * ypbindproc_domain_2_svc(domainname *, struct svc_req *);
+#define YPBINDPROC_SETDOM ((u_long)2)
+extern "C" void * ypbindproc_setdom_2(ypbind_setdom *, CLIENT *);
+extern "C" void * ypbindproc_setdom_2_svc(ypbind_setdom *, struct svc_req *);
+
+#elif defined(__STDC__)
+#define YPBINDPROC_NULL ((u_long)0)
+extern  void * ypbindproc_null_2(void *, CLIENT *);
+extern  void * ypbindproc_null_2_svc(void *, struct svc_req *);
+#define YPBINDPROC_DOMAIN ((u_long)1)
+extern  ypbind_resp * ypbindproc_domain_2(domainname *, CLIENT *);
+extern  ypbind_resp * ypbindproc_domain_2_svc(domainname *, struct svc_req *);
+#define YPBINDPROC_SETDOM ((u_long)2)
+extern  void * ypbindproc_setdom_2(ypbind_setdom *, CLIENT *);
+extern  void * ypbindproc_setdom_2_svc(ypbind_setdom *, struct svc_req *);
+
+#else /* Old Style C */ 
+#define YPBINDPROC_NULL ((u_long)0)
+extern  void * ypbindproc_null_2();
+extern  void * ypbindproc_null_2_svc();
+#define YPBINDPROC_DOMAIN ((u_long)1)
+extern  ypbind_resp * ypbindproc_domain_2();
+extern  ypbind_resp * ypbindproc_domain_2_svc();
+#define YPBINDPROC_SETDOM ((u_long)2)
+extern  void * ypbindproc_setdom_2();
+extern  void * ypbindproc_setdom_2_svc();
+#endif /* Old Style C */ 
+
+#endif /* !_YP_H_RPCGEN */
diff --git a/ypserv.tproj/ypdb.c b/ypserv.tproj/ypdb.c
new file mode 100644
index 0000000..c9bd178
--- /dev/null
+++ b/ypserv.tproj/ypdb.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdb.c,v 1.5 1997/02/09 09:49:36 maja Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * This code is derived from ndbm module of BSD4.4 db (hash) by
+ * Mats O Jansson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ypdb.h"
+
+#ifdef YPDB_PATCH
+extern DBM *__hash_open();
+#else
+extern DBM *__bt_open();
+#endif
+
+/*
+ * Returns:
+ * 	*DBM on success
+ *	 NULL on failure
+ */
+
+extern DBM *
+ypdb_open(file, flags, mode)
+	const char *file;
+	int flags, mode;
+{
+#ifdef YPDB_PATCH
+	HASHINFO info;
+	char path[MAXPATHLEN];
+
+	info.bsize = 4096;
+	info.ffactor = 40;
+	info.nelem = 1;
+	info.cachesize = NULL;
+	info.hash = NULL;
+	info.lorder = 0;
+	snprintf(path, sizeof(path), "%s%s", file, YPDB_SUFFIX);
+	return ((DBM *)__hash_open(path, flags, mode, &info, 0));
+#else
+	BTREEINFO info;
+	char path[MAXPATHLEN];
+	DBM *db;
+
+	info.flags = 0;
+	info.cachesize = 0;
+	info.maxkeypage = 0;
+	info.minkeypage = 0;
+	info.psize = 0;
+	info.compare = NULL;
+	info.prefix = NULL;
+	info.lorder = 0;
+	snprintf(path, sizeof(path), "%s%s", file, YPDB_SUFFIX);
+	db = (DBM *)__bt_open(path, flags, mode, &info, 0);
+	return (db);
+#endif
+}
+
+/*
+ * Returns:
+ * 	*DBM on success
+ *	 NULL on failure
+ */
+
+extern DBM *
+ypdb_open_suf(file, flags, mode)
+	const char *file;
+	int flags, mode;
+{
+#ifdef YPDB_PATCH
+	HASHINFO info;
+
+	info.bsize = 4096;
+	info.ffactor = 40;
+	info.nelem = 1;
+	info.cachesize = NULL;
+	info.hash = NULL;
+	info.lorder = 0;
+	return ((DBM *)__hash_open(file, flags, mode, &info, 0));
+#else
+	BTREEINFO info;
+	DBM *db;
+
+	info.flags = 0;
+	info.cachesize = 0;
+	info.maxkeypage = 0;
+	info.minkeypage = 0;
+	info.psize = 0;
+	info.compare = NULL;
+	info.prefix = NULL;
+	info.lorder = 0;
+	db = (DBM *)__bt_open(file, flags, mode, &info, 0);
+	return (db);
+#endif
+}
+
+extern void
+ypdb_close(db)
+	DBM *db;
+{
+	(void)(db->close)(db);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_fetch(db, key)
+	DBM *db;
+	datum key;
+{
+	datum retval;
+	int status;
+
+	status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
+	if (status) {
+		retval.dptr = NULL;
+		retval.dsize = 0;
+	}
+	return (retval);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_firstkey(db)
+	DBM *db;
+{
+	int status;
+	datum retdata, retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+	if (status)
+		retkey.dptr = NULL;
+	return (retkey);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_nextkey(db)
+	DBM *db;
+{
+	int status;
+	datum retdata, retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+	if (status)
+		retkey.dptr = NULL;
+	return (retkey);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_setkey(db, key)
+	DBM *db;
+        datum key;
+{
+	int status;
+	datum retdata;
+#ifdef YPDB_PATCH
+	datum retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+	if (status)
+		retkey.dptr = NULL;
+	while ((retkey.dptr != NULL) &&
+	       ((retkey.dsize != key.dsize) ||
+		(strncmp(key.dptr,retkey.dptr,retkey.dsize) != 0))) {
+	  status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+	  if (status)
+	  	retkey.dptr = NULL;
+	};
+	return (retkey);
+#else
+	status = (db->seq)(db, (DBT *)&key, (DBT *)&retdata, R_CURSOR);
+	if (status)
+		key.dptr = NULL;
+	return (key);
+#endif
+}
+
+/*
+ * Returns:
+ *	 0 on success
+ *	<0 failure
+ */
+
+int
+ypdb_delete(db, key)
+	DBM *db;
+	datum key;
+{
+	int status;
+
+	status = (db->del)(db, (DBT *)&key, 0);
+	if (status)
+		return (-1);
+	else
+		return (0);
+}
+
+/*
+ * Returns:
+ *	 0 on success
+ *	<0 failure
+ *	 1 if YPDB_INSERT and entry exists
+ */
+
+int
+ypdb_store(db, key, content, flags)
+	DBM *db;
+	datum key, content;
+	int flags;
+{
+	return ((db->put)(db, (DBT *)&key, (DBT *)&content,
+	    (flags == YPDB_INSERT) ? R_NOOVERWRITE : 0));
+}
+
diff --git a/ypserv.tproj/ypdb.h b/ypserv.tproj/ypdb.h
new file mode 100644
index 0000000..45b0a7f
--- /dev/null
+++ b/ypserv.tproj/ypdb.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdb.h,v 1.5 1997/02/09 09:49:37 maja Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * This code is derived from ndbm module of BSD4.4 db (hash) by
+ * Mats O Jansson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPDB_H_
+#define _YPDB_H_
+
+#ifndef _DB_H_
+#include <db.h>
+#endif
+
+#define YPDB_SUFFIX	".db"
+
+/* Flags to ypdb_store(). */
+#define YPDB_INSERT      0
+#define YPDB_REPLACE     1
+
+#ifndef DATUM
+typedef struct {
+	char	*dptr;
+	int	dsize;
+} datum;
+#define DATUM
+#endif
+
+typedef DB DBM;
+
+__BEGIN_DECLS
+void	 ypdb_close __P((DBM *));
+datum	 ypdb_fetch __P((DBM *, datum));
+datum	 ypdb_firstkey __P((DBM *));
+datum	 ypdb_nextkey __P((DBM *));
+datum	 ypdb_setkey __P((DBM *, datum));
+DBM     *ypdb_open __P((const char *, int, int));
+DBM     *ypdb_open_suf __P((const char *, int, int));
+int	 ypdb_store __P((DBM *, datum, datum, int));
+__END_DECLS
+
+#endif /* !_YPDB_H_ */
diff --git a/ypserv.tproj/ypdef.h b/ypserv.tproj/ypdef.h
new file mode 100644
index 0000000..89970d7
--- /dev/null
+++ b/ypserv.tproj/ypdef.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdef.h,v 1.6 1997/03/30 20:51:14 maja Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPDEF_H_
+#define _YPDEF_H_
+
+#define YP_DB_PATH "/var/yp"
+#define YP_LAST_KEY        "YP_LAST_MODIFIED"
+#define YP_LAST_LEN	   (sizeof(YP_LAST_KEY)-1)
+#define YP_INPUT_KEY       "YP_INPUT_FILE"
+#define YP_INPUT_LEN	   (sizeof(YP_INPUT_KEY)-1)
+#define YP_OUTPUT_KEY      "YP_OUTPUT_FILE"
+#define YP_OUTPUT_LEN	   (sizeof(YP_OUTPUT_KEY)-1)
+#define YP_MASTER_KEY      "YP_MASTER_NAME"
+#define YP_MASTER_LEN	   (sizeof(YP_MASTER_KEY)-1)
+#define YP_DOMAIN_KEY      "YP_DOMAIN_NAME"
+#define YP_DOMAIN_LEN	   (sizeof(YP_DOMAIN_KEY)-1)
+#define YP_INTERDOMAIN_KEY "YP_INTERDOMAIN"
+#define YP_INTERDOMAIN_LEN (sizeof(YP_INTERDOMAIN_KEY)-1)
+#define YP_SECURE_KEY      "YP_SECURE"
+#define YP_SECURE_LEN      (sizeof(YP_SECURE_KEY)-1)
+
+#define MAX_LAST_LEN 10
+#define MAX_MASTER_LEN 255
+#define YP_HOSTNAME "hosts.byname"
+#define YP_HOSTADDR "hosts.byaddr"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define YPXFR_PROC "/usr/sbin/ypxfr"
+#define YPPUSH_PROC "/usr/sbin/yppush"
+#define YPSERV_PID_PATH "/var/run/ypserv.pid"
+#define YP_SECURENET_FILE "/var/yp/securenet"
+
+#endif /* !_YPDEF_H_ */
diff --git a/ypserv.tproj/yplog.c b/ypserv.tproj/yplog.c
new file mode 100644
index 0000000..3460c9a
--- /dev/null
+++ b/ypserv.tproj/yplog.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yplog.c,v 1.5 1997/08/09 22:44:04 maja Exp $ */
+
+/*
+ * Copyright (c) 1996 Charles D. Cranor
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Charles D. Cranor.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * yplog.c: replacement yplog routines for 
+ * Mats O Jansson's ypserv program, as added by
+ * Chuck Cranor.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "yplog.h"
+
+static FILE	*logfp = NULL;		/* the log file */
+
+/*
+ * yplog(): like a printf, but to the log file.   does the flush
+ * and data for you.
+ */
+
+void
+#ifdef __STDC__
+yplog(const char *fmt, ...)
+#else
+yplog(fmt, va_alist)
+	char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+#ifdef __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	vyplog(fmt, ap);
+	va_end(ap);
+}
+
+/*
+ * vyplog() support routine for yplog()
+ */
+
+void
+vyplog(fmt, ap)
+	register const char *fmt;
+	va_list ap;
+{
+        time_t t;
+
+	if (logfp == NULL)
+		return;
+	(void)time(&t);
+	fprintf(logfp,"%.15s ", ctime(&t) + 4);
+	vfprintf(logfp, fmt, ap);
+	fprintf(logfp,"\n");
+	fflush(logfp);
+}
+
+/*
+ * open log
+ */
+
+void
+ypopenlog()
+{
+	static char logfn[] = "/var/yp/ypserv.log";
+
+	if (access(logfn, W_OK) == -1)
+		return;
+	logfp = fopen("/var/yp/ypserv.log", "a");
+	if (logfp == NULL)
+		return;
+	yplog("yplog opened");
+}
+
+/*
+ * close log
+ */
+
+void
+ypcloselog()
+{
+	if (logfp) {
+		yplog("yplog closed");
+		fclose(logfp);
+		logfp = NULL;
+	}
+}
diff --git a/ypserv.tproj/yplog.h b/ypserv.tproj/yplog.h
new file mode 100644
index 0000000..dd9d6fb
--- /dev/null
+++ b/ypserv.tproj/yplog.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yplog.h,v 1.3 1996/05/30 09:53:04 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPLOG_H_
+#define _YPLOG_H_
+
+__BEGIN_DECLS
+void    yplog __P((const char *, ...));
+void    vyplog __P((const char *, _BSD_VA_LIST_));
+void	ypopenlog __P((void));
+void	ypcloselog __P((void));
+__END_DECLS
+
+#endif /* !_YPLOG_H_ */
diff --git a/ypserv.tproj/ypserv.acl b/ypserv.tproj/ypserv.acl
new file mode 100644
index 0000000..afeb86f
--- /dev/null
+++ b/ypserv.tproj/ypserv.acl
@@ -0,0 +1,44 @@
+# This is an example of an access control file to be used by ypserv.
+#
+# This file is parsed line by line. First match will terminate the check
+# of the caller.
+#
+
+#############################################################################
+# This is the commands that will match a single host
+#
+#	allow host <hostname|ip-address>
+#	deny host <hostname|ip-address>
+#
+# To process hostname gethostbyname is called. If the hostname has multiple
+# ip-addresses all will be added (I hope). ip-address is processed by
+# inet_aton.
+allow host localhost
+deny host jodie
+
+#############################################################################
+# This is the commands that will match a network
+#
+#	allow net <netname|netnumber> [netmask <netname|netnumber>]
+#	deny net <netname|netnumber> [netmask <netname|netnumber>]
+#
+# To process netname getnetbyname is called, and inet_aton is used for
+# netnumber. inet_aton both access numbers as 255.255.255.0 and 0xffffff00.
+#
+# If netmask isn't given the parser will assume netmask from the first bits
+# of the network number. So if the network is subneted the you have to add
+# the netmask. In my case I've got the network 139.58.253.0 at home so too
+# allow any of my computers to talk with the server I need the following line
+#
+allow net mojathome netmask 255.255.255.0
+
+#############################################################################
+# At last we have a command that will match any caller:
+#
+#	allow all 
+#	deny all
+#
+
+# reject all connections
+deny all
+
diff --git a/ypserv.tproj/ypserv.acl.5 b/ypserv.tproj/ypserv.acl.5
new file mode 100644
index 0000000..4e00b7b
--- /dev/null
+++ b/ypserv.tproj/ypserv.acl.5
@@ -0,0 +1,182 @@
+.\"	$OpenBSD: ypserv.acl.5,v 1.6 1997/08/05 09:26:56 maja Exp $
+.\" Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by Mats O Jansson
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd July 2, 1994
+.Dt YPSERV.ACL 5
+.Os
+.Sh NAME
+.Nm ypserv.acl
+.Nd 
+.Xr ypserv 8
+configuration file
+.Sh DESCRIPTION
+The 
+.Nm ypserv.acl
+file controls which hosts can connect to the
+.Nm YP
+server.
+.Pp
+The format is more complex than the format for
+.Xr securenet 5 .
+The first two verbs on each line controls if the line will
+.Nm allow
+or
+.Nm deny
+access for a
+.Nm host ,
+network
+.Nm (net)
+or
+.Nm all
+hosts.
+.Pp
+The
+.Nm YP
+server reads the configuration file and build a list in memory. This list
+is processed from the beginning for every incomming request. As soon a
+match is found in the list the search terminates and it returns success
+or failure depending on 
+.Nm allow
+or 
+.Nm deny .
+If no match was found in the list success is returned.
+.Pp
+If access is denied every call will cause a 
+.Nm no such domain
+error for the caller.
+.Pp
+Don't forget to allow localhost access if you want the machine running
+.Nm ypserv
+access it too.
+.Pp
+There is no default name for this file. Start 
+.Nm ypserv
+with a
+.Ar -a filename
+to read a file with this format.
+.Pp
+The following different syntax can be used:
+.Pp
+<
+.Nm allow|deny
+>
+.Nm host
+<
+.Nm hostname|ip-address
+>
+.Pp
+If 
+.Nm hostname
+has more than one ip address then all will be added to the list.
+.Pp
+<
+.Nm allow|deny
+>
+.Nm net
+<
+.Nm netname|netnumber
+>
+.Op Nm netmask <netname|netnumber>
+.Pp
+If
+.Nm netmask
+part of the command isn't given then the netmask will be assumed to be a
+class A, B or C net depending on the net number.
+.Pp
+<
+.Nm allow|deny 
+>
+.Nm all
+.Pp
+A line containing one of these commands will always match any host.
+.Sh EXAMPLES
+.Pp
+A configuration file might appear as follows:
+.Bd -literal
+# This is an example of an access control file to be used by ypserv.
+#
+# This file is parsed line by line. First match will terminate the check
+# of the caller.
+#
+
+###########################################################################
+# This is the commands that will match a single host
+#
+#	allow host <hostname|ip-address>
+#	deny host <hostname|ip-address>
+#
+# To process hostname gethostbyname is called. If the hostname has
+# multiple ip-addresses all will be added (I hope). ip-address
+# processed by inet_aton.
+allow host localhost
+deny host jodie
+
+###########################################################################
+# This is the commands that will match a network
+#
+#	allow net <netname|netnumber> [netmask <netname|netnumber>]
+#	deny net <netname|netnumber> [netmask <netname|netnumber>]
+#
+# To process netname getnetbyname is called, and inet_aton is used for
+# netnumber. inet_aton both access numbers as 255.255.255.0 and 0xffffff00.
+#
+# If netmask isn't given the parser will assume netmask from the first bits
+# of the network number. So if the network is subneted the you have to add
+# the netmask. In my case I've got the network 139.58.253.0 at home so too
+# allow any of my computers to talk with the server I need the following
+# line
+#
+allow net mojathome netmask 255.255.255.0
+
+###########################################################################
+# At last we have a command that will match any caller:
+#
+#	allow all 
+#	deny all
+#
+
+# reject all connections
+deny all
+
+.Ed
+.Sh FILES
+.Bl -tag -width /var/yp/ypserv.acl -compact
+.It Pa /var/yp/ypserv.acl
+A
+.Xr ypserv 8
+configuration file.
+.El
+.Sh SEE ALSO
+.Xr yp 8 ,
+.Xr ypserv 8 ,
+.Xr securenet 5
+.Sh AUTHOR
+Mats O Jansson <moj@stacken.kth.se>
+
diff --git a/ypserv.tproj/ypserv.c b/ypserv.tproj/ypserv.c
new file mode 100644
index 0000000..7089884
--- /dev/null
+++ b/ypserv.tproj/ypserv.c
@@ -0,0 +1,559 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypserv.c,v 1.12 1997/11/04 07:40:52 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: ypserv.c,v 1.12 1997/11/04 07:40:52 deraadt Exp $";
+#endif
+
+#include "yp.h"
+#include "ypv1.h"
+#include <stdio.h>
+#include <stdlib.h>/* getenv, exit */
+#include <rpc/pmap_clnt.h> /* for pmap_unset */
+#include <string.h> /* strcmp */
+#include <unistd.h>
+#include <netdb.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/ttycom.h>/* TIOCNOTTY */
+#ifdef __cplusplus
+#include <sysent.h> /* getdtablesize, open */
+#endif /* __cplusplus */
+#include <memory.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include "acl.h"
+#include "yplog.h"
+#include "ypdef.h"
+#include <sys/wait.h>
+#include <sys/ioctl.h> /* for ioctl */
+#include <sys/fcntl.h> /* for open */
+
+#ifdef __STDC__
+#define SIG_PF void(*)(int)
+#endif
+
+#ifdef DEBUG
+#define RPC_SVC_FG
+#endif
+
+#define _RPCSVC_CLOSEDOWN 120
+static int _rpcpmstart;		/* Started by a port monitor ? */
+static int _rpcfdtype;		/* Whether Stream or Datagram ? */
+static int _rpcsvcdirty;	/* Still serving ? */
+
+int	usedns = FALSE;
+char   *progname = "ypserv";
+char   *aclfile = NULL;
+
+void sig_child();
+void sig_hup();
+
+/* in the RPC library */
+SVCXPRT *svcfd_create(int, u_int, u_int);
+
+static
+void _msgout(char* msg)
+{
+#ifdef RPC_SVC_FG
+	if (_rpcpmstart)
+		syslog(LOG_ERR, msg);
+	else
+		(void) fprintf(stderr, "%s\n", msg);
+#else
+	syslog(LOG_ERR, msg);
+#endif
+}
+
+static void
+closedown()
+{
+	if (_rpcsvcdirty == 0) {
+		extern fd_set svc_fdset;
+		static int size;
+		int i, openfd;
+
+		if (_rpcfdtype == SOCK_DGRAM)
+			exit(0);
+		if (size == 0) {
+			size = getdtablesize();
+		}
+		for (i = 0, openfd = 0; i < size && openfd < 2; i++)
+			if (FD_ISSET(i, &svc_fdset))
+				openfd++;
+		if (openfd <= (_rpcpmstart?0:1))
+			exit(0);
+	}
+	(void) alarm(_RPCSVC_CLOSEDOWN);
+}
+
+static void
+ypprog_1(struct svc_req *rqstp, register SVCXPRT *transp)
+{
+	union {
+		domainname ypproc_domain_1_arg;
+		domainname ypproc_domain_nonack_1_arg;
+		yprequest ypproc_match_1_arg;
+		yprequest ypproc_first_1_arg;
+		yprequest ypproc_next_1_arg;
+		yprequest ypproc_poll_1_arg;
+		yprequest ypproc_push_1_arg;
+		yprequest ypproc_pull_1_arg;
+		yprequest ypproc_get_1_arg;
+	} argument;
+	char *result;
+	xdrproc_t xdr_argument, xdr_result;
+	char *(*local)(char *, struct svc_req *);
+
+	_rpcsvcdirty = 1;
+	switch (rqstp->rq_proc) {
+	case YPOLDPROC_NULL:
+		xdr_argument = (xdrproc_t) xdr_void;
+		xdr_result = (xdrproc_t) xdr_void;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_null_1_svc;
+		break;
+
+	case YPOLDPROC_DOMAIN:
+		xdr_argument = (xdrproc_t) xdr_domainname;
+		xdr_result = (xdrproc_t) xdr_bool;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_domain_1_svc;
+		break;
+
+	case YPOLDPROC_DOMAIN_NONACK:
+		xdr_argument = (xdrproc_t) xdr_domainname;
+		xdr_result = (xdrproc_t) xdr_bool;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_domain_nonack_1_svc;
+		break;
+
+	case YPOLDPROC_MATCH:
+		xdr_argument = (xdrproc_t) xdr_yprequest;
+		xdr_result = (xdrproc_t) xdr_ypresponse;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_match_1_svc;
+		break;
+
+	case YPOLDPROC_FIRST:
+		xdr_argument = (xdrproc_t) xdr_yprequest;
+		xdr_result = (xdrproc_t) xdr_ypresponse;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_first_1_svc;
+		break;
+
+	case YPOLDPROC_NEXT:
+		xdr_argument = (xdrproc_t) xdr_yprequest;
+		xdr_result = (xdrproc_t) xdr_ypresponse;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_next_1_svc;
+		break;
+
+	case YPOLDPROC_POLL:
+		xdr_argument = (xdrproc_t) xdr_yprequest;
+		xdr_result = (xdrproc_t) xdr_ypresponse;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_poll_1_svc;
+		break;
+
+	case YPOLDPROC_PUSH:
+		xdr_argument = (xdrproc_t) xdr_yprequest;
+		xdr_result = (xdrproc_t) xdr_void;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_push_1_svc;
+		break;
+
+	case YPOLDPROC_PULL:
+		xdr_argument = (xdrproc_t) xdr_yprequest;
+		xdr_result = (xdrproc_t) xdr_void;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_pull_1_svc;
+		break;
+
+	case YPOLDPROC_GET:
+		xdr_argument = (xdrproc_t) xdr_yprequest;
+		xdr_result = (xdrproc_t) xdr_void;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_get_1_svc;
+		break;
+
+	default:
+		svcerr_noproc(transp);
+		_rpcsvcdirty = 0;
+		return;
+	}
+	(void) memset((char *)&argument, 0, sizeof (argument));
+	if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) {
+		svcerr_decode(transp);
+		_rpcsvcdirty = 0;
+		return;
+	}
+	result = (*local)((char *)&argument, rqstp);
+	if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
+		svcerr_systemerr(transp);
+	}
+	if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) {
+		_msgout("unable to free arguments");
+		exit(1);
+	}
+	_rpcsvcdirty = 0;
+	return;
+}
+
+static void
+ypprog_2(struct svc_req *rqstp, register SVCXPRT *transp)
+{
+	union {
+		domainname ypproc_domain_2_arg;
+		domainname ypproc_domain_nonack_2_arg;
+		ypreq_key ypproc_match_2_arg;
+		ypreq_nokey ypproc_first_2_arg;
+		ypreq_key ypproc_next_2_arg;
+		ypreq_xfr ypproc_xfr_2_arg;
+		ypreq_nokey ypproc_all_2_arg;
+		ypreq_nokey ypproc_master_2_arg;
+		ypreq_nokey ypproc_order_2_arg;
+		domainname ypproc_maplist_2_arg;
+	} argument;
+	char *result;
+	xdrproc_t xdr_argument, xdr_result;
+	char *(*local)(char *, struct svc_req *);
+
+	_rpcsvcdirty = 1;
+	switch (rqstp->rq_proc) {
+	case YPPROC_NULL:
+		xdr_argument = (xdrproc_t) xdr_void;
+		xdr_result = (xdrproc_t) xdr_void;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_null_2_svc;
+		break;
+
+	case YPPROC_DOMAIN:
+		xdr_argument = (xdrproc_t) xdr_domainname;
+		xdr_result = (xdrproc_t) xdr_bool;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_domain_2_svc;
+		break;
+
+	case YPPROC_DOMAIN_NONACK:
+		xdr_argument = (xdrproc_t) xdr_domainname;
+		xdr_result = (xdrproc_t) xdr_bool;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_domain_nonack_2_svc;
+		break;
+
+	case YPPROC_MATCH:
+		xdr_argument = (xdrproc_t) xdr_ypreq_key;
+		xdr_result = (xdrproc_t) xdr_ypresp_val;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_match_2_svc;
+		break;
+
+	case YPPROC_FIRST:
+		xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
+		xdr_result = (xdrproc_t) xdr_ypresp_key_val;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_first_2_svc;
+		break;
+
+	case YPPROC_NEXT:
+		xdr_argument = (xdrproc_t) xdr_ypreq_key;
+		xdr_result = (xdrproc_t) xdr_ypresp_key_val;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_next_2_svc;
+		break;
+
+	case YPPROC_XFR:
+		xdr_argument = (xdrproc_t) xdr_ypreq_xfr;
+		xdr_result = (xdrproc_t) xdr_ypresp_xfr;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_xfr_2_svc;
+		break;
+
+	case YPPROC_CLEAR:
+		xdr_argument = (xdrproc_t) xdr_void;
+		xdr_result = (xdrproc_t) xdr_void;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_clear_2_svc;
+		break;
+
+	case YPPROC_ALL:
+		xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
+		xdr_result = (xdrproc_t) xdr_ypresp_all;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_all_2_svc;
+		break;
+
+	case YPPROC_MASTER:
+		xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
+		xdr_result = (xdrproc_t) xdr_ypresp_master;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_master_2_svc;
+		break;
+
+	case YPPROC_ORDER:
+		xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
+		xdr_result = (xdrproc_t) xdr_ypresp_order;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_order_2_svc;
+		break;
+
+	case YPPROC_MAPLIST:
+		xdr_argument = (xdrproc_t) xdr_domainname;
+		xdr_result = (xdrproc_t) xdr_ypresp_maplist;
+		local = (char *(*)(char *, struct svc_req *)) ypproc_maplist_2_svc;
+		break;
+
+	default:
+		svcerr_noproc(transp);
+		_rpcsvcdirty = 0;
+		return;
+	}
+	(void) memset((char *)&argument, 0, sizeof (argument));
+	if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) {
+		svcerr_decode(transp);
+		_rpcsvcdirty = 0;
+		return;
+	}
+	result = (*local)((char *)&argument, rqstp);
+	if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
+		svcerr_systemerr(transp);
+	}
+	if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) {
+		_msgout("unable to free arguments");
+		exit(1);
+	}
+	_rpcsvcdirty = 0;
+	return;
+}
+
+int
+main (argc,argv)
+int argc;
+char *argv[];
+{
+	register SVCXPRT *transp = NULL;
+	int sock;
+	int proto = 0;
+	struct sockaddr_in saddr;
+	int asize = sizeof (saddr);
+	int	 usage = 0;
+	int	 xflag = 0;
+	int	 allowv1 = 0;
+	int	 ch;
+	extern	 char *optarg;
+	
+	while ((ch = getopt(argc, argv, "1a:dx")) != -1)
+		switch (ch) {
+		case '1':
+			allowv1 = TRUE;
+			break;
+		case 'a':
+			aclfile = optarg;
+			break;
+		case 'd':
+			usedns = TRUE;
+			break;
+		case 'x':
+			xflag = TRUE;
+			break;
+		default:
+			usage++;
+			break;
+		}
+	
+	if (usage) {
+		(void)fprintf(stderr,"usage: %s [-a aclfile] [-d] [-x]\n",progname);
+		exit(1);
+	}
+
+	if (geteuid() != 0) {
+		(void)fprintf(stderr,"%s: must be root to run.\n",progname);
+		exit(1);
+	}
+
+	if (aclfile != NULL) {
+		(void)acl_init(aclfile);
+	} else {
+		(void)acl_securenet(YP_SECURENET_FILE);
+	}
+	if (xflag) {
+		exit(1);
+	};
+
+	if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {
+		int ssize = sizeof (int);
+
+		if (saddr.sin_family != AF_INET)
+			exit(1);
+		if (getsockopt(0, SOL_SOCKET, SO_TYPE,
+				(char *)&_rpcfdtype, &ssize) == -1)
+			exit(1);
+		sock = 0;
+		_rpcpmstart = 1;
+		proto = 0;
+		openlog("ypserv", LOG_PID, LOG_DAEMON);
+	} else {
+#ifndef RPC_SVC_FG
+		int size;
+		int pid, i;
+
+		pid = fork();
+		if (pid < 0) {
+			perror("cannot fork");
+			exit(1);
+		}
+		if (pid)
+			exit(0);
+		size = getdtablesize();
+		for (i = 0; i < size; i++)
+			(void) close(i);
+		i = open("/dev/console", 2);
+		(void) dup2(i, 1);
+		(void) dup2(i, 2);
+		i = open("/dev/tty", 2);
+		if (i >= 0) {
+			(void) ioctl(i, TIOCNOTTY, (char *)NULL);
+			(void) close(i);
+		}
+		openlog("ypserv", LOG_PID, LOG_DAEMON);
+#endif
+		sock = RPC_ANYSOCK;
+		(void) pmap_unset(YPPROG, YPVERS);
+		(void) pmap_unset(YPPROG, YPOLDVERS);
+	}
+
+	ypopenlog();	/* open log file */
+	ypdb_init();	/* init db stuff */
+
+	chdir("/");
+	
+	(void)signal(SIGCHLD, sig_child);
+	(void)signal(SIGHUP, sig_hup);
+	{ FILE *pidfile = fopen(YPSERV_PID_PATH, "w");
+	  if (pidfile != NULL) {
+		fprintf(pidfile, "%d\n", getpid());
+		fclose(pidfile);
+	  }
+	}
+
+	if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) {
+		transp = svcudp_create(sock);
+		if (transp == NULL) {
+			_msgout("cannot create udp service.");
+			exit(1);
+		}
+		if (transp->xp_port >= IPPORT_RESERVED) {
+			_msgout("cannot allocate udp privileged port.");
+			exit(1);
+		}
+		if (!_rpcpmstart)
+			proto = IPPROTO_UDP;
+		if (allowv1) {
+			if (!svc_register(transp, YPPROG, YPOLDVERS, ypprog_1, proto)) {
+				_msgout("unable to register (YPPROG, YPOLDVERS, udp).");
+				exit(1);
+			}
+		}
+		if (!svc_register(transp, YPPROG, YPVERS, ypprog_2, proto)) {
+			_msgout("unable to register (YPPROG, YPVERS, udp).");
+			exit(1);
+		}
+	}
+
+	if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) {
+		if (_rpcpmstart)
+			transp = svcfd_create(sock, 0, 0);
+		else
+			transp = svctcp_create(sock, 0, 0);
+		if (transp == NULL) {
+			_msgout("cannot create tcp service.");
+			exit(1);
+		}
+		if (transp->xp_port >= IPPORT_RESERVED) {
+			_msgout("cannot allocate tcp privileged port.");
+			exit(1);
+		}
+		if (!_rpcpmstart)
+			proto = IPPROTO_TCP;
+		if (allowv1) {
+			if (!svc_register(transp, YPPROG, YPOLDVERS, ypprog_1, proto)) {
+				_msgout("unable to register (YPPROG, YPOLDVERS, tcp).");
+				exit(1);
+			}
+		}
+		if (!svc_register(transp, YPPROG, YPVERS, ypprog_2, proto)) {
+			_msgout("unable to register (YPPROG, YPVERS, tcp).");
+			exit(1);
+		}
+	}
+
+	if (transp == (SVCXPRT *)NULL) {
+		_msgout("could not create a handle");
+		exit(1);
+	}
+	if (_rpcpmstart) {
+		(void) signal(SIGALRM, (SIG_PF) closedown);
+		(void) alarm(_RPCSVC_CLOSEDOWN);
+	}
+	svc_run();
+	_msgout("svc_run returned");
+	exit(1);
+	/* NOTREACHED */
+}
+
+void
+sig_child()
+{
+	int save_errno = errno;
+
+	while (wait3((int *)NULL, WNOHANG, (struct rusage *)NULL) > 0)
+		;
+	errno = save_errno;
+}
+
+void
+sig_hup()
+{
+	acl_reset();
+	if (aclfile != NULL) {
+		yplog("sig_hup: reread %s",aclfile);
+		(void)acl_init(aclfile);
+	} else {
+		yplog("sig_hup: reread %s",YP_SECURENET_FILE);
+		(void)acl_securenet(YP_SECURENET_FILE);
+	}
+}
diff --git a/ypserv.tproj/ypserv_db.c b/ypserv.tproj/ypserv_db.c
new file mode 100644
index 0000000..b7b6469
--- /dev/null
+++ b/ypserv.tproj/ypserv_db.c
@@ -0,0 +1,811 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypserv_db.c,v 1.13 1997/08/09 23:10:12 maja Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * Copyright (c) 1996 Charles D. Cranor
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ *	and Charles D. Cranor.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: ypserv_db.c,v 1.13 1997/08/09 23:10:12 maja Exp $";
+#endif
+
+/*
+ * major revision/cleanup of Mats' version 
+ * done by Chuck Cranor <chuck@ccrc.wustl.edu>
+ * Jan 1996.
+ */
+
+
+#include <rpc/rpc.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/queue.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <syslog.h>
+#include <sys/errno.h>
+#include "yplog.h"
+#include "ypdb.h"
+#include "ypdef.h"
+
+LIST_HEAD(domainlist, opt_domain);	/* LIST of domains */
+LIST_HEAD(maplist, opt_map);		/* LIST of maps (in a domain) */
+CIRCLEQ_HEAD(mapq, opt_map);		/* CIRCLEQ of maps (LRU) */
+
+struct opt_map {
+	mapname	map;			/* map name (malloc'd) */
+	DBM	*db;			/* database */
+	struct opt_domain *dom;		/* back ptr to our domain */
+	int	host_lookup;		/* host lookup */
+	int	secure;			/* secure map? */
+	CIRCLEQ_ENTRY(opt_map) mapsq;	/* map queue pointers */
+	LIST_ENTRY(opt_map) mapsl;	/* map list pointers */
+};
+
+struct opt_domain {
+	domainname	domain;		/* domain name (malloc'd) */
+	struct maplist	dmaps;		/* the domain's active maps */
+	LIST_ENTRY(opt_domain) domsl;   /* global linked list of domains */
+};
+
+
+struct domainlist doms;			/* global list of domains */
+struct mapq maps;			/* global queue of maps (LRU) */
+
+extern int usedns;
+
+/*
+ * ypdb_init: init the queues and lists
+ */
+
+void
+ypdb_init()
+
+{
+	LIST_INIT(&doms);
+	CIRCLEQ_INIT(&maps);
+}
+
+
+/*
+ * yp_private:
+ * Check if key is a YP private key. Return TRUE if it is and
+ * ypprivate is FALSE.
+ */
+
+int
+yp_private(key,ypprivate)
+	datum	key;
+	int	ypprivate;
+{
+/*	int	result; */
+
+  	if (ypprivate)
+	    return (FALSE);
+
+	if (key.dsize == 0 || key.dptr == NULL)
+		return (FALSE);
+
+	if (key.dsize == YP_LAST_LEN &&
+	    strncmp(key.dptr,YP_LAST_KEY,YP_LAST_LEN) == 0)
+		return(TRUE);
+	if (key.dsize == YP_INPUT_LEN &&
+	    strncmp(key.dptr,YP_INPUT_KEY,YP_INPUT_LEN) == 0)
+		return(TRUE);
+	if (key.dsize == YP_OUTPUT_LEN &&
+	    strncmp(key.dptr,YP_OUTPUT_KEY,YP_OUTPUT_LEN) == 0)
+		return(TRUE);
+	if (key.dsize == YP_MASTER_LEN &&
+	    strncmp(key.dptr,YP_MASTER_KEY,YP_MASTER_LEN) == 0)
+		return(TRUE);
+	if (key.dsize == YP_DOMAIN_LEN &&
+	    strncmp(key.dptr,YP_DOMAIN_KEY,YP_DOMAIN_LEN) == 0)
+		return(TRUE);
+	if (key.dsize == YP_INTERDOMAIN_LEN &&
+	    strncmp(key.dptr,YP_INTERDOMAIN_KEY,YP_INTERDOMAIN_LEN) == 0)
+		return(TRUE);
+	if (key.dsize == YP_SECURE_LEN &&
+	    strncmp(key.dptr,YP_SECURE_KEY,YP_SECURE_LEN) == 0)
+		return(TRUE);
+	
+	return(FALSE);
+}     
+
+/*
+ * Close least recent used map. This routine is called when we have
+ * no more file descripotors free, or we want to close all maps.
+ */
+
+void
+ypdb_close_last()
+{
+	struct opt_map *last = maps.cqh_last;
+
+	if (last == (void*)&maps) {
+		yplog("  ypdb_close_last: LRU list is empty!");
+		return;
+	}
+
+	CIRCLEQ_REMOVE(&maps, last, mapsq);	/* remove from LRU circleq */
+	LIST_REMOVE(last, mapsl);		/* remove from domain list */
+
+#ifdef DEBUG
+	yplog("  ypdb_close_last: closing map %s in domain %s [db=0x%x]",
+		last->map, last->dom->domain, last->db);
+#endif
+
+	ypdb_close(last->db);			/* close DB */
+	free(last->map);			/* free map name */
+	free(last);				/* free map */
+
+	
+}
+
+/*
+ * Close all open maps.
+ */
+
+void
+ypdb_close_all()
+{
+	
+#ifdef DEBUG
+	yplog("  ypdb_close_all(): start");
+#endif
+	while (maps.cqh_first != (void *)&maps) {
+		ypdb_close_last();
+	}
+#ifdef DEBUG
+	yplog("  ypdb_close_all(): done");
+#endif
+}
+
+/*
+ * Close Database if Open/Close Optimization isn't turned on.
+ */
+
+void
+ypdb_close_db(db)
+	DBM	*db;
+{
+#ifdef DEBUG
+	yplog("  ypdb_close_db(0x%x)", db);
+#endif
+#ifndef OPTDB
+	ypdb_close_all();
+#endif
+}
+
+/*
+ * ypdb_open_db
+ */
+
+DBM *
+ypdb_open_db(domain, map, status, map_info)
+	domainname	domain;
+	mapname		map;
+	ypstat		*status;
+	struct opt_map	**map_info;
+{
+	char map_path[MAXPATHLEN];
+	static char   *domain_key = YP_INTERDOMAIN_KEY;
+	static char   *secure_key = YP_SECURE_KEY;
+/*	struct	stat finfo; */
+	DBM	*db;
+/*	int	fd; */
+	struct opt_domain *d = NULL;
+	struct opt_map	*m = NULL;
+	datum	k,v;
+#ifdef OPTDB
+	int	i;
+#endif
+	/*
+	 * check for preloaded domain, map
+	 */
+
+	for (d = doms.lh_first ; d != NULL ; d = d->domsl.le_next) {
+		if (strcmp(domain, d->domain) == 0) break;
+	}
+
+	if (d) {
+		for (m = d->dmaps.lh_first ; m != NULL ; m = m->mapsl.le_next)
+			if (strcmp(map, m->map) == 0) break;
+	}
+
+	/*
+	 * map found open?
+	 */
+
+	if (m) {
+#ifdef DEBUG
+		yplog("  ypdb_open_db: cached open: domain=%s, map=%s, db=0x%x",
+			domain, map, m->db);
+#endif
+		CIRCLEQ_REMOVE(&maps, m, mapsq);	/* adjust LRU queue */
+		CIRCLEQ_INSERT_HEAD(&maps, m, mapsq);
+		*status = YP_TRUE;
+		return(m->db);
+	}
+
+	/* Check for illegal charcaters */
+
+	if (strchr(domain, '/')) {
+		*status = YP_NODOM;
+		return (NULL);
+	}
+	if (strchr(map, '/')) {
+		*status = YP_NOMAP;
+		return (NULL);
+	}
+
+
+	/*
+	 * open map
+	 */
+#ifdef OPTDB
+	i = 0;
+	while (i == 0) {
+#endif
+		snprintf(map_path, sizeof(map_path), "%s/%s/%s", YP_DB_PATH, 
+			 domain, map);
+		db = ypdb_open(map_path, O_RDONLY, 0444);
+#ifdef OPTDB
+		if (db == NULL) {
+#ifdef DEBUG
+			yplog("  ypdb_open_db: errno %d (%s)",
+		        errno,sys_errlist[errno]);
+#endif
+			if ((errno == ENFILE) || (errno == EMFILE)) {
+				ypdb_close_last();
+			} else {
+				i = errno;
+			}
+		} else {
+			i = 4711;
+		}
+	};
+#endif
+	*status = YP_NOMAP;		/* see note below */
+	if (db == NULL) {
+		if (errno == ENOENT) {
+#ifdef DEBUG
+			yplog("  ypdb_open_db: no map %s (domain=%s)",
+			      map, domain);
+#endif
+			return(NULL);
+		}
+#ifdef DEBUG
+		yplog("  ypdb_open_db: ypdb_open FAILED: map %s (domain=%s)", 
+			map, domain);
+#endif
+		return(NULL);
+	}
+	
+	/*
+	 * note: status now YP_NOMAP
+	 */
+
+	if (d == NULL) {		/* allocate new domain? */
+		d = (struct opt_domain *) malloc(sizeof(*d));
+		if (d) d->domain = strdup(domain);
+		if (d == NULL || d->domain == NULL) {
+			yplog("  ypdb_open_db: MALLOC failed");
+			ypdb_close(db);
+			if (d) free(d);
+			return(NULL);
+		}
+		LIST_INIT(&d->dmaps);
+		LIST_INSERT_HEAD(&doms, d, domsl);
+#ifdef DEBUG
+		yplog("  ypdb_open_db: NEW DOMAIN %s", domain);
+#endif
+	}
+
+	/*
+	 * m must be NULL since we couldn't find a map.  allocate new one
+	 */
+
+	m = (struct opt_map *) malloc(sizeof(*m));
+	if (m) {
+		m->map = strdup(map);
+	}
+	if (m == NULL || m->map == NULL) {
+		if (m) free(m);
+		yplog("  ypdb_open_db: MALLOC failed");
+		ypdb_close(db);
+		return(NULL);
+	}
+	m->db = db;
+	m->dom = d;
+	m->host_lookup = FALSE;
+	CIRCLEQ_INSERT_HEAD(&maps, m, mapsq);
+	LIST_INSERT_HEAD(&d->dmaps, m, mapsl);
+	if (strcmp(map, YP_HOSTNAME) == 0 || strcmp(map, YP_HOSTADDR) == 0) {
+		if (!usedns) {
+			k.dptr = domain_key;
+			k.dsize = YP_INTERDOMAIN_LEN;
+			v = ypdb_fetch(db,k);
+			if (v.dptr) m->host_lookup = TRUE;
+		} else {
+			m->host_lookup = TRUE;
+		}
+	}
+	m->secure = FALSE;
+	k.dptr = secure_key;
+	k.dsize = YP_SECURE_LEN;
+	v = ypdb_fetch(db,k);
+	if (v.dptr) m->secure = TRUE;
+	*status = YP_TRUE;
+	if (map_info) *map_info = m;
+#ifdef DEBUG
+	     yplog("  ypdb_open_db: NEW MAP domain=%s, map=%s, hl=%d, s=%d, db=0x%x", 
+			domain, map, m->host_lookup, m->secure, m->db);
+#endif
+	return(m->db);
+}
+
+#if 0
+/*
+ * lookup host. Not needed for Rhapsody, lookupd does this stuff.
+ */
+
+ypstat
+lookup_host(nametable, host_lookup, db, keystr, result)
+	int	nametable;
+	int	host_lookup;
+	DBM	*db;
+	char	*keystr;
+	ypresp_val *result;
+{
+	struct	hostent	*host;
+	struct  in_addr *addr_name;
+	struct	in_addr addr_addr;
+	static  char val[BUFSIZ+1]; /* match libc */
+	static	hostname[MAXHOSTNAMELEN];
+	char	tmpbuf[MAXHOSTNAMELEN + 20];
+	char *v;
+	int l;
+	char	*ptr;
+	
+	if (!host_lookup) return(YP_NOKEY);
+
+	if ((_res.options & RES_INIT) == 0)
+		res_init();
+	bcopy("b", _res.lookups, sizeof("b"));
+
+	if (nametable) {
+		host = gethostbyname(keystr);
+		if (host == NULL || host->h_addrtype != AF_INET) 
+			return(YP_NOKEY);
+		addr_name = (struct in_addr *) *host->h_addr_list;
+		v = val;
+		for (; host->h_addr_list[0] != NULL; host->h_addr_list++) {
+			addr_name = (struct in_addr *)host->h_addr_list[0];
+			snprintf(tmpbuf,sizeof(tmpbuf), "%s %s\n",
+				inet_ntoa(*addr_name), host->h_name);
+			if (v - val + strlen(tmpbuf) + 1 > sizeof(val))
+				break;
+			strcpy(v, tmpbuf);
+			v = v + strlen(tmpbuf);
+		}
+		result->val.valdat_val = val;
+		result->val.valdat_len = v - val;
+		return(YP_TRUE);
+	}
+
+	inet_aton(keystr, &addr_addr);
+	host = gethostbyaddr((char *) &addr_addr, sizeof(addr_addr), AF_INET);
+	if (host == NULL) return(YP_NOKEY);
+
+	strncpy((char *)hostname, host->h_name, sizeof(hostname) - 1);
+	hostname[sizeof(hostname) - 1] = '\0';
+	host = gethostbyname((char *)hostname);
+	if (host == NULL) return(YP_NOKEY);
+
+	l = 0;
+	for(; host->h_addr_list[0] != NULL; host->h_addr_list++)
+		if (!bcmp(host->h_addr_list[0], &addr_addr, sizeof(addr_addr)))
+			l++;
+	if (l == 0) {
+		yplog("lookup_host: address %s not listed for host %s\n",
+		       inet_ntoa(addr_addr), hostname);
+		syslog(LOG_NOTICE,
+		       "ypserv: address %s not listed for host %s\n",
+		       inet_ntoa(addr_addr), hostname);
+		return(YP_NOKEY);
+	}
+
+	snprintf(val,sizeof(val),"%s %s",keystr,host->h_name);
+	l = strlen(val);
+	v = val + l;
+	while ((ptr = *(host->h_aliases)) != NULL) {
+		l = strlen(ptr);
+		if ((v - val) + l + 1 > BUFSIZ)
+			break;
+		strcpy(v, " ");
+		v += 1;
+		strcpy(v, ptr);
+		v += l;
+		host->h_aliases++;
+	}
+	result->val.valdat_val = val;
+	result->val.valdat_len = v - val;
+
+	return(YP_TRUE);
+}
+#endif 
+
+ypresp_val
+ypdb_get_record(domain, map, key, ypprivate)
+	domainname	domain;
+	mapname		map;
+	keydat		key;
+	int		ypprivate;
+{
+	static	ypresp_val res;
+/*	static	char keystr[YPMAXRECORD+1]; */
+	DBM	*db;
+	datum	k,v;
+	int	host_lookup;
+	struct opt_map *map_info = NULL;
+
+	bzero((char *)&res, sizeof(res));
+	
+	db = ypdb_open_db(domain, map, &res.stat, &map_info);
+	if (!db || res.stat < 0) 
+		return(res);
+	if (map_info)
+		host_lookup = map_info->host_lookup;
+
+	k.dptr = key.keydat_val;
+	k.dsize = key.keydat_len;
+	
+	if (yp_private(k,ypprivate)) {
+		res.stat = YP_NOKEY;
+		goto done;
+	}
+
+	v = ypdb_fetch(db, k);
+
+	/* lookupd does DNS resolution, not ypserv. */
+	if (v.dptr == NULL) {
+		res.stat = YP_NOKEY;
+		res.val.valdat_val = NULL;
+		res.val.valdat_len = 0;
+	} else {
+		res.val.valdat_val = v.dptr;
+		res.val.valdat_len = v.dsize;
+	}
+
+done:
+	ypdb_close_db(db);
+	return(res);
+	
+}
+
+ypresp_key_val
+ypdb_get_first(domain, map, ypprivate)
+	domainname domain;
+	mapname map;
+	int ypprivate;
+{
+	static ypresp_key_val res;
+	DBM	*db;
+	datum	k,v;
+
+	bzero((char *)&res, sizeof(res));
+	
+	db = ypdb_open_db(domain, map, &res.stat, NULL);
+
+	if (res.stat >= 0) {
+
+	  k = ypdb_firstkey(db);
+	  
+	  while (yp_private(k,ypprivate)) {
+	    k = ypdb_nextkey(db);
+	  };
+	  
+	  if (k.dptr == NULL) {
+	    res.stat = YP_NOKEY;
+	  } else {
+	    res.key.keydat_val = k.dptr;
+	    res.key.keydat_len = k.dsize;
+	    v = ypdb_fetch(db,k);
+	    if (v.dptr == NULL) {
+	      res.stat = YP_NOKEY;
+	    } else {
+	      res.val.valdat_val = v.dptr;
+	      res.val.valdat_len = v.dsize;
+	    }
+	  }
+	}
+
+	ypdb_close_db(db);
+	
+	return (res);
+}
+
+ypresp_key_val
+ypdb_get_next(domain, map, key, ypprivate)
+	domainname domain;
+	mapname map;
+	keydat key;
+	int ypprivate;
+{
+	static ypresp_key_val res;
+	DBM	*db;
+	datum	k,v,n;
+
+	bzero((char *)&res, sizeof(res));
+	
+	db = ypdb_open_db(domain, map, &res.stat, NULL);
+	
+	if (res.stat >= 0) {
+
+	  n.dptr = key.keydat_val;
+	  n.dsize = key.keydat_len;
+	  v.dptr = NULL;
+	  v.dsize = 0;
+	  k.dptr = NULL;
+	  k.dsize = 0;
+
+	  n = ypdb_setkey(db,n);
+
+	  if (n.dptr != NULL) {
+	    k = ypdb_nextkey(db);
+	  } else {
+	    k.dptr = NULL;
+	  };
+
+	  if (k.dptr != NULL) {
+	    while (yp_private(k,ypprivate)) {
+	      k = ypdb_nextkey(db);
+	    };
+	  };
+
+	  if (k.dptr == NULL) {
+	    res.stat = YP_NOMORE;
+	  } else {
+	    res.key.keydat_val = k.dptr;
+	    res.key.keydat_len = k.dsize;
+	    v = ypdb_fetch(db,k);
+	    if (v.dptr == NULL) {
+	      res.stat = YP_NOMORE;
+	    } else {
+	      res.val.valdat_val = v.dptr;
+	      res.val.valdat_len = v.dsize;
+	    }
+	  }
+	}
+
+	ypdb_close_db(db);
+	
+	return (res);
+}
+
+ypresp_order
+ypdb_get_order(domain, map)
+	domainname domain;
+	mapname map;
+{
+	static ypresp_order res;
+	static char   *order_key = YP_LAST_KEY;
+	char   order[MAX_LAST_LEN+1];
+	DBM	*db;
+	datum	k,v;
+
+	bzero((char *)&res, sizeof(res));
+	
+	db = ypdb_open_db(domain, map, &res.stat, NULL);
+	
+	if (res.stat >= 0) {
+
+	  k.dptr = order_key;
+	  k.dsize = YP_LAST_LEN;
+
+	  v = ypdb_fetch(db,k);
+	  if (v.dptr == NULL) {
+	    res.stat = YP_NOKEY;
+	  } else {
+	    strncpy(order, v.dptr, v.dsize);
+	    order[v.dsize] = '\0';
+	    res.ordernum = (u_int32_t)atol(order);
+	  }
+	}
+
+	ypdb_close_db(db);
+	
+	return (res);
+}
+
+ypresp_master
+ypdb_get_master(domain, map)
+	domainname domain;
+	mapname map;
+{
+	static ypresp_master res;
+	static char   *master_key = YP_MASTER_KEY;
+	static char   master[MAX_MASTER_LEN+1];
+	DBM	*db;
+	datum	k,v;
+
+	bzero((char *)&res, sizeof(res));
+	
+	db = ypdb_open_db(domain, map, &res.stat, NULL);
+	
+	if (res.stat >= 0) {
+
+	  k.dptr = master_key;
+	  k.dsize = YP_MASTER_LEN;
+
+	  v = ypdb_fetch(db,k);
+	  if (v.dptr == NULL) {
+	    res.stat = YP_NOKEY;
+	  } else {
+	    strncpy(master, v.dptr, v.dsize);
+	    master[v.dsize] = '\0';
+	    res.peer = (peername) &master;
+	  }
+	}
+
+	ypdb_close_db(db);
+	
+	return (res);
+}
+
+bool_t
+ypdb_xdr_get_all(xdrs, req)
+	XDR *xdrs;
+	ypreq_nokey *req;
+{
+	static ypresp_all resp;
+	DBM	*db;
+	datum	k,v;
+
+	bzero((char *)&resp, sizeof(resp));
+	
+	/*
+	 * open db, and advance past any private keys we may see
+	 */
+
+	db = ypdb_open_db(req->domain, req->map, 
+			&resp.ypresp_all_u.val.stat, NULL);
+	if (!db || resp.ypresp_all_u.val.stat < 0) 
+		return(FALSE);
+	k = ypdb_firstkey(db);
+	while (yp_private(k,FALSE)) {
+		k = ypdb_nextkey(db);
+	};
+	
+	while(1) {
+		
+		if (k.dptr == NULL) 
+			break;
+
+		v = ypdb_fetch(db,k);
+
+		if (v.dptr == NULL) 
+			break;
+
+		resp.more = TRUE;
+		resp.ypresp_all_u.val.stat = YP_TRUE;
+		resp.ypresp_all_u.val.key.keydat_val = k.dptr;
+		resp.ypresp_all_u.val.key.keydat_len = k.dsize;
+		resp.ypresp_all_u.val.val.valdat_val = v.dptr;
+		resp.ypresp_all_u.val.val.valdat_len = v.dsize;
+			
+		if (!xdr_ypresp_all(xdrs, &resp)) {
+#ifdef DEBUG
+			yplog("  ypdb_xdr_get_all: xdr_ypresp_all failed");
+#endif					
+			return(FALSE);
+		}
+			
+		/* advance past private keys */
+		k = ypdb_nextkey(db);
+		while (yp_private(k,FALSE)) {
+			k = ypdb_nextkey(db);
+		}
+	}
+		
+	bzero((char *)&resp, sizeof(resp));
+	resp.ypresp_all_u.val.stat = YP_NOKEY;
+	resp.more = FALSE;
+	
+	if (!xdr_ypresp_all(xdrs, &resp)) {
+#ifdef DEBUG
+		yplog("  ypdb_xdr_get_all: final xdr_ypresp_all failed");
+#endif
+		return(FALSE);
+	}
+		
+	ypdb_close_db(db);
+	
+	return (TRUE);
+}
+
+int
+ypdb_secure(domain, map)
+	domainname	domain;
+	mapname		map;
+{
+	static	ypresp_val res;
+	DBM	*db;
+	int	secure;
+	struct opt_map *map_info = NULL;
+
+	bzero((char *)&res, sizeof(res));
+	secure = FALSE;
+
+	db = ypdb_open_db(domain, map, &res.stat, &map_info);
+	if (!db || res.stat < 0) 
+		return(secure);			/* ? */
+	if (map_info)
+		secure = map_info->secure;
+
+	ypdb_close_db(db);
+	return(secure);
+}
+
diff --git a/ypserv.tproj/ypserv_proc.c b/ypserv.tproj/ypserv_proc.c
new file mode 100644
index 0000000..84accf6
--- /dev/null
+++ b/ypserv.tproj/ypserv_proc.c
@@ -0,0 +1,1061 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypserv_proc.c,v 1.14 1997/09/12 01:44:57 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: ypserv_proc.c,v 1.14 1997/09/12 01:44:57 deraadt Exp $";
+#endif
+
+#include <rpc/rpc.h>
+#include "yp.h"
+#include "ypv1.h"
+#include <rpcsvc/ypclnt.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "ypdb.h"
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "yplog.h"
+#include "ypdef.h"
+
+#ifdef DEBUG
+#define YPLOG yplog
+#else /* DEBUG */
+#define YPLOG if (!ok) yplog
+#endif /* DEBUG */
+
+extern ypresp_val ypdb_get_record();
+extern ypresp_key_val ypdb_get_first();
+extern ypresp_key_val ypdb_get_next();
+extern ypresp_order ypdb_get_order();
+extern ypresp_master ypdb_get_master();
+extern bool_t ypdb_xdr_get_all();
+extern void ypdb_close_all();
+extern int ypdb_secure();
+
+static char *True = "true";
+static char *False = "FALSE";
+#define TORF(N) ((N) ? True : False)
+void *
+ypproc_null_2_svc(argp, rqstp)
+	void *argp;
+        struct svc_req *rqstp;
+{
+	static char *result;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+
+	YPLOG("null_2: caller=[%s].%d, auth_ok=%s",
+	      inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok));
+
+	if (!ok) {
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	result = NULL;
+
+	return ((void *)&result);
+}
+
+bool_t *
+ypproc_domain_2_svc(argp, rqstp)
+	domainname *argp;
+        struct svc_req *rqstp;
+{
+	static bool_t result; /* is domain_served? */
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	static char domain_path[MAXPATHLEN];
+	struct stat finfo;
+
+	if (strchr(*argp, '/'))
+		goto bail;
+	snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp);
+	result = (bool_t) ((stat(domain_path, &finfo) == 0) &&
+				    (finfo.st_mode & S_IFDIR));
+
+	YPLOG("domain_2: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s",
+	      inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), 
+	      TORF(ok), *argp, TORF(result));
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	return (&result);
+}
+
+bool_t *
+ypproc_domain_nonack_2_svc(argp, rqstp)
+	domainname *argp;
+        struct svc_req *rqstp;
+{
+	static bool_t result; /* is domain served? */
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	static char domain_path[MAXPATHLEN];
+	struct stat finfo;
+
+	if (strchr(*argp, '/'))
+		goto bail;
+	snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp);
+	result = (bool_t) ((stat(domain_path, &finfo) == 0) &&
+				    (finfo.st_mode & S_IFDIR));
+
+	YPLOG(
+	  "domain_nonack_2: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), 
+	  *argp, TORF(result));
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (!result) {
+		return(NULL); /* don't send nack */
+	}
+
+	return (&result);
+}
+
+ypresp_val *
+ypproc_match_2_svc(argp, rqstp)
+	ypreq_key *argp;
+        struct svc_req *rqstp;
+{
+	static ypresp_val res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure = ypdb_secure(argp->domain,argp->map);
+
+	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
+		goto bail;
+	YPLOG(
+	  "match_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->domain, argp->map, argp->key.keydat_len, argp->key.keydat_val);
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
+		res.stat = YP_YPERR;
+	} else {
+		res = ypdb_get_record(argp->domain,argp->map,argp->key, FALSE);
+	}
+
+#ifdef DEBUG
+	yplog("  match2_status: %s", yperr_string(ypprot_err(res.stat)));
+#endif
+
+	return (&res);
+}
+
+ypresp_key_val *
+ypproc_first_2_svc(argp, rqstp)
+	ypreq_nokey *argp;
+        struct svc_req *rqstp;
+{
+	static ypresp_key_val res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure = ypdb_secure(argp->domain,argp->map);
+
+	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
+		goto bail;
+	YPLOG( "first_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->domain, argp->map);
+	
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
+		res.stat = YP_YPERR;
+	} else {
+		res = ypdb_get_first(argp->domain,argp->map,FALSE);
+	}
+
+#ifdef DEBUG
+	yplog("  first2_status: %s", yperr_string(ypprot_err(res.stat)));
+#endif
+
+	return (&res);
+}
+
+ypresp_key_val *
+ypproc_next_2_svc(argp, rqstp)
+	ypreq_key *argp;
+        struct svc_req *rqstp;
+{
+	static ypresp_key_val res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure = ypdb_secure(argp->domain,argp->map);
+
+	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
+		goto bail;
+	YPLOG(
+	  "next_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->domain, argp->map, argp->key.keydat_len, argp->key.keydat_val);
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
+		res.stat = YP_YPERR;
+	} else {
+		res = ypdb_get_next(argp->domain,argp->map,argp->key,FALSE);
+	}
+
+#ifdef DEBUG
+	yplog("  next2_status: %s", yperr_string(ypprot_err(res.stat)));
+#endif
+
+	return (&res);
+}
+
+ypresp_xfr *
+ypproc_xfr_2_svc(argp, rqstp)
+	ypreq_xfr *argp;
+        struct svc_req *rqstp;
+{
+	static ypresp_xfr res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	pid_t	pid;
+	char	tid[11];
+	char	prog[11];
+	char	port[11];
+	char	ypxfr_proc[] = YPXFR_PROC;
+	char	*ipadd;
+
+	bzero((char *)&res, sizeof(res));
+
+	YPLOG("xfr_2: caller=[%s].%d, auth_ok=%s, domain=%s, tid=%d, prog=%d",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), 
+	  argp->map_parms.domain, argp->transid, argp->prog);
+	YPLOG("       ipadd=%s, port=%d, map=%s", inet_ntoa(caller->sin_addr),
+	  argp->port, argp->map_parms.map);
+
+	if (strchr(argp->map_parms.domain, '/') ||
+	    strchr(argp->map_parms.map, '/') ||
+	    ntohs(caller->sin_port) >= IPPORT_RESERVED) {
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	snprintf(tid, sizeof(tid), "%d",argp->transid);
+	snprintf(prog, sizeof(prog), "%d", argp->prog);
+	snprintf(port, sizeof(port), "%d", argp->port);
+	ipadd = inet_ntoa(caller->sin_addr);
+
+	pid = vfork();
+	if (pid == -1) {
+		svcerr_systemerr(rqstp->rq_xprt);
+		return(NULL);
+	}
+	if (pid == 0) {
+		execl(ypxfr_proc, "ypxfr", "-d", argp->map_parms.domain,
+		    "-C",tid, prog, ipadd, port, argp->map_parms.map, NULL);
+		_exit(1);
+	}
+	
+	/*
+	 * XXX: fill in res
+	 */
+	return (&res);
+}
+
+void *
+ypproc_clear_2_svc(argp, rqstp)
+	void *argp;
+        struct svc_req *rqstp;
+{
+	static char *res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+
+	YPLOG( "clear_2: caller=[%s].%d, auth_ok=%s, opt=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok),
+#ifdef OPTDB
+		True
+#else
+		False
+#endif
+	);
+
+	if (ntohs(caller->sin_port) >= IPPORT_RESERVED)
+		ok = FALSE;
+
+	if (!ok) {
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	res = NULL;
+	
+#ifdef OPTDB
+        ypdb_close_all();
+#endif
+
+	return ((void *)&res);
+}
+
+ypresp_all *
+ypproc_all_2_svc(argp, rqstp)
+	ypreq_nokey *argp;
+        struct svc_req *rqstp;
+{
+	static ypresp_all res;
+	pid_t pid;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure = ypdb_secure(argp->domain,argp->map);
+
+	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
+		goto bail;
+	YPLOG( "all_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure), argp->domain, argp->map);
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	bzero((char *)&res, sizeof(res));
+	
+	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
+		res.ypresp_all_u.val.stat = YP_YPERR;
+		return(&res);
+	}
+
+	pid = fork();
+
+	if (pid) {
+
+		if (pid == -1) {
+			/* XXXCDC An error has occurred */
+		}
+		
+		return(NULL); /* PARENT: continue */
+		
+	}
+	/* CHILD: send result, then exit */
+
+	if (!svc_sendreply(rqstp->rq_xprt, ypdb_xdr_get_all, (char *) argp)) {
+		svcerr_systemerr(rqstp->rq_xprt);
+	}
+
+	/* note: no need to free args, we are exiting */
+
+	exit(0);
+}
+
+ypresp_master *
+ypproc_master_2_svc(argp, rqstp)
+	ypreq_nokey *argp;
+        struct svc_req *rqstp;
+{
+	static ypresp_master res;
+	static peername nopeer = "";
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure = ypdb_secure(argp->domain,argp->map);
+
+	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
+		goto bail;
+	YPLOG( "master_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure), argp->domain, argp->map);
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
+		res.stat = YP_YPERR;
+	} else {
+		res = ypdb_get_master(argp->domain,argp->map);
+	}
+
+#ifdef DEBUG
+	yplog("  master2_status: %s", yperr_string(ypprot_err(res.stat)));
+#endif
+
+	/* This code was added because a yppoll <unknown-domain> */
+	/* from a sun crashed the server in xdr_string, trying   */
+	/* to access the peer through a NULL-pointer. yppoll in  */
+	/* this server start asking for order. If order is ok    */
+	/* then it will ask for master. SunOS 4 asks for both    */
+	/* always. I'm not sure this is the best place for the   */
+	/* fix, but for now it will do. xdr_peername or          */
+	/* xdr_string in ypserv_xdr.c may be a better place?     */
+	
+	if (res.peer == NULL) {
+		res.peer = nopeer;
+	}
+
+	/* End of fix                                            */
+
+	return (&res);
+}
+
+
+ypresp_order *
+ypproc_order_2_svc(argp, rqstp)
+	ypreq_nokey *argp;
+        struct svc_req *rqstp;
+{
+	static ypresp_order res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure = ypdb_secure(argp->domain,argp->map);
+
+	if (strchr(argp->domain, '/'))
+		goto bail;
+	YPLOG( "order_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure), argp->domain, argp->map);
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
+		res.stat = YP_YPERR;
+	} else if (strchr(argp->map, '/')) {
+		res.stat = YP_NOMAP;
+	} else {
+		res = ypdb_get_order(argp->domain,argp->map);
+	}
+
+#ifdef DEBUG
+	yplog("  order2_status: %s", yperr_string(ypprot_err(res.stat)));
+#endif
+
+	return (&res);
+}
+
+
+ypresp_maplist *
+ypproc_maplist_2_svc(argp, rqstp)
+	domainname *argp;
+        struct svc_req *rqstp;
+{
+	static ypresp_maplist res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	static char domain_path[MAXPATHLEN];
+	struct stat finfo;
+	DIR   *dirp = NULL;
+	struct dirent *dp;
+	char  *suffix;
+	ypstat status;
+	struct ypmaplist *m;
+	char  *map_name;
+
+	if (strchr(*argp, '/'))
+		goto bail;
+	YPLOG("maplist_2: caller=[%s].%d, auth_ok=%s, domain=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok),
+	  *argp);
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	bzero((char *)&res, sizeof(res));
+	
+	snprintf(domain_path,MAXPATHLEN, "%s/%s",YP_DB_PATH,*argp);
+
+	status = YP_TRUE;
+
+	res.maps = NULL;
+
+	if (!((stat(domain_path, &finfo) == 0) &&
+		((finfo.st_mode & S_IFMT) == S_IFDIR))) 
+		status = YP_NODOM;
+
+	if (status >= 0) {
+	  if ((dirp = opendir(domain_path)) == NULL) {
+	    status = YP_NODOM;
+	  }
+	}
+
+	if (status >= 0) {
+	  for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+	    if ((!strcmp(dp->d_name, ".")) ||
+		((!strcmp(dp->d_name, ".."))) ||
+		(dp->d_namlen < 4))
+	      continue;
+	    suffix = (char *) &dp->d_name[dp->d_namlen-3];
+	    if (strcmp(suffix,".db") == 0) {
+
+	      if ((m = (struct ypmaplist *)
+		   malloc((unsigned) sizeof(struct ypmaplist))) == NULL) {
+		status = YP_YPERR;
+		break;
+	      }
+
+	      if ((map_name = (char *)
+		   malloc((unsigned) dp->d_namlen - 2)) == NULL) {
+		status = YP_YPERR;
+		break;
+	      }
+
+	      m->next = res.maps;
+	      m->map = map_name;
+	      res.maps = m;
+	      strncpy(map_name, dp->d_name, dp->d_namlen - 3);
+	      m->map[dp->d_namlen - 3] = '\0';
+	      
+	    }
+	  }
+	}
+	
+	if (dirp != NULL) {
+	  closedir(dirp);
+	}
+
+	res.stat = status;
+	
+#ifdef DEBUG
+	yplog("  maplist_status: %s", yperr_string(ypprot_err(res.stat)));
+#endif
+
+	return (&res);
+}
+
+void *
+ypproc_null_1_svc(argp, rqstp)
+	void *argp;
+        struct svc_req *rqstp;
+{
+	static char *result;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+
+	YPLOG("null_1: caller=[%s].%d, auth_ok=%s",
+	      inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok));
+
+	if (!ok) {
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	result = NULL;
+
+	return ((void *)&result);
+}
+
+bool_t *
+ypproc_domain_1_svc(argp, rqstp)
+	domainname *argp;
+        struct svc_req *rqstp;
+{
+	static bool_t result; /* is domain_served? */
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	static char domain_path[MAXPATHLEN];
+	struct stat finfo;
+
+	if (strchr(*argp, '/'))
+		goto bail;
+	snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp);
+	result = (bool_t) ((stat(domain_path, &finfo) == 0) &&
+				    (finfo.st_mode & S_IFDIR));
+
+	YPLOG("domain_1: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s",
+	      inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), 
+	      TORF(ok), *argp, TORF(result));
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	return (&result);
+}
+
+bool_t *
+ypproc_domain_nonack_1_svc(argp, rqstp)
+	domainname *argp;
+        struct svc_req *rqstp;
+{
+	static bool_t result; /* is domain served? */
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	static char domain_path[MAXPATHLEN];
+	struct stat finfo;
+
+	if (strchr(*argp, '/'))
+		goto bail;
+	snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp);
+	result = (bool_t) ((stat(domain_path, &finfo) == 0) &&
+				    (finfo.st_mode & S_IFDIR));
+
+	YPLOG(
+	  "domain_nonack_1: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), 
+	  *argp, TORF(result));
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (!result) {
+		return(NULL); /* don't send nack */
+	}
+
+	return (&result);
+}
+
+ypresponse *
+ypproc_match_1_svc(argp, rqstp)
+	yprequest *argp;
+        struct svc_req *rqstp;
+{
+	static ypresponse res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure;
+
+	if (strchr(argp->ypmatch_req_domain, '/') ||
+	    strchr(argp->ypmatch_req_map, '/'))
+		goto bail;
+	res.yp_resptype = YPMATCH_RESPTYPE;
+	res.ypmatch_resp_valptr = "";
+	res.ypmatch_resp_valsize = 0;
+
+	if (argp->yp_reqtype != YPMATCH_REQTYPE) {
+		res.ypmatch_resp_status = YP_BADARGS;
+		return(&res);
+	}
+
+	secure = ypdb_secure(argp->ypmatch_req_domain, argp->ypmatch_req_map);
+
+	YPLOG(
+	  "match_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->ypmatch_req_domain,  argp->ypmatch_req_map,
+	  argp->ypmatch_req_keysize, argp->ypmatch_req_keyptr);
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
+		res.ypmatch_resp_status = YP_YPERR;
+	} else {
+		res.ypmatch_resp_val =
+		      ypdb_get_record(argp->ypmatch_req_domain,
+				      argp->ypmatch_req_map,
+				      argp->ypmatch_req_keydat,
+				      FALSE);
+	}
+
+#ifdef DEBUG
+	yplog("  match1_status: %s",
+	      yperr_string(ypprot_err(res.ypmatch_resp_status)));
+#endif
+
+	return (&res);
+}
+
+ypresponse *
+ypproc_first_1_svc(argp, rqstp)
+	yprequest *argp;
+        struct svc_req *rqstp;
+{
+	static ypresponse res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure;
+
+	if (strchr(argp->ypfirst_req_domain, '/') ||
+	    strchr(argp->ypfirst_req_map, '/'))
+		goto bail;
+	res.yp_resptype = YPFIRST_RESPTYPE;
+	res.ypfirst_resp_valptr  = res.ypfirst_resp_keyptr  = "";
+	res.ypfirst_resp_valsize = res.ypfirst_resp_keysize = 0;
+
+	if (argp->yp_reqtype != YPREQ_NOKEY) {
+		res.ypfirst_resp_status = YP_BADARGS;
+		return(&res);
+	}
+
+	secure = ypdb_secure(argp->ypfirst_req_domain, argp->ypfirst_req_map);
+
+	YPLOG( "first_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->ypfirst_req_domain, argp->ypfirst_req_map);
+	
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
+		res.ypfirst_resp_status = YP_YPERR;
+	} else {
+		res.ypfirst_resp_val =
+		      ypdb_get_first(argp->ypfirst_req_domain,
+				     argp->ypfirst_req_map,
+				     FALSE);
+	}
+
+#ifdef DEBUG
+	yplog("  first1_status: %s",
+	      yperr_string(ypprot_err(res.ypfirst_resp_status)));
+#endif
+
+	return (&res);
+}
+
+ypresponse *
+ypproc_next_1_svc(argp, rqstp)
+	yprequest *argp;
+        struct svc_req *rqstp;
+{
+	static ypresponse res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure;
+
+	if (strchr(argp->ypnext_req_domain, '/') ||
+	    strchr(argp->ypnext_req_map, '/'))
+		goto bail;
+	res.yp_resptype = YPNEXT_RESPTYPE;
+	res.ypnext_resp_valptr  = res.ypnext_resp_keyptr  = "";
+	res.ypnext_resp_valsize = res.ypnext_resp_keysize = 0;
+
+	if (argp->yp_reqtype != YPNEXT_REQTYPE) {
+		res.ypnext_resp_status = YP_BADARGS;
+		return(&res);
+	}
+
+	secure = ypdb_secure(argp->ypnext_req_domain, argp->ypnext_req_map);
+
+	YPLOG(
+	  "next_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->ypnext_req_domain,  argp->ypnext_req_map,
+	  argp->ypnext_req_keysize, argp->ypnext_req_keyptr);
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
+		res.ypnext_resp_status = YP_YPERR;
+	} else {
+		res.ypnext_resp_val =
+		      ypdb_get_next(argp->ypnext_req_domain,
+				    argp->ypnext_req_map,
+				    argp->ypnext_req_keydat,
+				    FALSE);
+	}
+
+#ifdef DEBUG
+	yplog("  next1_status: %s",
+	      yperr_string(ypprot_err(res.ypnext_resp_status)));
+#endif
+
+	return (&res);
+}
+
+ypresponse *
+ypproc_poll_1_svc(argp, rqstp)
+	yprequest *argp;
+        struct svc_req *rqstp;
+{
+	static ypresponse res;
+	ypresp_order order;
+	ypresp_master master;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure;
+
+	if (strchr(argp->yppoll_req_domain, '/') ||
+	    strchr(argp->yppoll_req_map, '/'))
+		goto bail;
+	res.yp_resptype = YPPOLL_RESPTYPE;
+	res.yppoll_resp_domain = argp->yppoll_req_domain;
+	res.yppoll_resp_map = argp->yppoll_req_map;
+	res.yppoll_resp_ordernum = 0;
+	res.yppoll_resp_owner = "";
+
+	if (argp->yp_reqtype != YPPOLL_REQTYPE) {
+		return(&res);
+	}
+
+	secure = ypdb_secure(argp->yppoll_req_domain, argp->yppoll_req_map);
+
+	YPLOG( "poll_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->yppoll_req_domain, argp->yppoll_req_map);
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	if (!(secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED))) {
+		order = ypdb_get_order(argp->yppoll_req_domain,
+				       argp->yppoll_req_map);
+		master = ypdb_get_master(argp->yppoll_req_domain,
+					 argp->yppoll_req_map);
+		res.yppoll_resp_ordernum = order.ordernum;
+		res.yppoll_resp_owner = master.peer;
+	}
+
+#ifdef DEBUG
+	yplog("  poll1_status: %s", "none");
+#endif
+	return (&res);
+}
+
+void *
+ypproc_push_1_svc(argp, rqstp)
+	yprequest *argp;
+        struct svc_req *rqstp;
+{
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure;
+	pid_t	pid;
+	char	yppush_proc[] = YPPUSH_PROC;
+
+	if (strchr(argp->yppush_req_domain, '/') ||
+	    strchr(argp->yppush_req_map, '/'))
+		goto bail;
+	if (argp->yp_reqtype != YPPUSH_REQTYPE) {
+		return(NULL);
+	}
+
+	secure = ypdb_secure(argp->yppush_req_domain, argp->yppush_req_map);
+
+	YPLOG( "push_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->yppush_req_domain, argp->yppush_req_map);
+
+	if (ntohs(caller->sin_port) >= IPPORT_RESERVED)
+		ok = FALSE;
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	pid = vfork();
+	if (pid == -1) {
+		svcerr_systemerr(rqstp->rq_xprt);
+		return(NULL);
+	}
+	if (pid == 0) {
+		execl(yppush_proc, "yppush", "-d", argp->yppush_req_domain,
+		      argp->yppush_req_map, NULL);
+		_exit(1);
+	}
+	
+	return (NULL);
+}
+
+void *
+ypproc_pull_1_svc(argp, rqstp)
+	yprequest *argp;
+        struct svc_req *rqstp;
+{
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure;
+	pid_t	pid;
+	char	ypxfr_proc[] = YPXFR_PROC;
+
+	if (strchr(argp->yppull_req_domain, '/') ||
+	    strchr(argp->yppull_req_map, '/'))
+		goto bail;
+	if (argp->yp_reqtype != YPPULL_REQTYPE) {
+		return(NULL);
+	}
+
+	secure = ypdb_secure(argp->yppull_req_domain, argp->yppull_req_map);
+
+	YPLOG( "pull_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->yppull_req_domain, argp->yppull_req_map);
+
+	if (ntohs(caller->sin_port) >= IPPORT_RESERVED)
+		ok = FALSE;
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	pid = vfork();
+	if (pid == -1) {
+		svcerr_systemerr(rqstp->rq_xprt);
+		return(NULL);
+	}
+	if (pid == 0) {
+		execl(ypxfr_proc, "ypxfr", "-d", argp->yppull_req_domain,
+		      argp->yppull_req_map, NULL);
+		_exit(1);
+	}
+	
+	return (NULL);
+}
+
+void *
+ypproc_get_1_svc(argp, rqstp)
+	yprequest *argp;
+        struct svc_req *rqstp;
+{
+	char *res;
+	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
+	int ok = acl_check_host(&caller->sin_addr);
+	int secure;
+	pid_t	pid;
+	char	ypxfr_proc[] = YPXFR_PROC;
+
+	if (strchr(argp->ypget_req_domain, '/') ||
+	    strchr(argp->ypget_req_map, '/'))
+		goto bail;
+	if (argp->yp_reqtype != YPGET_REQTYPE) {
+		return(NULL);
+	}
+
+	secure = ypdb_secure(argp->ypget_req_domain, argp->ypget_req_map);
+
+	YPLOG( "get_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, owner=%s",
+	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
+	  TORF(ok), TORF(secure),
+	  argp->ypget_req_domain, argp->ypget_req_map,
+	  argp->ypget_req_owner);
+
+	if (ntohs(caller->sin_port) >= IPPORT_RESERVED)
+		ok = FALSE;
+
+	if (!ok) {
+bail:
+		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
+		return(NULL);
+	}
+
+	pid = vfork();
+	if (pid == -1) {
+		svcerr_systemerr(rqstp->rq_xprt);
+		return(NULL);
+	}
+	if (pid == 0) {
+		execl(ypxfr_proc, "ypxfr", "-d", argp->ypget_req_domain, "-h",
+		      argp->ypget_req_owner, argp->yppush_req_map, NULL);
+		_exit(1);
+	}
+	
+	return (NULL);
+}
diff --git a/ypserv.tproj/ypserv_xdr.c b/ypserv.tproj/ypserv_xdr.c
new file mode 100644
index 0000000..2e1fb2a
--- /dev/null
+++ b/ypserv.tproj/ypserv_xdr.c
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "yp.h"
+#ifndef lint
+static char rcsid[] = "$OpenBSD: ypserv_xdr.c,v 1.3 1996/05/30 09:53:31 deraadt Exp $";
+#endif /* not lint */
+
+__private_extern__
+bool_t
+xdr_ypstat(xdrs, objp)
+	XDR *xdrs;
+	ypstat *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+bool_t
+xdr_ypxfrstat(xdrs, objp)
+	XDR *xdrs;
+	ypxfrstat *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_domainname(xdrs, objp)
+	XDR *xdrs;
+	domainname *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_mapname(xdrs, objp)
+	XDR *xdrs;
+	mapname *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_string(xdrs, objp, YPMAXMAP)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_peername(xdrs, objp)
+	XDR *xdrs;
+	peername *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_string(xdrs, objp, YPMAXPEER)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_keydat(xdrs, objp)
+	XDR *xdrs;
+	keydat *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_bytes(xdrs, (char **)&objp->keydat_val, (u_int *)&objp->keydat_len, YPMAXRECORD)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_valdat(xdrs, objp)
+	XDR *xdrs;
+	valdat *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_bytes(xdrs, (char **)&objp->valdat_val, (u_int *)&objp->valdat_len, YPMAXRECORD)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+bool_t
+xdr_ypmap_parms(xdrs, objp)
+	XDR *xdrs;
+	ypmap_parms *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_domainname(xdrs, &objp->domain)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_mapname(xdrs, &objp->map)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_u_int(xdrs, &objp->ordernum)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_peername(xdrs, &objp->peer)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypreq_key(xdrs, objp)
+	XDR *xdrs;
+	ypreq_key *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_domainname(xdrs, &objp->domain)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_mapname(xdrs, &objp->map)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_keydat(xdrs, &objp->key)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypreq_nokey(xdrs, objp)
+	XDR *xdrs;
+	ypreq_nokey *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_domainname(xdrs, &objp->domain)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_mapname(xdrs, &objp->map)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+bool_t
+xdr_ypreq_xfr(xdrs, objp)
+	XDR *xdrs;
+	ypreq_xfr *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_ypmap_parms(xdrs, &objp->map_parms)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_u_int(xdrs, &objp->transid)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_u_int(xdrs, &objp->prog)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_u_int(xdrs, &objp->port)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypresp_val(xdrs, objp)
+	XDR *xdrs;
+	ypresp_val *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_ypstat(xdrs, &objp->stat)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_valdat(xdrs, &objp->val)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypresp_key_val(xdrs, objp)
+	XDR *xdrs;
+	ypresp_key_val *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_ypstat(xdrs, &objp->stat)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_valdat(xdrs, &objp->val)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_keydat(xdrs, &objp->key)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypresp_master(xdrs, objp)
+	XDR *xdrs;
+	ypresp_master *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_ypstat(xdrs, &objp->stat)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_peername(xdrs, &objp->peer)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypresp_order(xdrs, objp)
+	XDR *xdrs;
+	ypresp_order *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_ypstat(xdrs, &objp->stat)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_u_int(xdrs, &objp->ordernum)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypresp_all(xdrs, objp)
+	XDR *xdrs;
+	ypresp_all *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_bool(xdrs, &objp->more)) {
+		 return (FALSE);
+	 }
+	switch (objp->more) {
+	case TRUE:
+		 if (!xdr_ypresp_key_val(xdrs, &objp->ypresp_all_u.val)) {
+			 return (FALSE);
+		 }
+		break;
+	case FALSE:
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_ypresp_xfr(xdrs, objp)
+	XDR *xdrs;
+	ypresp_xfr *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_u_int(xdrs, &objp->transid)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_ypxfrstat(xdrs, &objp->xfrstat)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypmaplist(xdrs, objp)
+	XDR *xdrs;
+	ypmaplist *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_mapname(xdrs, &objp->map)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof(ypmaplist), (xdrproc_t)xdr_ypmaplist)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypresp_maplist(xdrs, objp)
+	XDR *xdrs;
+	ypresp_maplist *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_ypstat(xdrs, &objp->stat)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_pointer(xdrs, (char **)&objp->maps, sizeof(ypmaplist), (xdrproc_t)xdr_ypmaplist)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+bool_t
+xdr_yppush_status(xdrs, objp)
+	XDR *xdrs;
+	yppush_status *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+bool_t
+xdr_yppushresp_xfr(xdrs, objp)
+	XDR *xdrs;
+	yppushresp_xfr *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_u_int(xdrs, &objp->transid)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_yppush_status(xdrs, &objp->status)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypbind_resptype(xdrs, objp)
+	XDR *xdrs;
+	ypbind_resptype *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypbind_binding(xdrs, objp)
+	XDR *xdrs;
+	ypbind_binding *objp;
+{
+
+	 register long *buf;
+
+	 int i;
+	 if (!xdr_opaque(xdrs, objp->ypbind_binding_addr, 4)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_opaque(xdrs, objp->ypbind_binding_port, 2)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+__private_extern__
+bool_t
+xdr_ypbind_resp(xdrs, objp)
+	XDR *xdrs;
+	ypbind_resp *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_ypbind_resptype(xdrs, &objp->ypbind_status)) {
+		 return (FALSE);
+	 }
+	switch (objp->ypbind_status) {
+	case YPBIND_FAIL_VAL:
+		 if (!xdr_u_int(xdrs, &objp->ypbind_resp_u.ypbind_error)) {
+			 return (FALSE);
+		 }
+		break;
+	case YPBIND_SUCC_VAL:
+		 if (!xdr_ypbind_binding(xdrs, &objp->ypbind_resp_u.ypbind_bindinfo)) {
+			 return (FALSE);
+		 }
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_ypbind_setdom(xdrs, objp)
+	XDR *xdrs;
+	ypbind_setdom *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_domainname(xdrs, &objp->ypsetdom_domain)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_ypbind_binding(xdrs, &objp->ypsetdom_binding)) {
+		 return (FALSE);
+	 }
+	 if (!xdr_u_int(xdrs, &objp->ypsetdom_vers)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
diff --git a/ypserv.tproj/ypserv_xdr_v1.c b/ypserv.tproj/ypserv_xdr_v1.c
new file mode 100644
index 0000000..3870f58
--- /dev/null
+++ b/ypserv.tproj/ypserv_xdr_v1.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "yp.h"
+#include "ypv1.h"
+#ifndef lint
+static char rcsid[] = "$OpenBSD: ypserv_xdr_v1.c,v 1.1 1997/03/30 20:51:22 maja Exp $";
+#endif /* not lint */
+
+bool_t
+xdr_ypreqtype(xdrs, objp)
+	XDR *xdrs;
+	ypreqtype *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+bool_t
+xdr_ypresptype(xdrs, objp)
+	XDR *xdrs;
+	ypresptype *objp;
+{
+
+	 register long *buf;
+
+	 if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		 return (FALSE);
+	 }
+	return (TRUE);
+}
+
+bool_t
+xdr_yprequest(xdrs, objp)
+	XDR *xdrs;
+	yprequest *objp;
+{
+	if (!xdr_ypreqtype(xdrs, &objp->yp_reqtype)) {
+		printf("error 1\n");
+		return (FALSE);
+	}
+	switch (objp->yp_reqtype) {
+	case YPREQ_KEY:
+		if (!xdr_ypreq_key(xdrs, &objp->yp_reqbody.yp_req_keytype)) {
+			printf("error 2\n");
+			return (FALSE);
+		}
+		break;
+	case YPREQ_NOKEY:
+		if (!xdr_ypreq_nokey(xdrs, &objp->yp_reqbody.yp_req_nokeytype)) {
+			printf("error 3\n");
+			return (FALSE);
+		}
+		break;
+	case YPREQ_MAP_PARMS:
+		if (!xdr_ypmap_parms(xdrs, &objp->yp_reqbody.yp_req_map_parmstype)) {
+			printf("error 4\n");
+			return (FALSE);
+		}
+		break;
+	default:
+		printf("error 5\n");
+		return (FALSE);	 	
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_ypresponse(xdrs, objp)
+	XDR *xdrs;
+	ypresponse *objp;
+{
+
+	register long *buf;
+
+	if (!xdr_ypresptype(xdrs, &objp->yp_resptype)) {
+		return (FALSE);
+	}
+	switch (objp->yp_resptype) {
+	case YPRESP_VAL:
+		if (!xdr_ypresp_val(xdrs, &objp->yp_respbody.yp_resp_valtype)) {
+			return (FALSE);
+		}
+		break;
+	case YPRESP_KEY_VAL:
+		if (!xdr_ypresp_key_val(xdrs, &objp->yp_respbody.yp_resp_key_valtype)) {
+			return (FALSE);
+		}
+		break;
+	case YPRESP_MAP_PARMS:
+		if (!xdr_ypmap_parms(xdrs, &objp->yp_respbody.yp_resp_map_parmstype)) {
+			return (FALSE);
+		}
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
diff --git a/ypserv.tproj/ypv1.h b/ypserv.tproj/ypv1.h
new file mode 100644
index 0000000..d378f83
--- /dev/null
+++ b/ypserv.tproj/ypv1.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: ypv1.h,v 1.2 1997/07/25 20:12:31 mickey Exp $ */
+
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _YPV1_H_RPCGEN
+#define _YPV1_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+#define YPOLDVERS ((u_long)1)
+
+enum ypreqtype {
+	YPREQ_KEY = 1,
+	YPREQ_NOKEY = 2,
+	YPREQ_MAP_PARMS = 3
+};
+typedef enum ypreqtype ypreqtype;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypreqtype(XDR *, ypreqtype*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypreqtype(XDR *, ypreqtype*);
+#else /* Old Style C */ 
+bool_t xdr_ypreqtype();
+#endif /* Old Style C */ 
+
+typedef struct {
+	ypreqtype yp_reqtype;
+	union {
+		struct ypreq_key yp_req_keytype;
+		struct ypreq_nokey yp_req_nokeytype;
+		struct ypmap_parms yp_req_map_parmstype;
+	}yp_reqbody;
+} yprequest;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_yprequest(XDR *, yprequest*);
+#elif defined(__STDC__)
+extern  bool_t xdr_yprequest(XDR *, yprequest*);
+#else /* Old Style C */ 
+bool_t xdr_yprequest();
+#endif /* Old Style C */ 
+
+#define YPMATCH_REQTYPE YPREQ_KEY
+#define ypmatch_req_domain yp_reqbody.yp_req_keytype.domain
+#define ypmatch_req_map yp_reqbody.yp_req_keytype.map
+#define ypmatch_req_keydat yp_reqbody.yp_req_keytype.key
+#define ypmatch_req_keyptr yp_reqbody.yp_req_keytype.key.keydat_val
+#define ypmatch_req_keysize yp_reqbody.yp_req_keytype.key.keydat_len
+
+#define YPFIRST_REQTYPE YPREQ_NOKEY
+#define ypfirst_req_domain yp_reqbody.yp_req_nokeytype.domain
+#define ypfirst_req_map yp_reqbody.yp_req_nokeytype.map
+
+#define YPNEXT_REQTYPE YPREQ_KEY
+#define ypnext_req_domain yp_reqbody.yp_req_keytype.domain
+#define ypnext_req_map yp_reqbody.yp_req_keytype.map
+#define ypnext_req_keydat yp_reqbody.yp_req_keytype.key
+#define ypnext_req_keyptr yp_reqbody.yp_req_keytype.key.keydat_val
+#define ypnext_req_keysize yp_reqbody.yp_req_keytype.key.keydat_len
+
+#define YPPUSH_REQTYPE YPREQ_NOKEY
+#define yppush_req_domain yp_reqbody.yp_req_nokeytype.domain
+#define yppush_req_map yp_reqbody.yp_req_nokeytype.map
+
+#define YPPULL_REQTYPE YPREQ_NOKEY
+#define yppull_req_domain yp_reqbody.yp_req_nokeytype.domain
+#define yppull_req_map yp_reqbody.yp_req_nokeytype.map
+
+#define YPPOLL_REQTYPE YPREQ_NOKEY
+#define yppoll_req_domain yp_reqbody.yp_req_nokeytype.domain
+#define yppoll_req_map yp_reqbody.yp_req_nokeytype.map
+
+#define YPGET_REQTYPE YPREQ_MAP_PARMS
+#define ypget_req_domain yp_reqbody.yp_req_map_parmstype.domain
+#define ypget_req_map yp_reqbody.yp_req_map_parmstype.map
+#define ypget_req_ordernum yp_reqbody.yp_req_map_parmstype.ordernum
+#define ypget_req_owner yp_reqbody.yp_req_map_parmstype.peer
+
+enum ypresptype {
+	YPRESP_VAL = 1,
+	YPRESP_KEY_VAL = 2,
+	YPRESP_MAP_PARMS = 3
+};
+typedef enum ypresptype ypresptype;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypresptype(XDR *, ypresptype*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypresptype(XDR *, ypresptype*);
+#else /* Old Style C */ 
+bool_t xdr_ypresptype();
+#endif /* Old Style C */ 
+
+typedef struct {
+	ypresptype yp_resptype;
+	union {
+		struct ypresp_val yp_resp_valtype;
+		struct ypresp_key_val yp_resp_key_valtype;
+		struct ypmap_parms yp_resp_map_parmstype;
+	} yp_respbody;
+} ypresponse;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_ypresponse(XDR *, ypresponse*);
+#elif defined(__STDC__)
+extern  bool_t xdr_ypresponse(XDR *, ypresponse*);
+#else /* Old Style C */ 
+bool_t xdr_ypresponse();
+#endif /* Old Style C */ 
+
+#define YPMATCH_RESPTYPE YPRESP_VAL
+#define ypmatch_resp_status yp_respbody.yp_resp_valtype.stat
+#define ypmatch_resp_val yp_respbody.yp_resp_valtype
+#define ypmatch_resp_valdat yp_respbody.yp_resp_valtype.val
+#define ypmatch_resp_valptr yp_respbody.yp_resp_valtype.val.valdat_val
+#define ypmatch_resp_valsize yp_respbody.yp_resp_valtype.val.valdat_len
+
+#define YPFIRST_RESPTYPE YPRESP_KEY_VAL
+#define ypfirst_resp_status yp_respbody.yp_resp_key_valtype.stat
+#define ypfirst_resp_keydat yp_respbody.yp_resp_key_valtype.key
+#define ypfirst_resp_keyptr yp_respbody.yp_resp_key_valtype.key.keydat_val
+#define ypfirst_resp_keysize yp_respbody.yp_resp_key_valtype.key.keydat_len
+#define ypfirst_resp_val yp_respbody.yp_resp_key_valtype
+#define ypfirst_resp_valdat yp_respbody.yp_resp_key_valtype.val
+#define ypfirst_resp_valptr yp_respbody.yp_resp_key_valtype.val.valdat_val
+#define ypfirst_resp_valsize yp_respbody.yp_resp_key_valtype.val.valdat_len
+
+#define YPNEXT_RESPTYPE YPRESP_KEY_VAL
+#define ypnext_resp_status yp_respbody.yp_resp_key_valtype.stat
+#define ypnext_resp_keydat yp_respbody.yp_resp_key_valtype.key
+#define ypnext_resp_keyptr yp_respbody.yp_resp_key_valtype.key.keydat_val
+#define ypnext_resp_keysize yp_respbody.yp_resp_key_valtype.key.keydat_len
+#define ypnext_resp_val yp_respbody.yp_resp_key_valtype
+#define ypnext_resp_valdat yp_respbody.yp_resp_key_valtype.val
+#define ypnext_resp_valptr yp_respbody.yp_resp_key_valtype.val.valdat_val
+#define ypnext_resp_valsize yp_respbody.yp_resp_key_valtype.val.valdat_len
+
+#define YPPOLL_RESPTYPE YPRESP_MAP_PARMS
+#define yppoll_resp_domain yp_respbody.yp_resp_map_parmstype.domain
+#define yppoll_resp_map yp_respbody.yp_resp_map_parmstype.map
+#define yppoll_resp_ordernum yp_respbody.yp_resp_map_parmstype.ordernum
+#define yppoll_resp_owner yp_respbody.yp_resp_map_parmstype.peer
+
+#ifdef __cplusplus
+#define YPOLDPROC_NULL ((u_long)0)
+extern "C" void * ypproc_null_1(void *, CLIENT *);
+extern "C" void * ypproc_null_1_svc(void *, struct svc_req *);
+#define YPOLDPROC_DOMAIN ((u_long)1)
+extern "C" bool_t * ypproc_domain_1(domainname *, CLIENT *);
+extern "C" bool_t * ypproc_domain_1_svc(domainname *, struct svc_req *);
+#define YPOLDPROC_DOMAIN_NONACK ((u_long)2)
+extern "C" bool_t * ypproc_domain_nonack_1(domainname *, CLIENT *);
+extern "C" bool_t * ypproc_domain_nonack_1_svc(domainname *, struct svc_req *);
+#define YPOLDPROC_MATCH ((u_long)3)
+extern "C" ypresponse * ypproc_match_1(yprequest *, CLIENT *);
+extern "C" ypresponse * ypproc_match_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_FIRST ((u_long)4)
+extern "C" ypresponse * ypproc_first_1(yprequest *, CLIENT *);
+extern "C" ypresponse * ypproc_first_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_NEXT ((u_long)5)
+extern "C" ypresponse * ypproc_next_1(yprequest *, CLIENT *);
+extern "C" ypresponse * ypproc_next_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_POLL ((u_long)6)
+extern "C" ypresponse * ypproc_poll_1(yprequest *, CLIENT *);
+extern "C" ypresponse * ypproc_poll_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_PUSH ((u_long)7)
+extern "C" void * ypproc_push_1(yprequest *, CLIENT *);
+extern "C" void * ypproc_push_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_PULL ((u_long)8)
+extern "C" void * ypproc_pull_1(yprequest *, CLIENT *);
+extern "C" void * ypproc_pull_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_GET ((u_long)9)
+extern "C" void * ypproc_get_1(yprequest *, CLIENT *);
+extern "C" void * ypproc_get_1_svc(yprequest *, struct svc_req *);
+
+#elif defined(__STDC__)
+#define YPOLDPROC_NULL ((u_long)0)
+extern  void * ypproc_null_1(void *, CLIENT *);
+extern  void * ypproc_null_1_svc(void *, struct svc_req *);
+#define YPOLDPROC_DOMAIN ((u_long)1)
+extern  bool_t * ypproc_domain_1(domainname *, CLIENT *);
+extern  bool_t * ypproc_domain_1_svc(domainname *, struct svc_req *);
+#define YPOLDPROC_DOMAIN_NONACK ((u_long)2)
+extern  bool_t * ypproc_domain_nonack_1(domainname *, CLIENT *);
+extern  bool_t * ypproc_domain_nonack_1_svc(domainname *, struct svc_req *);
+#define YPOLDPROC_MATCH ((u_long)3)
+extern  ypresponse * ypproc_match_1(yprequest *, CLIENT *);
+extern  ypresponse * ypproc_match_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_FIRST ((u_long)4)
+extern  ypresponse * ypproc_first_1(yprequest *, CLIENT *);
+extern  ypresponse * ypproc_first_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_NEXT ((u_long)5)
+extern  ypresponse * ypproc_next_1(yprequest *, CLIENT *);
+extern  ypresponse * ypproc_next_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_POLL ((u_long)6)
+extern  ypresponse * ypproc_poll_1(yprequest *, CLIENT *);
+extern  ypresponse * ypproc_poll_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_PUSH ((u_long)7)
+extern  void * ypproc_push_1(yprequest *, CLIENT *);
+extern  void * ypproc_push_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_PULL ((u_long)8)
+extern  void * ypproc_pull_1(yprequest *, CLIENT *);
+extern  void * ypproc_pull_1_svc(yprequest *, struct svc_req *);
+#define YPOLDPROC_GET ((u_long)9)
+extern  void * ypproc_get_1(yprequest *, CLIENT *);
+extern  void * ypproc_get_1_svc(yprequest *, struct svc_req *);
+
+#else /* Old Style C */ 
+#define YPOLDPROC_NULL ((u_long)0)
+extern  void * ypproc_null_1();
+extern  void * ypproc_null_1_svc();
+#define YPOLDPROC_DOMAIN ((u_long)1)
+extern  bool_t * ypproc_domain_1();
+extern  bool_t * ypproc_domain_1_svc();
+#define YPOLDPROC_DOMAIN_NONACK ((u_long)2)
+extern  bool_t * ypproc_domain_nonack_1();
+extern  bool_t * ypproc_domain_nonack_1_svc();
+#define YPOLDPROC_MATCH ((u_long)3)
+extern  ypresponse * ypproc_match_1();
+extern  ypresponse * ypproc_match_1_svc();
+#define YPOLDPROC_FIRST ((u_long)4)
+extern  ypresponse * ypproc_first_1();
+extern  ypresponse * ypproc_first_1_svc();
+#define YPOLDPROC_NEXT ((u_long)5)
+extern  ypresponse * ypproc_next_1();
+extern  ypresponse * ypproc_next_1_svc();
+#define YPOLDPROC_POLL ((u_long)6)
+extern  ypresponse * ypproc_poll_1();
+extern  ypresponse * ypproc_poll_1_svc();
+#define YPOLDPROC_PUSH ((u_long)7)
+extern  void * ypproc_push_1();
+extern  void * ypproc_push_1_svc();
+#define YPOLDPROC_PULL ((u_long)8)
+extern  void * ypproc_pull_1();
+extern  void * ypproc_pull_1_svc();
+#define YPOLDPROC_GET ((u_long)9)
+extern  void * ypproc_get_1();
+extern  void * ypproc_get_1_svc();
+#endif /* Old Style C */ 
+
+#endif /* !_YPV1_H_RPCGEN */
diff --git a/ypset.tproj/Makefile b/ypset.tproj/Makefile
new file mode 100644
index 0000000..7abe695
--- /dev/null
+++ b/ypset.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ypset
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = ypset.c
+
+OTHERSRCS = Makefile.dist Makefile.preamble
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /usr/sbin
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ypset.tproj/Makefile.dist b/ypset.tproj/Makefile.dist
new file mode 100644
index 0000000..1cb38ca
--- /dev/null
+++ b/ypset.tproj/Makefile.dist
@@ -0,0 +1,7 @@
+#	from: @(#)Makefile	5.8 (Berkeley) 7/28/90
+#	$Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:59:06 wsanchez Exp $
+
+PROG=	ypset
+NOMAN=
+
+.include <bsd.prog.mk>
diff --git a/ypset.tproj/Makefile.preamble b/ypset.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/ypset.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/ypset.tproj/PB.project b/ypset.tproj/PB.project
new file mode 100644
index 0000000..bbc1e0f
--- /dev/null
+++ b/ypset.tproj/PB.project
@@ -0,0 +1,36 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LINKED = (ypset.c); 
+        OTHER_SOURCES = (Makefile.dist, Makefile.preamble); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/sbin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ypset; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/sbin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ypset.tproj/ypset.c b/ypset.tproj/ypset.c
new file mode 100644
index 0000000..cddc148
--- /dev/null
+++ b/ypset.tproj/ypset.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "ypset.c,v 1.3 1993/06/12 00:02:37 deraadt Exp";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+//#include <rpcsvc/yp_prot.h>
+//#include <rpcsvc/ypclnt.h>
+#include <arpa/inet.h>
+
+extern bool_t xdr_domainname();
+
+void
+usage()
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\typset [-h host ] [-d domain] server\n");
+	exit(1);
+}
+
+int
+bind_tohost(sin, dom, server)
+struct sockaddr_in *sin;
+char *dom, *server;
+{
+	ypbind_setdom ypsd;
+	struct timeval tv;
+	struct hostent *hp;
+	CLIENT *client;
+	int sock;
+	u_short port;
+	int r;
+	unsigned long server_addr;
+	
+	if( (port=htons(getrpcport(server, YPPROG, YPPROC_NULL, IPPROTO_UDP))) == 0) {
+		fprintf(stderr, "%s not running ypserv.\n", server);
+		exit(1);
+	}
+
+	tv.tv_sec = 15;
+	tv.tv_usec = 0;
+	sock = RPC_ANYSOCK;
+	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
+	if (client==NULL) {
+		fprintf(stderr, "RPC error: can't create YPBIND client\n");
+		return YP_YPERR;
+	}
+	client->cl_auth = authunix_create_default();
+
+	bzero(&ypsd, sizeof(struct ypbind_setdom));
+
+
+	if( (hp = gethostbyname (server)) != NULL ) {
+		/* is this the most compatible way?? */
+		bcopy(hp->h_addr_list[0], &ypsd.ypsetdom_binding.ypbind_binding_addr, 4);
+	} else if( (long)(server_addr = inet_addr (server)) == -1) {
+		fprintf(stderr, "can't find address for %s\n", server);
+		exit(1);
+	} else
+		bcopy (&server_addr, &ypsd.ypsetdom_binding.ypbind_binding_addr, 4);
+		
+	ypsd.ypsetdom_domain = dom;
+
+	bcopy(&port, ypsd.ypsetdom_binding.ypbind_binding_port, 2);
+	ypsd.ypsetdom_vers = YPVERS;
+	
+	r = clnt_call(client, YPBINDPROC_SETDOM,
+		xdr_ypbind_setdom, &ypsd, xdr_void, NULL, tv);
+	if (r != RPC_SUCCESS)
+	{
+		fprintf(stderr, "Can't ypset for domain %s: %s \n",
+			dom, clnt_sperror(client, "setdomain"));
+		clnt_destroy(client);
+		return YP_YPERR;
+	}
+	clnt_destroy(client);
+	return 0;
+}
+
+int
+main(argc, argv)
+char **argv;
+{
+	struct sockaddr_in sin;
+	struct hostent *hent;
+	extern char *optarg;
+	extern int optind;
+	char *domainname;
+	int c;
+
+	yp_get_default_domain(&domainname);
+
+	bzero(&sin, sizeof sin);
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = htonl(0x7f000001);
+
+	while( (c=getopt(argc, argv, "h:d:")) != -1)
+		switch(c) {
+		case 'd':
+			domainname = optarg;
+			break;
+		case 'h':
+			if( (sin.sin_addr.s_addr=inet_addr(optarg)) == -1) {
+				hent = gethostbyname(optarg);
+				if(hent==NULL) {
+					fprintf(stderr, "ypset: host %s unknown\n",
+						optarg);
+					exit(1);
+				}
+				bcopy(&hent->h_addr_list[0], &sin.sin_addr,
+					sizeof sin.sin_addr);
+			}
+			break;
+		default:
+			usage();
+		}
+
+	if(optind + 1 != argc )
+		usage();
+
+	if (bind_tohost(&sin, domainname, argv[optind]))
+		exit(1);
+	exit(0);
+}
diff --git a/ypwhich.tproj/Makefile b/ypwhich.tproj/Makefile
new file mode 100644
index 0000000..4eb6204
--- /dev/null
+++ b/ypwhich.tproj/Makefile
@@ -0,0 +1,48 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ypwhich
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = ypwhich.c
+
+OTHERSRCS = Makefile.dist Makefile.preamble ypwhich.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ypwhich.tproj/Makefile.dist b/ypwhich.tproj/Makefile.dist
new file mode 100644
index 0000000..9837ebe
--- /dev/null
+++ b/ypwhich.tproj/Makefile.dist
@@ -0,0 +1,6 @@
+#	from: @(#)Makefile	5.8 (Berkeley) 7/28/90
+#	$Id: Makefile.dist,v 1.1.1.1 1999/05/02 03:59:06 wsanchez Exp $
+
+PROG=	ypwhich
+
+.include <bsd.prog.mk>
diff --git a/ypwhich.tproj/Makefile.preamble b/ypwhich.tproj/Makefile.preamble
new file mode 100644
index 0000000..dc05194
--- /dev/null
+++ b/ypwhich.tproj/Makefile.preamble
@@ -0,0 +1,2 @@
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+-include ../Makefile.include
diff --git a/ypwhich.tproj/PB.project b/ypwhich.tproj/PB.project
new file mode 100644
index 0000000..6bbaabd
--- /dev/null
+++ b/ypwhich.tproj/PB.project
@@ -0,0 +1,36 @@
+{
+    FILESTABLE = {
+        C_FILES = (); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LINKED = (ypwhich.c); 
+        OTHER_SOURCES = (Makefile.dist, Makefile.preamble, ypwhich.1); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDDIR = ""; 
+    NEXTSTEP_BUILDTOOL = /bin/make; 
+    NEXTSTEP_COMPILEROPTIONS = ""; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_LINKEROPTIONS = ""; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDDIR = ""; 
+    PDO_UNIX_BUILDTOOL = /bin/make; 
+    PDO_UNIX_COMPILEROPTIONS = ""; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_LINKEROPTIONS = ""; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ypwhich; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDDIR = ""; 
+    WINDOWS_BUILDTOOL = /bin/make; 
+    WINDOWS_COMPILEROPTIONS = ""; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_LINKEROPTIONS = ""; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ypwhich.tproj/ypwhich.1 b/ypwhich.tproj/ypwhich.1
new file mode 100644
index 0000000..5c466f2
--- /dev/null
+++ b/ypwhich.tproj/ypwhich.1
@@ -0,0 +1,94 @@
+.\"
+.\" Copyright (c) 1994 Christopher G. Demetriou
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"      This product includes software developed by Christopher G. Demetriou.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\"	$Id: ypwhich.1,v 1.1.1.1 1999/05/02 03:59:06 wsanchez Exp $
+.\"
+.Dd February 23, 1994
+.Dt YPWHICH 1
+.Os
+.Sh NAME
+.Nm ypwhich
+.Nd return hostname of YP server of map master
+.Sh SYNOPSIS
+.Nm ypwhich
+.Op Fl d Ar domain
+.Oo
+.Op Fl t
+.Fl m Op Ar mname
+|
+.Ar host
+.Oc
+.Nm ypmatch
+.Fl x
+.Sh DESCRIPTION
+.Nm Ypmatch
+tells which
+.Tn YP
+server supplies
+.Tn YP
+services to a client, or which is the master for a map.
+If invoked without arguments, it gives the
+.Tn YP
+server for the local machine.
+If
+.Ar host
+is specified, that machine is queried to find out
+which
+.Tn YP
+server it is using.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl d Ar domain
+Specify a domain other than the default domain.
+.It Fl t
+Inhibit translation of map nicknames
+to their corresponding map names.
+.It Fl m Op Ar mname
+Find the master
+.Tn YP
+server for the named map.  No
+.Ar host
+may be specified with the
+.Fl m
+option.
+.Ar Mname
+can be a map name or nickname.  If
+.Ar mname
+is ommitted,
+.Nm ypwhich
+will produce a list of available maps.
+.It Fl x
+Display the map nickname table.
+.El
+.Sh SEE ALSO
+.Xr ypset 8 ,
+.Xr yp 8
+.Sh AUTHOR
+Theo De Raadt
diff --git a/ypwhich.tproj/ypwhich.c b/ypwhich.tproj/ypwhich.c
new file mode 100644
index 0000000..523e1d0
--- /dev/null
+++ b/ypwhich.tproj/ypwhich.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$Id: ypwhich.c,v 1.1.1.1 1999/05/02 03:59:06 wsanchez Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+//#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern bool_t xdr_domainname();
+
+struct ypalias {
+	char *alias, *name;
+} ypaliases[] = {
+	{ "passwd", "passwd.byname" },
+	{ "group", "group.byname" },
+	{ "networks", "networks.byaddr" },
+	{ "hosts", "hosts.byaddr" },
+	{ "protocols", "protocols.bynumber" },
+	{ "services", "services.byname" },
+	{ "aliases", "mail.aliases" },
+	{ "ethers", "ethers.byname" },
+};
+static int n_aliases = 8;
+
+void
+usage()
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\typwhich [-d domain] [[-t] -m [mname] | host]\n");
+	fprintf(stderr, "\typwhich -x\n");
+	exit(1);
+}
+
+
+/*
+ * Like yp_bind except can query a specific host
+ */
+int
+bind_host(char *dom, struct sockaddr_in *sin)
+{
+	struct hostent *hent = NULL;
+	struct ypbind_resp ypbr;
+	struct timeval tv;
+	CLIENT *client;
+	int sock, r;
+	struct in_addr addr;
+
+	sock = RPC_ANYSOCK;
+	tv.tv_sec = 15;
+	tv.tv_usec = 0;
+	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
+	if (client==NULL)
+	{
+		fprintf(stderr, "can't clntudp_create: %s\n",
+			yperr_string(YPERR_YPBIND));
+		return YPERR_YPBIND;
+	}
+
+	tv.tv_sec = 5;
+	tv.tv_usec = 0;
+	r = clnt_call(client, YPBINDPROC_DOMAIN,
+		xdr_domainname, &dom, xdr_ypbind_resp, &ypbr, tv);
+
+	if (r != RPC_SUCCESS)
+	{
+		fprintf(stderr, "can't clnt_call: %s\n", yperr_string(YPERR_YPBIND));
+		clnt_destroy(client);
+		return YPERR_YPBIND;
+	}
+	else
+	{
+		if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
+		{
+			fprintf(stderr, "can't yp_bind: Reason: %s\n",
+				yperr_string(ypbr.ypbind_status));
+			clnt_destroy(client);
+			return r;
+		}
+	}
+	
+	clnt_destroy(client);
+
+	memmove(&addr, ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr, 4);
+
+	hent = gethostbyaddr((char *)&(addr.s_addr), sizeof(u_long), AF_INET);
+	if (hent != NULL) printf("%s\n", hent->h_name);
+	else printf("%s\n", inet_ntoa(addr));
+	return 0;
+}
+	
+int
+main(int argc, char *argv[])
+{
+	char *domainname, *master, *map;
+	ypmaplist *ypml, *y;
+	extern char *optarg;
+	extern int optind;
+	struct hostent *hent;
+	struct sockaddr_in sin;
+	int notrans, mode, getmap;
+	int c, r, i;
+
+	yp_get_default_domain(&domainname);
+
+	map = NULL;
+	getmap = notrans = mode = 0;
+	while ((c = getopt(argc, argv, "xd:mt")) != -1)
+	{
+		switch(c)
+		{
+			case 'x':
+				for (i = 0; i < n_aliases; i++)
+				{
+					printf("Use \"%s\" for \"%s\"\n",
+						ypaliases[i].alias,
+						ypaliases[i].name);
+				}
+				exit(0);
+
+			case 'd':
+				domainname = optarg;
+				break;
+
+			case 't':
+				notrans++;
+				break;
+
+			case 'm':
+				mode++;
+				break;
+
+			default:
+				usage();
+		}
+	}
+
+	if (mode == 0)
+	{
+		switch(argc-optind)
+		{
+			case 0:
+				bzero(&sin, sizeof sin);
+				sin.sin_family = AF_INET;
+				sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+				if (bind_host(domainname, &sin)) exit(1);
+				break;
+
+			case 1:
+				bzero(&sin, sizeof sin);
+				sin.sin_family = AF_INET;
+				sin.sin_addr.s_addr = inet_addr(argv[optind]);
+				if (sin.sin_addr.s_addr == -1)
+				{
+					hent = gethostbyname(argv[optind]);
+					if (hent == NULL)
+					{
+						fprintf(stderr, "ypwhich: host %s unknown\n",
+							argv[optind]);
+						exit(1);
+					}
+
+					bcopy((char *)hent->h_addr_list[0],
+						(char *)&sin.sin_addr, sizeof sin.sin_addr);
+				}
+
+				if (bind_host(domainname, &sin)) exit(1);
+				break;
+				
+			default:
+				usage();
+		}
+		
+		exit(0);
+	}
+
+	if (argc-optind > 1) usage();
+
+	if (argv[optind])
+	{
+		map = argv[optind];
+		for (i = 0; (!notrans) && (i < n_aliases); i++)
+		{
+			if (!strcmp(map, ypaliases[i].alias)) map = ypaliases[i].name;
+		}
+		
+		r = yp_master(domainname, map, &master);
+		switch(r)
+		{
+			case 0:
+				printf("%s\n", master);
+				free(master);
+				break;
+			case YPERR_YPBIND:
+				fprintf(stderr, "ypwhich: not running ypbind\n");
+				exit(1);
+			default:
+				fprintf(stderr, "Can't find master for map %s. Reason: %s\n",
+					map, yperr_string(r));
+				exit(1);
+			}
+			exit(0);
+		}
+
+		ypml = NULL;
+		r = yp_maplist(domainname, &ypml);
+		switch(r)
+		{
+			case 0:
+				while (ypml != NULL)
+				{
+					r = yp_master(domainname, ypml->map, &master);
+					switch(r)
+					{
+						case 0:
+							printf("%s %s\n", ypml->map, master);
+							free(master);
+							break;
+						default:
+							fprintf(stderr,
+								"YP: can't find the master of %s: Reason: %s\n",
+								ypml->map, yperr_string(r));
+							break;
+					}
+
+					y = ypml;
+					ypml = ypml->next;
+					free(y);
+				}
+				break;
+
+			case YPERR_YPBIND:
+				fprintf(stderr, "ypwhich: not running ypbind\n");
+				exit(1);
+				
+			default:
+				fprintf(stderr, "Can't get map list for domain %s. Reason: %s\n",
+					domainname, yperr_string(r));
+				exit(1);
+		}
+
+	exit(0);
+}
diff --git a/ypxfr.tproj/Makefile b/ypxfr.tproj/Makefile
new file mode 100644
index 0000000..bec2e2c
--- /dev/null
+++ b/ypxfr.tproj/Makefile
@@ -0,0 +1,49 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = ypxfr
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = ypdb.h ypdef.h yplib_host.h yplog.h
+
+CFILES = ypdb.c yplib_host.c yplog.c ypxfr.c ypxfr_xdr.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
+            ypxfr_1perday.sh ypxfr_1perhour.sh ypxfr_2perday.sh ypxfr.8
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/ypxfr.tproj/Makefile.postamble b/ypxfr.tproj/Makefile.postamble
new file mode 100644
index 0000000..509e7f5
--- /dev/null
+++ b/ypxfr.tproj/Makefile.postamble
@@ -0,0 +1,101 @@
+###############################################################################
+#  Makefile.postamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile, which is imported after all other makefiles, to
+#  override attributes for a project's Makefile environment. This allows you  
+#  to take advantage of the environment set up by the other Makefiles. 
+#  You can also define custom rules at the end of this file.
+#
+###############################################################################
+# 
+# These variables are exported by the standard makefiles and can be 
+# used in any customizations you make.  They are *outputs* of
+# the Makefiles and should be used, not set.
+# 
+#  PRODUCTS: products to install.  All of these products will be placed in
+#	 the directory $(DSTROOT)$(INSTALLDIR)
+#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+#  OFILE_DIR: Directory into which .o object files are generated.
+#  DERIVED_SRC_DIR: Directory used for all other derived files
+#
+#  ALL_CFLAGS:  flags to pass when compiling .c files
+#  ALL_MFLAGS:  flags to pass when compiling .m files
+#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
+#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
+#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
+#  ALL_LDFLAGS:  flags to pass when linking object files
+#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
+#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
+#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
+#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
+#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
+#
+#  NAME: name of application, bundle, subproject, palette, etc.
+#  LANGUAGE: langage in which the project is written (default "English")
+#  LOCAL_RESOURCES: localized resources (e.g. nib's, images) of project
+#  GLOBAL_RESOURCES: non-localized resources of project
+#
+#  SRCROOT:  base directory in which to place the new source files
+#  SRCPATH:  relative path from SRCROOT to present subdirectory
+#
+#  INSTALLDIR: Directory the product will be installed into by 'install' target
+#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
+#        to prefix this with DSTROOT when you use it.
+#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
+#	 to prefix this with DSTROOT when you use it.
+#
+#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
+#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
+#	to -g)
+#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
+#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
+#	to -O)
+#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
+#	to -pg -DPROFILE)
+#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
+#	the include path (defaults to -I.)
+#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+#	passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
+#	against the framework will run against the correct version even if
+#	the current version of the framework changes.  You may override this
+#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+#	development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+        # User/group ownership 
+#INSTALL_AS_GROUP = wheel
+        # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =
+        # If set, 'install' chmod's executable to this
+
+
+# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+STRIPFLAGS =
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+#
diff --git a/ypxfr.tproj/Makefile.preamble b/ypxfr.tproj/Makefile.preamble
new file mode 100644
index 0000000..83f25c7
--- /dev/null
+++ b/ypxfr.tproj/Makefile.preamble
@@ -0,0 +1,123 @@
+###############################################################################
+#  Makefile.preamble
+#  Copyright 1997, Apple Computer, Inc.
+#
+#  Use this makefile for configuring the standard application makefiles 
+#  associated with ProjectBuilder. It is included before the main makefile.
+#  In Makefile.preamble you set attributes for a project, so they are available
+#  to the project's makefiles.  In contrast, you typically write additional rules or 
+#  override built-in behavior in the Makefile.postamble.
+#  
+#  Each directory in a project tree (main project plus subprojects) should 
+#  have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+# Before the main makefile is included for this project, you may set:
+#
+#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
+#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
+
+# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
+# inherited by all nested sub-projects, but the LOCAL_ versions of the same
+# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
+# Build Attributes inspector if at all possible.  To override the default flags
+# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
+# variables below are *inputs* to the build process and distinct from the override
+# settings done (less often) in the Makefile.postamble.
+#
+#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
+#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
+#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
+#	flags in OTHER_MFLAGS, etc.
+#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
+#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
+#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
+#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
+#	precompiling header files
+#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
+#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
+#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
+#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
+#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
+
+# These variables provide hooks enabling you to add behavior at almost every 
+# stage of the make:
+#
+#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
+#    AFTER_PREBUILD: targets to build after installing headers for a subproject
+#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
+#    BEFORE_BUILD: targets to make before a build, but after subprojects
+#    AFTER_BUILD: targets to make after a build
+#
+#    BEFORE_INSTALL: targets to build before installing the product
+#    AFTER_INSTALL: targets to build after installing the product
+#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
+#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
+#
+#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
+#         subproject
+#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
+#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
+#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
+#
+#    BEFORE_DEPEND: targets to build before building dependencies for a
+#	  subproject
+#    AFTER_DEPEND: targets to build after building dependencies for a
+#	  subproject
+#
+#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
+#	  updated every time the project is built.  If NO, the dependency
+#	  file is only built when the depend target is invoked.
+
+# Framework-related variables:
+#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the framework's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+
+# Library-related variables:
+#    PUBLIC_HEADER_DIR:  Determines where public exported header files
+#	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    PRIVATE_HEADER_DIR:  Determines where private exported header files
+#  	should be installed.  Do not include $(DSTROOT) in this value --
+#	it is prefixed automatically.
+#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
+#  	whether the libraries produced are statically linked when they
+#	are used or if they are dynamically loadable. <<default?>>
+#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
+#	where to put the library's DLL.  This variable defaults to 
+#	$(INSTALLDIR)/../Executables
+#
+#    INSTALL_AS_USER: owner of the intalled products (default root)
+#    INSTALL_AS_GROUP: group of the installed products (default wheel)
+#    INSTALL_PERMISSION: permissions of the installed product (default o+rX)
+#
+#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
+#  	passed on the command line to recursive invocations of make.  Note that
+#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
+#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
+#	OTHER_RECURSIVE_VARIABLES. 
+
+# Additional headers to export beyond those in the PB.project:
+#    OTHER_PUBLIC_HEADERS
+#    OTHER_PROJECT_HEADERS
+#    OTHER_PRIVATE_HEADERS
+
+# Additional files for the project's product: <<path relative to proj?>>
+#    OTHER_RESOURCES: (non-localized) resources for this project
+#    OTHER_OFILES: relocatables to be linked into this project
+#    OTHER_LIBS: more libraries to link against
+#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
+#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
+#    OTHER_GARBAGE: additional files to be removed by `make clean'
+
+# Set this to YES if you don't want a final libtool call for a library/framework.
+#    BUILD_OFILES_LIST_ONLY
+
+# To include a version string, project source must exist in a directory named 
+# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
+# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+
+# This definition will suppress stripping of debug symbols when an executable
+# is installed.  By default it is YES.
+# STRIP_ON_INSTALL = NO
diff --git a/ypxfr.tproj/PB.project b/ypxfr.tproj/PB.project
new file mode 100644
index 0000000..1371c2f
--- /dev/null
+++ b/ypxfr.tproj/PB.project
@@ -0,0 +1,36 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (ypdb.h, ypdef.h, yplib_host.h, yplog.h); 
+        LIBRARYSEARCH = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (ypdb.c, yplib_host.c, yplog.c, ypxfr.c, ypxfr_xdr.c); 
+        OTHER_SOURCES = (
+            Makefile.preamble, 
+            Makefile, 
+            Makefile.postamble, 
+            ypxfr_1perday.sh, 
+            ypxfr_1perhour.sh, 
+            ypxfr_2perday.sh, 
+            ypxfr.8
+        ); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = ypxfr; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/ypxfr.tproj/ypdb.c b/ypxfr.tproj/ypdb.c
new file mode 100644
index 0000000..c9bd178
--- /dev/null
+++ b/ypxfr.tproj/ypdb.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdb.c,v 1.5 1997/02/09 09:49:36 maja Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * This code is derived from ndbm module of BSD4.4 db (hash) by
+ * Mats O Jansson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ypdb.h"
+
+#ifdef YPDB_PATCH
+extern DBM *__hash_open();
+#else
+extern DBM *__bt_open();
+#endif
+
+/*
+ * Returns:
+ * 	*DBM on success
+ *	 NULL on failure
+ */
+
+extern DBM *
+ypdb_open(file, flags, mode)
+	const char *file;
+	int flags, mode;
+{
+#ifdef YPDB_PATCH
+	HASHINFO info;
+	char path[MAXPATHLEN];
+
+	info.bsize = 4096;
+	info.ffactor = 40;
+	info.nelem = 1;
+	info.cachesize = NULL;
+	info.hash = NULL;
+	info.lorder = 0;
+	snprintf(path, sizeof(path), "%s%s", file, YPDB_SUFFIX);
+	return ((DBM *)__hash_open(path, flags, mode, &info, 0));
+#else
+	BTREEINFO info;
+	char path[MAXPATHLEN];
+	DBM *db;
+
+	info.flags = 0;
+	info.cachesize = 0;
+	info.maxkeypage = 0;
+	info.minkeypage = 0;
+	info.psize = 0;
+	info.compare = NULL;
+	info.prefix = NULL;
+	info.lorder = 0;
+	snprintf(path, sizeof(path), "%s%s", file, YPDB_SUFFIX);
+	db = (DBM *)__bt_open(path, flags, mode, &info, 0);
+	return (db);
+#endif
+}
+
+/*
+ * Returns:
+ * 	*DBM on success
+ *	 NULL on failure
+ */
+
+extern DBM *
+ypdb_open_suf(file, flags, mode)
+	const char *file;
+	int flags, mode;
+{
+#ifdef YPDB_PATCH
+	HASHINFO info;
+
+	info.bsize = 4096;
+	info.ffactor = 40;
+	info.nelem = 1;
+	info.cachesize = NULL;
+	info.hash = NULL;
+	info.lorder = 0;
+	return ((DBM *)__hash_open(file, flags, mode, &info, 0));
+#else
+	BTREEINFO info;
+	DBM *db;
+
+	info.flags = 0;
+	info.cachesize = 0;
+	info.maxkeypage = 0;
+	info.minkeypage = 0;
+	info.psize = 0;
+	info.compare = NULL;
+	info.prefix = NULL;
+	info.lorder = 0;
+	db = (DBM *)__bt_open(file, flags, mode, &info, 0);
+	return (db);
+#endif
+}
+
+extern void
+ypdb_close(db)
+	DBM *db;
+{
+	(void)(db->close)(db);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_fetch(db, key)
+	DBM *db;
+	datum key;
+{
+	datum retval;
+	int status;
+
+	status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
+	if (status) {
+		retval.dptr = NULL;
+		retval.dsize = 0;
+	}
+	return (retval);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_firstkey(db)
+	DBM *db;
+{
+	int status;
+	datum retdata, retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+	if (status)
+		retkey.dptr = NULL;
+	return (retkey);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_nextkey(db)
+	DBM *db;
+{
+	int status;
+	datum retdata, retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+	if (status)
+		retkey.dptr = NULL;
+	return (retkey);
+}
+
+/*
+ * Returns:
+ *	DATUM on success
+ *	NULL on failure
+ */
+
+extern datum
+ypdb_setkey(db, key)
+	DBM *db;
+        datum key;
+{
+	int status;
+	datum retdata;
+#ifdef YPDB_PATCH
+	datum retkey;
+
+	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+	if (status)
+		retkey.dptr = NULL;
+	while ((retkey.dptr != NULL) &&
+	       ((retkey.dsize != key.dsize) ||
+		(strncmp(key.dptr,retkey.dptr,retkey.dsize) != 0))) {
+	  status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+	  if (status)
+	  	retkey.dptr = NULL;
+	};
+	return (retkey);
+#else
+	status = (db->seq)(db, (DBT *)&key, (DBT *)&retdata, R_CURSOR);
+	if (status)
+		key.dptr = NULL;
+	return (key);
+#endif
+}
+
+/*
+ * Returns:
+ *	 0 on success
+ *	<0 failure
+ */
+
+int
+ypdb_delete(db, key)
+	DBM *db;
+	datum key;
+{
+	int status;
+
+	status = (db->del)(db, (DBT *)&key, 0);
+	if (status)
+		return (-1);
+	else
+		return (0);
+}
+
+/*
+ * Returns:
+ *	 0 on success
+ *	<0 failure
+ *	 1 if YPDB_INSERT and entry exists
+ */
+
+int
+ypdb_store(db, key, content, flags)
+	DBM *db;
+	datum key, content;
+	int flags;
+{
+	return ((db->put)(db, (DBT *)&key, (DBT *)&content,
+	    (flags == YPDB_INSERT) ? R_NOOVERWRITE : 0));
+}
+
diff --git a/ypxfr.tproj/ypdb.h b/ypxfr.tproj/ypdb.h
new file mode 100644
index 0000000..9afbad5
--- /dev/null
+++ b/ypxfr.tproj/ypdb.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdb.h,v 1.5 1997/02/09 09:49:37 maja Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * This code is derived from ndbm module of BSD4.4 db (hash) by
+ * Mats O Jansson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPDB_H_
+#define _YPDB_H_
+
+#ifndef _DB_H_
+#include <bsd/db.h>
+#endif
+
+#define YPDB_SUFFIX	".db"
+
+/* Flags to ypdb_store(). */
+#define YPDB_INSERT      0
+#define YPDB_REPLACE     1
+
+#ifndef DATUM
+typedef struct {
+	char	*dptr;
+	int	dsize;
+} datum;
+#define DATUM
+#endif
+
+typedef DB DBM;
+
+__BEGIN_DECLS
+void	 ypdb_close __P((DBM *));
+datum	 ypdb_fetch __P((DBM *, datum));
+datum	 ypdb_firstkey __P((DBM *));
+datum	 ypdb_nextkey __P((DBM *));
+datum	 ypdb_setkey __P((DBM *, datum));
+DBM     *ypdb_open __P((const char *, int, int));
+DBM     *ypdb_open_suf __P((const char *, int, int));
+int	 ypdb_store __P((DBM *, datum, datum, int));
+__END_DECLS
+
+#endif /* !_YPDB_H_ */
diff --git a/ypxfr.tproj/ypdef.h b/ypxfr.tproj/ypdef.h
new file mode 100644
index 0000000..89970d7
--- /dev/null
+++ b/ypxfr.tproj/ypdef.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypdef.h,v 1.6 1997/03/30 20:51:14 maja Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPDEF_H_
+#define _YPDEF_H_
+
+#define YP_DB_PATH "/var/yp"
+#define YP_LAST_KEY        "YP_LAST_MODIFIED"
+#define YP_LAST_LEN	   (sizeof(YP_LAST_KEY)-1)
+#define YP_INPUT_KEY       "YP_INPUT_FILE"
+#define YP_INPUT_LEN	   (sizeof(YP_INPUT_KEY)-1)
+#define YP_OUTPUT_KEY      "YP_OUTPUT_FILE"
+#define YP_OUTPUT_LEN	   (sizeof(YP_OUTPUT_KEY)-1)
+#define YP_MASTER_KEY      "YP_MASTER_NAME"
+#define YP_MASTER_LEN	   (sizeof(YP_MASTER_KEY)-1)
+#define YP_DOMAIN_KEY      "YP_DOMAIN_NAME"
+#define YP_DOMAIN_LEN	   (sizeof(YP_DOMAIN_KEY)-1)
+#define YP_INTERDOMAIN_KEY "YP_INTERDOMAIN"
+#define YP_INTERDOMAIN_LEN (sizeof(YP_INTERDOMAIN_KEY)-1)
+#define YP_SECURE_KEY      "YP_SECURE"
+#define YP_SECURE_LEN      (sizeof(YP_SECURE_KEY)-1)
+
+#define MAX_LAST_LEN 10
+#define MAX_MASTER_LEN 255
+#define YP_HOSTNAME "hosts.byname"
+#define YP_HOSTADDR "hosts.byaddr"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define YPXFR_PROC "/usr/sbin/ypxfr"
+#define YPPUSH_PROC "/usr/sbin/yppush"
+#define YPSERV_PID_PATH "/var/run/ypserv.pid"
+#define YP_SECURENET_FILE "/var/yp/securenet"
+
+#endif /* !_YPDEF_H_ */
diff --git a/ypxfr.tproj/yplib_host.c b/ypxfr.tproj/yplib_host.c
new file mode 100644
index 0000000..70b914b
--- /dev/null
+++ b/ypxfr.tproj/yplib_host.c
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yplib_host.c,v 1.7 1997/06/23 01:11:12 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char *rcsid = "$OpenBSD: yplib_host.c,v 1.7 1997/06/23 01:11:12 deraadt Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+extern bool_t xdr_domainname(), xdr_ypbind_resp();
+extern bool_t xdr_ypreq_key(), xdr_ypresp_val();
+extern bool_t xdr_ypreq_nokey(), xdr_ypresp_key_val();
+extern bool_t xdr_ypresp_all(), xdr_ypresp_all_seq();
+extern bool_t xdr_ypresp_master();
+
+extern int (*ypresp_allfn)();
+extern void *ypresp_data;
+
+int _yplib_host_timeout = 10;
+
+CLIENT *
+yp_bind_host(server,program,version,port,usetcp)
+char *server;
+u_long	program,version;
+u_short port;
+int usetcp;
+{
+	struct sockaddr_in rsrv_sin;
+	int rsrv_sock;
+	struct hostent *h;
+	struct timeval tv;
+	static CLIENT *client;
+
+	memset(&rsrv_sin, 0, sizeof rsrv_sin);
+	rsrv_sin.sin_len = sizeof rsrv_sin;
+	rsrv_sin.sin_family = AF_INET;
+	rsrv_sock = RPC_ANYSOCK;
+	if (port != 0) {
+		rsrv_sin.sin_port = htons(port);
+	}
+
+	if ((*server >= '0') && (*server <= '9')) {
+		if(inet_aton(server,&rsrv_sin.sin_addr) == 0) {
+			fprintf(stderr, "inet_aton: invalid address %s.\n",
+				server);
+	                exit(1);
+		}
+	} else {
+		h = gethostbyname(server);
+		if(h == NULL) {
+			fprintf(stderr, "gethostbyname: unknown host %s.\n",
+				server);
+	                exit(1);
+		}
+		rsrv_sin.sin_addr.s_addr = *(u_int32_t *)h->h_addr;
+	}
+
+	tv.tv_sec = 10;
+	tv.tv_usec = 0;
+
+	if (usetcp) {
+		client = clnttcp_create(&rsrv_sin, program, version,
+					&rsrv_sock, 0, 0);
+	} else {
+		client = clntudp_create(&rsrv_sin, program, version, tv,
+					&rsrv_sock);
+	}
+
+	if (client == NULL) {
+		fprintf(stderr, "clntudp_create: no contact with host %s.\n",
+			server);
+	        exit(1);
+	}
+
+	return(client);
+	
+}
+
+CLIENT *
+yp_bind_local(program,version)
+u_long	program,version;
+{
+	struct sockaddr_in rsrv_sin;
+	int rsrv_sock;
+	struct timeval tv;
+	static CLIENT *client;
+
+	memset(&rsrv_sin, 0, sizeof rsrv_sin);
+	rsrv_sin.sin_len = sizeof rsrv_sin;
+	rsrv_sin.sin_family = AF_INET;
+	rsrv_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+	rsrv_sock = RPC_ANYSOCK;
+
+	tv.tv_sec = 10;
+	tv.tv_usec = 0;
+
+	client = clntudp_create(&rsrv_sin, program, version, tv, &rsrv_sock);
+	if (client == NULL) {
+		fprintf(stderr,"clntudp_create: no contact with localhost.\n");
+	        exit(1);
+	}
+
+	return(client);
+	
+}
+
+int
+yp_match_host(client, indomain, inmap, inkey, inkeylen, outval, outvallen)
+CLIENT *client;
+char *indomain;
+char *inmap;
+const char *inkey;
+int inkeylen;
+char **outval;
+int *outvallen;
+{
+	struct ypresp_val yprv;
+	struct timeval tv;
+	struct ypreq_key yprk;
+	int r;
+
+	*outval = NULL;
+	*outvallen = 0;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprk.domain = indomain;
+	yprk.map = inmap;
+	yprk.key.keydat_val = (char *)inkey;
+	yprk.key.keydat_len = inkeylen;
+
+	memset(&yprv, 0, sizeof yprv);
+
+	r = clnt_call(client, YPPROC_MATCH,
+		xdr_ypreq_key, &yprk, xdr_ypresp_val, &yprv, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_match_host: clnt_call");
+	}
+	if( !(r=ypprot_err(yprv.stat)) ) {
+		*outvallen = yprv.val.valdat_len;
+		*outval = (char *)malloc(*outvallen+1);
+		memcpy(*outval, yprv.val.valdat_val, *outvallen);
+		(*outval)[*outvallen] = '\0';
+	}
+	xdr_free(xdr_ypresp_val, (char *)&yprv);
+	return r;
+}
+
+int
+yp_first_host(client, indomain, inmap, outkey, outkeylen, outval, outvallen)
+CLIENT *client;
+char *indomain;
+char *inmap;
+char **outkey;
+int *outkeylen;
+char **outval;
+int *outvallen;
+{
+	struct ypresp_key_val yprkv;
+	struct ypreq_nokey yprnk;
+	struct timeval tv;
+	int r;
+
+	*outkey = *outval = NULL;
+	*outkeylen = *outvallen = 0;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprnk.domain = indomain;
+	yprnk.map = inmap;
+	memset(&yprkv, 0, sizeof yprkv);
+
+	r = clnt_call(client, YPPROC_FIRST,
+		xdr_ypreq_nokey, &yprnk, xdr_ypresp_key_val, &yprkv, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_first_host: clnt_call");
+	}
+	if( !(r=ypprot_err(yprkv.stat)) ) {
+		*outkeylen = yprkv.key.keydat_len;
+		*outkey = (char *)malloc(*outkeylen+1);
+		memcpy(*outkey, yprkv.key.keydat_val, *outkeylen);
+		(*outkey)[*outkeylen] = '\0';
+		*outvallen = yprkv.val.valdat_len;
+		*outval = (char *)malloc(*outvallen+1);
+		memcpy(*outval, yprkv.val.valdat_val, *outvallen);
+		(*outval)[*outvallen] = '\0';
+	}
+	xdr_free(xdr_ypresp_key_val, (char *)&yprkv);
+	return r;
+}
+
+int
+yp_next_host(client, indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen)
+CLIENT *client;
+char *indomain;
+char *inmap;
+char *inkey;
+int inkeylen;
+char **outkey;
+int *outkeylen;
+char **outval;
+int *outvallen;
+{
+	struct ypresp_key_val yprkv;
+	struct ypreq_key yprk;
+	struct timeval tv;
+	int r;
+
+	*outkey = *outval = NULL;
+	*outkeylen = *outvallen = 0;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprk.domain = indomain;
+	yprk.map = inmap;
+	yprk.key.keydat_val = inkey;
+	yprk.key.keydat_len = inkeylen;
+	memset(&yprkv, 0, sizeof yprkv);
+
+	r = clnt_call(client, YPPROC_NEXT,
+		xdr_ypreq_key, &yprk, xdr_ypresp_key_val, &yprkv, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_next_host: clnt_call");
+	}
+	if( !(r=ypprot_err(yprkv.stat)) ) {
+		*outkeylen = yprkv.key.keydat_len;
+		*outkey = (char *)malloc(*outkeylen+1);
+		memcpy(*outkey, yprkv.key.keydat_val, *outkeylen);
+		(*outkey)[*outkeylen] = '\0';
+		*outvallen = yprkv.val.valdat_len;
+		*outval = (char *)malloc(*outvallen+1);
+		memcpy(*outval, yprkv.val.valdat_val, *outvallen);
+		(*outval)[*outvallen] = '\0';
+	}
+	xdr_free(xdr_ypresp_key_val, (char *)&yprkv);
+	return r;
+}
+
+int
+yp_all_host(client, indomain, inmap, incallback)
+CLIENT *client;
+char *indomain;
+char *inmap;
+struct ypall_callback *incallback;
+{
+	struct ypreq_nokey yprnk;
+	struct timeval tv;
+	u_long status;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprnk.domain = indomain;
+	yprnk.map = inmap;
+	ypresp_allfn = incallback->foreach;
+	ypresp_data = (void *)incallback->data;
+
+	(void) clnt_call(client, YPPROC_ALL,
+		xdr_ypreq_nokey, &yprnk, xdr_ypresp_all_seq, &status, tv);
+	xdr_free(xdr_ypresp_all_seq, (char *)&status);	/* not really needed... */
+
+	if(status != YP_FALSE)
+		return ypprot_err(status);
+	return 0;
+}
+
+int
+yp_order_host(client, indomain, inmap, outorder)
+CLIENT *client;
+char *indomain;
+char *inmap;
+u_int32_t *outorder;
+{
+	struct ypresp_order ypro;
+	struct ypreq_nokey yprnk;
+	struct timeval tv;
+	int r;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprnk.domain = indomain;
+	yprnk.map = inmap;
+
+	memset(&ypro, 0, sizeof ypro);
+
+	r = clnt_call(client, YPPROC_ORDER,
+		xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_order_host: clnt_call");
+	}
+
+	*outorder = ypro.ordernum;
+	xdr_free(xdr_ypresp_order, (char *)&ypro);
+	return ypprot_err(ypro.stat);
+}
+
+int
+yp_master_host(client, indomain, inmap, outname)
+CLIENT *client;
+char *indomain;
+char *inmap;
+char **outname;
+{
+	struct ypresp_master yprm;
+	struct ypreq_nokey yprnk;
+	struct timeval tv;
+	int r;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	yprnk.domain = indomain;
+	yprnk.map = inmap;
+
+	memset(&yprm, 0, sizeof yprm);
+
+	r = clnt_call(client, YPPROC_MASTER,
+		xdr_ypreq_nokey, &yprnk, xdr_ypresp_master, &yprm, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_master: clnt_call");
+	}
+	if( !(r=ypprot_err(yprm.stat)) ) {
+		*outname = (char *)strdup(yprm.peer);
+	}
+	xdr_free(xdr_ypresp_master, (char *)&yprm);
+	return r;
+}
+
+int
+yp_maplist_host(client, indomain, outmaplist)
+CLIENT *client;
+char *indomain;
+struct ypmaplist **outmaplist;
+{
+	struct ypresp_maplist ypml;
+	struct timeval tv;
+	int r;
+
+	tv.tv_sec = _yplib_host_timeout;
+	tv.tv_usec = 0;
+
+	memset(&ypml, 0, sizeof ypml);
+
+	r = clnt_call(client, YPPROC_MAPLIST,
+		xdr_domainname, &indomain, xdr_ypresp_maplist, &ypml, tv);
+	if (r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_maplist: clnt_call");
+	}
+	*outmaplist = ypml.maps;
+	/* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/
+	return ypprot_err(ypml.stat);
+}
+
diff --git a/ypxfr.tproj/yplib_host.h b/ypxfr.tproj/yplib_host.h
new file mode 100644
index 0000000..038fb68
--- /dev/null
+++ b/ypxfr.tproj/yplib_host.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yplib_host.h,v 1.4 1997/05/01 22:14:45 niklas Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPLIB_HOST_H_
+#define _YPLIB_HOST_H_
+
+int	yp_match_host 	__P((CLIENT *client, char *indomain, char *inmap,
+			    const char *inkey, int inkeylen, char **outval,
+			    int *outvallen));
+int	yp_first_host	__P((CLIENT *client, char *indomain, char *inmap,
+			    char **outkey, int *outkeylen, char **outval,
+			    int *outvallen));
+int	yp_next_host	__P((CLIENT *client, char *indomain, char *inmap,
+			    char *inkey, int inkeylen, char **outkey,
+			    int *outkeylen, char **outval, int *outvallen));
+int	yp_master_host	__P((CLIENT *client,
+			    char *indomain, char *inmap, char **outname));
+int	yp_order_host	__P((CLIENT *client,
+			    char *indomain, char *inmap, u_int32_t *outorder));
+int	yp_all_host	__P((CLIENT *client, char *indomain, char *inmap,
+			    struct ypall_callback *incallback));
+int	yp_maplist_host	__P((CLIENT *client, char *indomain,
+			    struct ypmaplist **outmaplist));
+CLIENT *yp_bind_local	__P((u_long program, u_long version));
+CLIENT *yp_bind_host	__P((char *server, u_long program, u_long version,
+			    u_short port, int usetcp));
+
+#endif /* _YPLIB_HOST_H_ */
+
diff --git a/ypxfr.tproj/yplog.c b/ypxfr.tproj/yplog.c
new file mode 100644
index 0000000..3460c9a
--- /dev/null
+++ b/ypxfr.tproj/yplog.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yplog.c,v 1.5 1997/08/09 22:44:04 maja Exp $ */
+
+/*
+ * Copyright (c) 1996 Charles D. Cranor
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Charles D. Cranor.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * yplog.c: replacement yplog routines for 
+ * Mats O Jansson's ypserv program, as added by
+ * Chuck Cranor.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "yplog.h"
+
+static FILE	*logfp = NULL;		/* the log file */
+
+/*
+ * yplog(): like a printf, but to the log file.   does the flush
+ * and data for you.
+ */
+
+void
+#ifdef __STDC__
+yplog(const char *fmt, ...)
+#else
+yplog(fmt, va_alist)
+	char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+#ifdef __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	vyplog(fmt, ap);
+	va_end(ap);
+}
+
+/*
+ * vyplog() support routine for yplog()
+ */
+
+void
+vyplog(fmt, ap)
+	register const char *fmt;
+	va_list ap;
+{
+        time_t t;
+
+	if (logfp == NULL)
+		return;
+	(void)time(&t);
+	fprintf(logfp,"%.15s ", ctime(&t) + 4);
+	vfprintf(logfp, fmt, ap);
+	fprintf(logfp,"\n");
+	fflush(logfp);
+}
+
+/*
+ * open log
+ */
+
+void
+ypopenlog()
+{
+	static char logfn[] = "/var/yp/ypserv.log";
+
+	if (access(logfn, W_OK) == -1)
+		return;
+	logfp = fopen("/var/yp/ypserv.log", "a");
+	if (logfp == NULL)
+		return;
+	yplog("yplog opened");
+}
+
+/*
+ * close log
+ */
+
+void
+ypcloselog()
+{
+	if (logfp) {
+		yplog("yplog closed");
+		fclose(logfp);
+		logfp = NULL;
+	}
+}
diff --git a/ypxfr.tproj/yplog.h b/ypxfr.tproj/yplog.h
new file mode 100644
index 0000000..dd9d6fb
--- /dev/null
+++ b/ypxfr.tproj/yplog.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yplog.h,v 1.3 1996/05/30 09:53:04 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _YPLOG_H_
+#define _YPLOG_H_
+
+__BEGIN_DECLS
+void    yplog __P((const char *, ...));
+void    vyplog __P((const char *, _BSD_VA_LIST_));
+void	ypopenlog __P((void));
+void	ypcloselog __P((void));
+__END_DECLS
+
+#endif /* !_YPLOG_H_ */
diff --git a/ypxfr.tproj/ypxfr.8 b/ypxfr.tproj/ypxfr.8
new file mode 100644
index 0000000..5a78dad
--- /dev/null
+++ b/ypxfr.tproj/ypxfr.8
@@ -0,0 +1,92 @@
+.\"	$OpenBSD: ypxfr.8,v 1.5 1997/04/20 10:08:35 maja Exp $
+.\" Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by Mats O Jansson
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	$OpenBSD: ypxfr.8,v 1.5 1997/04/20 10:08:35 maja Exp $
+.\"
+.Dd August 18, 1994
+.Dt YPXFR 8
+.Os
+.Sh NAME
+.Nm ypxfr
+.Nd get a YP map from YP server
+.Sh SYNOPSIS
+.Nm ypxfr
+.Op Fl bcf
+.Op Fl d Ar domain
+.Op Fl h Ar host
+.Op Fl s Ar domain
+.Op Fl C Ar tid prog ipadd port
+.Ar mapname
+.Sh DESCRIPTION
+.Nm ypxfr 
+is the utiliy in YP that transfers maps to the local host.
+.Pp
+Since the YP master transfers a map when it has changed, an YP slave should
+check for missed maps regulary. This can be done via an entry in
+.Xr crontab 5 .
+The scripts
+.Ar ypxfr_1perhour , ypxfr_2perday
+and
+.Ar ypxfr_1perday
+could be used for that.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl b
+Preserve the entry in the database informing a YP server to use
+DNS to get information about unknown hosts. This option will only have
+effect on the two maps hosts.byname and hosts.byaddr.
+.It Fl c
+Don't send a "Clear current map" to local ypserv process. Useful if ypserv
+isn't running localy to avoid timeout message. 
+.It Fl f 
+Force map transfer, even if version of master is older than local copy.
+.It Fl d Ar domain
+Don't use default domain, use the specifiyed domain.
+.It Fl h Ar host
+Get map from host insteed of the maps master host.
+.It Fl s Ar domain
+Specify a source domain other than the target domain.
+.It Fl C Ar tid prog ipadd port
+This option is only used by ypserv. This is to open communication with
+an yppush on another host.
+.El
+.Sh FILES
+.Bl -tag -width /usr/sbin/ypxfr_1perhour -compact
+.It Pa /usr/sbin/ypxfr_1perhour
+.It Pa /usr/sbin/ypxfr_2perday
+.It Pa /usr/sbin/ypxfr_1perday
+.El
+.Sh SEE ALSO
+.Xr yp 8 ,
+.Xr yppush 8 ,
+.Xr ypserv 8 
+.Sh AUTHOR
+Mats O Jansson <moj@stacken.kth.se>
diff --git a/ypxfr.tproj/ypxfr.c b/ypxfr.tproj/ypxfr.c
new file mode 100644
index 0000000..faa88bf
--- /dev/null
+++ b/ypxfr.tproj/ypxfr.c
@@ -0,0 +1,668 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypxfr.c,v 1.22 1997/07/30 12:07:02 maja Exp $ */
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: ypxfr.c,v 1.22 1997/07/30 12:07:02 maja Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+#include "yplib_host.h"
+#include "yplog.h"
+#include "ypdb.h"
+#include "ypdef.h"
+
+extern char *__progname;		/* from crt0.o */
+DBM	*db;
+
+extern bool_t xdr_ypresp_all_seq();
+
+extern int (*ypresp_allfn)();
+extern void *ypresp_data;
+
+static int
+ypxfr_foreach(status,keystr,keylen,valstr,vallen,data)
+int status,keylen,vallen;
+char *keystr,*valstr,*data;
+{
+	datum	key,val;
+
+	if (status == YP_NOMORE)
+		return(0);
+
+	keystr[keylen] = '\0';
+	valstr[vallen] = '\0';
+
+	key.dptr = keystr;
+	key.dsize = strlen(keystr);
+
+	val.dptr = valstr;
+	val.dsize = strlen(valstr);
+	
+	ypdb_store(db, key, val, YPDB_INSERT);
+
+	return 0;
+}
+
+int
+get_local_ordernum(domain, map, lordernum)
+char *domain;
+char *map;
+u_int32_t *lordernum;
+{
+	char map_path[MAXPATHLEN];
+	char order_key[] = YP_LAST_KEY;
+	char order[MAX_LAST_LEN+1];
+	struct stat finfo;
+	DBM *db;
+	datum k,v;
+	int status;
+
+	/* This routine returns YPPUSH_SUCC or YPPUSH_NODOM */
+	
+	status = YPPUSH_SUCC;
+	
+	snprintf(map_path, sizeof map_path, "%s/%s", YP_DB_PATH, domain);
+	if (!((stat(map_path, &finfo) == 0) &&
+	      ((finfo.st_mode & S_IFMT) == S_IFDIR))) {
+		fprintf(stderr, "%s: domain %s not found locally\n",
+		    __progname, domain);
+		status = YPPUSH_NODOM;
+	}
+
+	if(status > 0) {
+		snprintf(map_path, sizeof map_path, "%s/%s/%s%s",
+		    YP_DB_PATH, domain, map, YPDB_SUFFIX);
+		if(!(stat(map_path, &finfo) == 0)) {
+			status = YPPUSH_NOMAP;
+		}
+	}
+	
+	if(status > 0) {
+		snprintf(map_path, sizeof map_path, "%s/%s/%s",
+		    YP_DB_PATH, domain, map);
+		db = ypdb_open(map_path, O_RDONLY, 0444);
+		if(db == NULL) {
+			status = YPPUSH_DBM;
+		}
+		
+	}
+		
+	if(status > 0) {
+		k.dptr = (char *)&order_key;
+		k.dsize = YP_LAST_LEN;
+
+		v = ypdb_fetch(db,k);
+		ypdb_close(db);
+		
+		if (v.dptr == NULL) {
+			*lordernum = 0;
+		} else {
+	        	strncpy(order, v.dptr, sizeof order-1);
+			order[sizeof order-1] = '\0';
+			*lordernum = (u_int32_t)atol(order);
+		}
+	}
+
+	if((status == YPPUSH_NOMAP) || (status == YPPUSH_DBM)) {
+		*lordernum = 0;
+		status = YPPUSH_SUCC;
+	}
+
+	return(status);
+
+}
+
+int
+get_remote_ordernum(client, domain, map, lordernum, rordernum)
+CLIENT *client;
+char *domain;
+char *map;
+u_int32_t lordernum;
+u_int32_t *rordernum;
+{
+	int status;
+
+	status = yp_order_host(client, domain, map, rordernum);
+
+	if (status == 0) {
+		if(*rordernum <= lordernum) {
+			status = YPPUSH_AGE;
+		} else {
+			status = YPPUSH_SUCC;
+		}
+	} 
+
+	return status;
+}
+
+void
+get_map(client,domain,map,incallback)
+CLIENT *client;
+char *domain;
+char *map;
+struct ypall_callback *incallback;
+{
+	(void)yp_all_host(client, domain, map, incallback);
+		
+}
+
+DBM *
+create_db(domain,map,temp_map)
+char *domain;
+char *map;
+char *temp_map;
+{
+	return ypdb_open_suf(temp_map, O_RDWR, 0444);
+}
+
+int
+install_db(domain,map,temp_map)
+char *domain;
+char *map;
+char *temp_map;
+{
+	char	db_name[MAXPATHLEN];
+
+	snprintf(db_name, sizeof db_name, "%s/%s/%s%s",
+	    YP_DB_PATH, domain, map, YPDB_SUFFIX);
+	rename(temp_map, db_name);
+
+	return YPPUSH_SUCC;
+}
+
+int
+add_order(db, ordernum)
+DBM *db;
+u_int32_t ordernum;
+{
+	char	datestr[11];
+	datum	key,val;
+	char	keystr[] = YP_LAST_KEY;
+	int	status;
+
+	sprintf(datestr, "%010u", ordernum);
+
+	key.dptr = keystr;
+	key.dsize = strlen(keystr);
+	
+	val.dptr = datestr;
+	val.dsize = strlen(datestr);
+	
+	status = ypdb_store(db, key, val, YPDB_INSERT);
+	if(status >= 0) {
+		status = YPPUSH_SUCC;
+	} else {
+		status = YPPUSH_DBM;
+	}
+	return(status);
+}
+
+int
+add_master(client, domain, map, db)
+CLIENT *client;
+char *domain;
+char *map;
+DBM *db;
+{
+	char	keystr[] = YP_MASTER_KEY;
+	char	*master;
+	int	status;
+	datum	key,val;
+
+	master = NULL;
+
+	/* Get MASTER */
+
+	status = yp_master_host(client, domain, map, &master);
+	
+	if(master != NULL) {
+	  key.dptr = keystr;
+	  key.dsize = strlen(keystr);
+	  
+	  val.dptr = master;
+	  val.dsize = strlen(master);
+	
+	  status = ypdb_store(db, key, val, YPDB_INSERT);
+	  if(status >= 0) {
+	  	status = YPPUSH_SUCC;
+	  } else {
+	  	status = YPPUSH_DBM;
+	  }
+	}
+
+	return status;
+}
+
+int
+add_interdomain(client, domain, map, db)
+CLIENT *client;
+char *domain;
+char *map;
+DBM *db;
+{
+	char	keystr[] = YP_INTERDOMAIN_KEY;
+	char	*value;
+	int	vallen;
+	int	status;
+	datum	k,v;
+
+	/* Get INTERDOMAIN */
+
+	k.dptr = keystr;
+	k.dsize = strlen(keystr);
+
+	status = yp_match_host(client, domain, map,
+			       k.dptr, k.dsize, &value, &vallen);
+	
+	if(status == 0 && value) {
+		v.dptr = value;
+		v.dsize = vallen;
+		
+		if(v.dptr != NULL) {
+			status = ypdb_store(db,k,v,YPDB_INSERT);
+			if(status >= 0) {
+				status = YPPUSH_SUCC;
+			} else {
+				status = YPPUSH_DBM;
+			}
+		}
+	}
+
+	return 1;
+}
+
+int
+add_secure(client, domain, map, db)
+CLIENT *client;
+char *domain;
+char *map;
+DBM *db;
+{
+	char	keystr[] = YP_SECURE_KEY;
+	char	*value;
+	int	vallen;
+	int	status;
+	datum	k,v;
+
+	/* Get SECURE */
+
+	k.dptr = keystr;
+	k.dsize = strlen(keystr);
+
+	status = yp_match_host(client, domain, map,
+			       k.dptr, k.dsize, &value, &vallen);
+	
+	if(status > 0) {
+		v.dptr = value;
+		v.dsize = vallen;
+		
+		if(v.dptr != NULL) {
+			status = ypdb_store(db,k,v,YPDB_INSERT);
+			if(status >= 0) {
+				status = YPPUSH_SUCC;
+			} else {
+				status = YPPUSH_DBM;
+			}
+		}
+	}
+
+	return status;
+
+}
+
+int
+send_clear(client)
+CLIENT *client;
+{
+	struct	timeval tv;
+	int	r;
+	int	status;
+
+	status = YPPUSH_SUCC;
+
+	tv.tv_sec = 10;
+	tv.tv_usec = 0;
+
+	/* Send CLEAR */
+
+	r = clnt_call(client, YPPROC_CLEAR,
+		      xdr_void, 0, xdr_void, 0, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yp_clear: clnt_call");
+	}
+
+	return status;
+
+}
+
+int
+send_reply(client,status,tid)
+CLIENT *client;
+u_long	status;
+u_long  tid;
+{
+	struct	timeval tv;
+	struct	ypresp_xfr resp;
+	int	r;
+
+	tv.tv_sec = 10;
+	tv.tv_usec = 0;
+
+	resp.transid = tid;
+	resp.xfrstat = status;
+
+	/* Send CLEAR */
+
+	r = clnt_call(client, 1,
+		      xdr_ypresp_xfr, &resp, xdr_void, 0, tv);
+	if(r != RPC_SUCCESS) {
+		clnt_perror(client, "yppushresp_xdr: clnt_call");
+	}
+
+	return status;
+
+}
+
+int
+main (argc,argv)
+int argc;
+char *argv[];
+{
+	int	 usage = 0;
+	int	 cflag = 0;
+	int	 fflag = 0;
+	int	 Cflag = 0;
+	int	 ch;
+	extern	 char *optarg;
+	char	 *domain;
+	char	 *host = NULL;
+	char	 *srcdomain = NULL;
+	char	 *tid = NULL;
+	char	 *prog = NULL;
+	char	 *ipadd = NULL;
+	char	 *port = NULL;
+	char	 *map = NULL;
+	u_int32_t ordernum, new_ordernum;
+	struct	 ypall_callback callback;
+	CLIENT   *client;
+	int	 status,xfr_status;
+	int	 srvport;
+	
+	status = YPPUSH_SUCC;
+	client = NULL;
+
+	yp_get_default_domain(&domain);
+
+	while ((ch = getopt(argc, argv, "cd:fh:s:C:")) != -1)
+	  switch (ch) {
+	  case 'c':
+	    cflag++;
+	    break;
+	  case 'd':
+	    if (strchr(optarg, '/'))	/* Ha ha, we are not listening */
+		break;
+	    domain = optarg;
+	    break;
+	  case 'f':
+	    fflag++;
+	    break;
+	  case 'h':
+	    host = optarg;
+	    break;
+	  case 's':
+	    if (strchr(optarg, '/'))	/* Ha ha, we are not listening */
+		break;
+	    srcdomain = optarg;
+	    break;
+	  case 'C':
+	    if (optind + 3 >= argc) {
+		usage++;
+		optind = argc;
+		break;
+	    }
+	    Cflag++;
+	    tid = optarg;
+	    prog = argv[optind++];
+	    ipadd = argv[optind++];
+	    port = argv[optind++];
+	    break;
+	  default:
+	    usage++;
+	    break;
+	  }
+
+	if(optind + 1 != argc) {
+	  usage++;
+	} else {
+	  map = argv[optind];
+	}
+
+	if (usage) {
+		status = YPPUSH_BADARGS;
+		fprintf(stderr, "usage: %s %s %s\n",
+		    "[-cf] [-d domain] [-h host] [-s domain]",
+		    "[-C tid prog ipadd port] mapname\n",
+		    __progname);
+	}
+
+	if (status > 0) {
+		ypopenlog();
+
+		yplog("ypxfr: Arguments:");
+		yplog("YP clear to local: %s", (cflag) ? "no" : "yes");
+		yplog("   Force transfer: %s", (fflag) ? "yes" : "no");
+		yplog("           domain: %s", domain); 
+		yplog("             host: %s", host);
+		yplog("    source domain: %s", srcdomain);
+		yplog("          transid: %s", tid);
+		yplog("             prog: %s", prog);
+		yplog("             port: %s", port);
+		yplog("            ipadd: %s", ipadd);
+		yplog("              map: %s", map);
+
+		if(fflag != 0) {
+			ordernum = 0;
+		} else {
+			status = get_local_ordernum(domain, map, &ordernum);
+		}
+	}
+
+	if (status > 0) {
+
+	        yplog("Get Master");
+
+		if (host == NULL) {
+			if (srcdomain == NULL) {
+				status = yp_master(domain,map,&host);
+		        } else {
+				status = yp_master(srcdomain,map,&host);
+			}
+			if(status == 0) {
+				status = YPPUSH_SUCC;
+			} else {
+				status = -status;
+			}
+		}
+	};
+
+	/* XXX this is raceable if portmap has holes! */
+	if (status > 0) {
+		
+	        yplog("Check for reserved port on host: %s", host); 
+
+		srvport = getrpcport(host,YPPROG,YPVERS,IPPROTO_TCP);
+		if (srvport >= IPPORT_RESERVED)
+			status = YPPUSH_REFUSED;
+		
+	}
+
+	if (status > 0) {
+	  	
+	        yplog("Connect host: %s", host); 
+
+		client = yp_bind_host(host,YPPROG,YPVERS,0,1);
+
+		status = get_remote_ordernum(client, domain, map,
+					     ordernum, &new_ordernum);
+		
+	}
+
+	if (status == YPPUSH_SUCC) {
+		char	tmpmapname[MAXPATHLEN];
+		int	fd;
+
+		/* Create temporary db */
+		snprintf(tmpmapname, sizeof tmpmapname,
+		    "%s/%s/ypdbXXXXXXXXXX", YP_DB_PATH, domain);
+		fd = mkstemp(tmpmapname);
+		if (fd == -1)
+			status = YPPUSH_DBM;
+		else
+			close(fd);
+
+		if (status > 0) {
+			db = create_db(domain,map,tmpmapname);
+			if(db == NULL)
+				status = YPPUSH_DBM;
+		}
+
+	  	/* Add ORDER */
+		if(status > 0) {
+			status = add_order(db, new_ordernum);
+		}
+		
+		/* Add MASTER */
+		if(status > 0) {
+			status = add_master(client,domain,map,db);
+		}
+		
+	        /* Add INTERDOMAIN */
+		if(status > 0) {
+			status = add_interdomain(client,domain,map,db);
+		}
+		
+	        /* Add SECURE */
+		if(status > 0) {
+			status = add_secure(client,domain,map,db);
+		}
+		
+		if(status > 0) {
+			callback.foreach=ypxfr_foreach;
+			get_map(client,domain,map,&callback);
+		}
+		
+		/* Close db */
+		if(db != NULL) {
+			ypdb_close(db);
+		}
+
+		/* Rename db */
+		if(status > 0) {
+			status = install_db(domain,map,tmpmapname);
+		} else {
+			unlink(tmpmapname);
+			status = YPPUSH_SUCC;
+		}
+		
+	}
+	
+	xfr_status = status;
+
+	if(client != NULL) {
+		clnt_destroy(client);
+	}
+
+	/* YP_CLEAR */
+
+	if(!cflag) {
+		client = yp_bind_local(YPPROG,YPVERS);
+		status = send_clear(client);
+		clnt_destroy(client);
+	}
+
+	if(Cflag > 0) {
+		/* Send Response */
+		client = yp_bind_host(ipadd,
+				      atoi(prog),
+				      1,
+				      atoi(port),
+				      0);
+		status = send_reply(client,xfr_status,atoi(tid));
+		clnt_destroy(client);
+	}
+
+	return(0);
+
+}
+
diff --git a/ypxfr.tproj/ypxfr_1perday.sh b/ypxfr.tproj/ypxfr_1perday.sh
new file mode 100755
index 0000000..dab042c
--- /dev/null
+++ b/ypxfr.tproj/ypxfr_1perday.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+#	$OpenBSD: ypxfr_1perday.sh,v 1.1 1997/04/20 10:08:36 maja Exp $
+#
+# ypxfr_1perday.sh - YP maps to be updated daily
+#
+
+/usr/sbin/ypxfr group.byname
+/usr/sbin/ypxfr group.bygid 
+/usr/sbin/ypxfr protocols.byname
+/usr/sbin/ypxfr protocols.bynumber
+/usr/sbin/ypxfr networks.byname
+/usr/sbin/ypxfr networks.byaddr
+/usr/sbin/ypxfr services.byname
+/usr/sbin/ypxfr rpc.bynumber
+/usr/sbin/ypxfr rpc.byname
diff --git a/ypxfr.tproj/ypxfr_1perhour.sh b/ypxfr.tproj/ypxfr_1perhour.sh
new file mode 100755
index 0000000..82f43a2
--- /dev/null
+++ b/ypxfr.tproj/ypxfr_1perhour.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+#	$OpenBSD: ypxfr_1perhour.sh,v 1.1 1997/04/20 10:08:37 maja Exp $
+#
+# ypxfr_1perhour.sh - YP maps to be updated every hour
+#
+
+/usr/sbin/ypxfr passwd.byname
+/usr/sbin/ypxfr passwd.byuid 
+/usr/sbin/ypxfr master.passwd.byname
+/usr/sbin/ypxfr master.passwd.byuid 
+/usr/sbin/ypxfr netid.byname
diff --git a/ypxfr.tproj/ypxfr_2perday.sh b/ypxfr.tproj/ypxfr_2perday.sh
new file mode 100755
index 0000000..0905270
--- /dev/null
+++ b/ypxfr.tproj/ypxfr_2perday.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+#	$OpenBSD: ypxfr_2perday.sh,v 1.1 1997/04/20 10:08:38 maja Exp $
+#
+# ypxfr_2perday.sh - YP maps to be updated twice a day
+#
+
+/usr/sbin/ypxfr hosts.byname
+/usr/sbin/ypxfr hosts.byaddr
+/usr/sbin/ypxfr ethers.byaddr
+/usr/sbin/ypxfr ethers.byname
diff --git a/ypxfr.tproj/ypxfr_xdr.c b/ypxfr.tproj/ypxfr_xdr.c
new file mode 100644
index 0000000..460addf
--- /dev/null
+++ b/ypxfr.tproj/ypxfr_xdr.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypxfr_xdr.c,v 1.3 1996/06/26 21:26:41 maja Exp $ */
+
+/*
+ * Copyright (c) 1995 Mats O Jansson <moj@stacken.kth.se>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mats O Jansson
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: ypxfr_xdr.c,v 1.3 1996/06/26 21:26:41 maja Exp $";
+#endif
+
+
+
+#include <rpc/rpc.h>
+#include <rpcsvc/yp.h>
+
+bool_t
+xdr_ypxfrstat(xdrs, objp)
+	XDR *xdrs;
+	ypxfrstat *objp;
+{
+	if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+#ifdef notdef
+bool_t
+xdr_ypreq_xfr(xdrs, objp)
+	XDR *xdrs;
+	ypreq_xfr *objp;
+{
+	if (!xdr_ypmap_parms(xdrs, &objp->map_parms)) {
+		return (FALSE);
+	}
+	if (!xdr_u_int(xdrs, &objp->transid)) {
+		return (FALSE);
+	}
+	if (!xdr_u_int(xdrs, &objp->prog)) {
+		return (FALSE);
+	}
+	if (!xdr_u_int(xdrs, &objp->port)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+#endif
+
+bool_t
+xdr_ypresp_xfr(xdrs, objp)
+	XDR *xdrs;
+	ypresp_xfr *objp;
+{
+	if (!xdr_u_int(xdrs, &objp->transid)) {
+		return (FALSE);
+	}
+	if (!xdr_ypxfrstat(xdrs, &objp->xfrstat)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+
+
+
-- 
2.47.2