summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2010-03-04 13:35:57 +0000
committerdes <des@FreeBSD.org>2010-03-04 13:35:57 +0000
commit834fb25a9ed2240101506d137b5be7d71c75f306 (patch)
tree4002c72cd1ed11909f7640bea343988cfcf63c5b /usr.sbin
parent98b742f57cafbed05c101e60cc131f5980f044d0 (diff)
parent787cf8d03f1c58ada088933408f30fd63de85bf2 (diff)
downloadFreeBSD-src-834fb25a9ed2240101506d137b5be7d71c75f306.zip
FreeBSD-src-834fb25a9ed2240101506d137b5be7d71c75f306.tar.gz
IFH@204581
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/Makefile7
-rw-r--r--usr.sbin/Makefile.inc2
-rw-r--r--usr.sbin/ac/Makefile2
-rw-r--r--usr.sbin/ac/ac.818
-rw-r--r--usr.sbin/ac/ac.c171
-rw-r--r--usr.sbin/accton/Makefile2
-rw-r--r--usr.sbin/accton/accton.c2
-rw-r--r--usr.sbin/acpi/acpiconf/Makefile1
-rw-r--r--usr.sbin/acpi/acpidb/Makefile4
-rw-r--r--usr.sbin/acpi/acpidb/acpidb.c14
-rw-r--r--usr.sbin/acpi/acpidump/Makefile1
-rw-r--r--usr.sbin/acpi/iasl/Makefile5
-rw-r--r--usr.sbin/adduser/adduser.sh20
-rw-r--r--usr.sbin/amd/Makefile.inc2
-rw-r--r--usr.sbin/ancontrol/ancontrol.c4
-rw-r--r--usr.sbin/apm/Makefile3
-rw-r--r--usr.sbin/apm/apm.834
-rw-r--r--usr.sbin/apm/apm.c13
-rw-r--r--usr.sbin/apmd/Makefile2
-rw-r--r--usr.sbin/arp/arp.c86
-rw-r--r--usr.sbin/asf/Makefile2
-rw-r--r--usr.sbin/asf/asf_kld.c2
-rw-r--r--usr.sbin/audit/Makefile2
-rw-r--r--usr.sbin/auditd/Makefile6
-rw-r--r--usr.sbin/auditreduce/Makefile2
-rw-r--r--usr.sbin/authpf/Makefile2
-rw-r--r--usr.sbin/boot0cfg/Makefile6
-rw-r--r--usr.sbin/bootparamd/Makefile.inc2
-rw-r--r--usr.sbin/bootparamd/bootparamd/bootparamd.c4
-rw-r--r--usr.sbin/bsnmpd/bsnmpd/Makefile1
-rw-r--r--usr.sbin/bsnmpd/gensnmptree/Makefile2
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c8
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c33
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c1
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_pf/Makefile1
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c2
-rw-r--r--usr.sbin/btxld/Makefile2
-rw-r--r--usr.sbin/burncd/Makefile2
-rw-r--r--usr.sbin/burncd/burncd.88
-rw-r--r--usr.sbin/burncd/burncd.c20
-rw-r--r--usr.sbin/cdcontrol/Makefile2
-rw-r--r--usr.sbin/cdcontrol/cdcontrol.c27
-rw-r--r--usr.sbin/chkgrp/Makefile2
-rw-r--r--usr.sbin/chown/Makefile2
-rw-r--r--usr.sbin/chown/chgrp.110
-rw-r--r--usr.sbin/chown/chown.812
-rw-r--r--usr.sbin/chown/chown.c17
-rw-r--r--usr.sbin/chroot/Makefile2
-rw-r--r--usr.sbin/chroot/chroot.c6
-rw-r--r--usr.sbin/clear_locks/Makefile1
-rw-r--r--usr.sbin/config/Makefile1
-rw-r--r--usr.sbin/config/lang.l2
-rw-r--r--usr.sbin/cpucontrol/Makefile2
-rw-r--r--usr.sbin/cpucontrol/cpucontrol.c4
-rwxr-xr-xusr.sbin/crashinfo/crashinfo.sh9
-rw-r--r--usr.sbin/cron/cron/Makefile2
-rw-r--r--usr.sbin/cron/cron/cron.c4
-rw-r--r--usr.sbin/crunch/Makefile.inc2
-rw-r--r--usr.sbin/crunch/examples/really-big.conf4
-rw-r--r--usr.sbin/ctm/ctm/Makefile2
-rw-r--r--usr.sbin/ctm/ctm_dequeue/Makefile2
-rw-r--r--usr.sbin/ctm/ctm_rmail/Makefile2
-rw-r--r--usr.sbin/ctm/ctm_smail/Makefile2
-rw-r--r--usr.sbin/ctm/ctm_smail/ctm_smail.c2
-rw-r--r--usr.sbin/cxgbtool/Makefile2
-rw-r--r--usr.sbin/cxgbtool/cxgbtool.c205
-rw-r--r--usr.sbin/cxgbtool/reg_defs.c22
-rw-r--r--usr.sbin/cxgbtool/reg_defs_t3.c48
-rw-r--r--usr.sbin/cxgbtool/reg_defs_t3b.c48
-rw-r--r--usr.sbin/cxgbtool/reg_defs_t3c.c48
-rw-r--r--usr.sbin/daemon/Makefile2
-rw-r--r--usr.sbin/dconschat/Makefile2
-rw-r--r--usr.sbin/devinfo/Makefile2
-rw-r--r--usr.sbin/devinfo/devinfo.c2
-rw-r--r--usr.sbin/digictl/Makefile2
-rw-r--r--usr.sbin/diskinfo/Makefile2
-rw-r--r--usr.sbin/diskinfo/diskinfo.83
-rw-r--r--usr.sbin/diskinfo/diskinfo.c12
-rw-r--r--usr.sbin/dnssec-dsfromkey/Makefile2
-rw-r--r--usr.sbin/dnssec-keyfromlabel/Makefile2
-rw-r--r--usr.sbin/dnssec-keygen/Makefile2
-rw-r--r--usr.sbin/dnssec-signzone/Makefile2
-rw-r--r--usr.sbin/dumpcis/Makefile1
-rw-r--r--usr.sbin/editmap/Makefile2
-rw-r--r--usr.sbin/eeprom/Makefile1
-rw-r--r--usr.sbin/eeprom/eeprom.87
-rw-r--r--usr.sbin/eeprom/eeprom.c9
-rw-r--r--usr.sbin/extattr/Makefile2
-rw-r--r--usr.sbin/extattr/rmextattr.c2
-rw-r--r--usr.sbin/extattrctl/Makefile2
-rw-r--r--usr.sbin/extattrctl/extattrctl.c2
-rw-r--r--usr.sbin/faithd/Makefile2
-rw-r--r--usr.sbin/faithd/faithd.889
-rw-r--r--usr.sbin/faithd/faithd.c8
-rw-r--r--usr.sbin/fdcontrol/Makefile1
-rw-r--r--usr.sbin/fdformat/Makefile1
-rw-r--r--usr.sbin/fdread/Makefile2
-rw-r--r--usr.sbin/fdwrite/Makefile1
-rw-r--r--usr.sbin/fifolog/Makefile.inc2
-rw-r--r--usr.sbin/fifolog/fifolog_writer/fifolog_writer.c2
-rw-r--r--usr.sbin/fifolog/lib/getdate.y2
-rw-r--r--usr.sbin/freebsd-update/freebsd-update.sh4
-rw-r--r--usr.sbin/ftp-proxy/Makefile.inc2
-rw-r--r--usr.sbin/ftp-proxy/libevent/Makefile2
-rw-r--r--usr.sbin/getfmac/Makefile2
-rw-r--r--usr.sbin/getpmac/Makefile2
-rw-r--r--usr.sbin/gstat/Makefile1
-rw-r--r--usr.sbin/i2c/i2c.82
-rw-r--r--usr.sbin/inetd/Makefile2
-rw-r--r--usr.sbin/inetd/inetd.c7
-rw-r--r--usr.sbin/iostat/Makefile2
-rw-r--r--usr.sbin/ip6addrctl/Makefile2
-rw-r--r--usr.sbin/ipfwpcap/Makefile2
-rw-r--r--usr.sbin/jail/Makefile2
-rw-r--r--usr.sbin/jail/jail.822
-rw-r--r--usr.sbin/jexec/Makefile1
-rw-r--r--usr.sbin/jls/Makefile2
-rw-r--r--usr.sbin/jls/jls.c5
-rw-r--r--usr.sbin/kbdcontrol/kbdcontrol.c2
-rw-r--r--usr.sbin/kernbb/Makefile1
-rw-r--r--usr.sbin/lastlogin/Makefile2
-rw-r--r--usr.sbin/lastlogin/lastlogin.86
-rw-r--r--usr.sbin/lastlogin/lastlogin.c73
-rw-r--r--usr.sbin/lmcconfig/Makefile2
-rw-r--r--usr.sbin/lpr/common_source/Makefile2
-rw-r--r--usr.sbin/lpr/common_source/lp.h2
-rw-r--r--usr.sbin/lpr/common_source/rmjob.c2
-rw-r--r--usr.sbin/lpr/filters.ru/Makefile.inc2
-rw-r--r--usr.sbin/lpr/lp/lp.sh4
-rw-r--r--usr.sbin/lpr/lpc/Makefile2
-rw-r--r--usr.sbin/lpr/lpd/Makefile2
-rw-r--r--usr.sbin/lpr/lpr/Makefile2
-rw-r--r--usr.sbin/lptcontrol/Makefile2
-rw-r--r--usr.sbin/mailstats/Makefile2
-rw-r--r--usr.sbin/mailwrapper/Makefile1
-rw-r--r--usr.sbin/makefs/compat/pwcache.c7
-rw-r--r--usr.sbin/makefs/compat/strsuftoll.c7
-rw-r--r--usr.sbin/makefs/getid.c7
-rw-r--r--usr.sbin/makefs/makefs.82
-rw-r--r--usr.sbin/makemap/Makefile2
-rw-r--r--usr.sbin/memcontrol/Makefile1
-rw-r--r--usr.sbin/mergemaster/mergemaster.867
-rwxr-xr-xusr.sbin/mergemaster/mergemaster.sh260
-rw-r--r--usr.sbin/mfiutil/Makefile1
-rw-r--r--usr.sbin/mixer/Makefile2
-rw-r--r--usr.sbin/mld6query/Makefile2
-rw-r--r--usr.sbin/mlxcontrol/Makefile2
-rw-r--r--usr.sbin/mount_portalfs/mount_portalfs.c2
-rw-r--r--usr.sbin/mount_smbfs/Makefile1
-rw-r--r--usr.sbin/mountd/exports.53
-rw-r--r--usr.sbin/moused/Makefile2
-rw-r--r--usr.sbin/mptable/Makefile1
-rw-r--r--usr.sbin/mptable/mptable.c2
-rw-r--r--usr.sbin/mptutil/Makefile4
-rw-r--r--usr.sbin/mptutil/mpt_cam.c222
-rw-r--r--usr.sbin/mptutil/mpt_show.c16
-rw-r--r--usr.sbin/mtree/Makefile2
-rw-r--r--usr.sbin/mtree/mtree.54
-rw-r--r--usr.sbin/named-checkconf/Makefile2
-rw-r--r--usr.sbin/named-checkzone/Makefile2
-rw-r--r--usr.sbin/named/Makefile2
-rw-r--r--usr.sbin/ndiscvt/ndiscvt.c6
-rw-r--r--usr.sbin/ndp/Makefile2
-rw-r--r--usr.sbin/ndp/gnuc.h2
-rw-r--r--usr.sbin/newsyslog/Makefile2
-rw-r--r--usr.sbin/newsyslog/newsyslog.88
-rw-r--r--usr.sbin/newsyslog/newsyslog.c21
-rw-r--r--usr.sbin/nfsd/Makefile2
-rw-r--r--usr.sbin/nfsd/nfsd.c6
-rw-r--r--usr.sbin/nfsd/nfsv4.444
-rw-r--r--usr.sbin/nfsd/stablerestart.526
-rw-r--r--usr.sbin/nghook/Makefile1
-rw-r--r--usr.sbin/nscd/nscd.conf.52
-rw-r--r--usr.sbin/ntp/Makefile2
-rw-r--r--usr.sbin/ntp/Makefile.inc2
-rw-r--r--usr.sbin/ntp/config.h2
-rw-r--r--usr.sbin/ntp/doc/Makefile2
-rw-r--r--usr.sbin/ntp/doc/ntpd.82
-rw-r--r--usr.sbin/ntp/ntptrace/Makefile9
-rw-r--r--usr.sbin/nvram/Makefile2
-rw-r--r--usr.sbin/ofwdump/Makefile2
-rw-r--r--usr.sbin/pciconf/Makefile2
-rw-r--r--usr.sbin/pkg_install/add/main.c2
-rw-r--r--usr.sbin/pkg_install/create/main.c2
-rw-r--r--usr.sbin/pkg_install/delete/Makefile1
-rw-r--r--usr.sbin/pkg_install/delete/main.c2
-rw-r--r--usr.sbin/pkg_install/info/Makefile1
-rw-r--r--usr.sbin/pkg_install/info/main.c2
-rw-r--r--usr.sbin/pkg_install/lib/lib.h2
-rw-r--r--usr.sbin/pkg_install/updating/Makefile1
-rw-r--r--usr.sbin/pkg_install/updating/main.c59
-rw-r--r--usr.sbin/pkg_install/updating/pkg_updating.127
-rw-r--r--usr.sbin/pkg_install/version/Makefile1
-rw-r--r--usr.sbin/pkg_install/version/main.c2
-rw-r--r--usr.sbin/pmcannotate/Makefile2
-rw-r--r--usr.sbin/pmcannotate/pmcannotate.c4
-rw-r--r--usr.sbin/pmccontrol/Makefile2
-rw-r--r--usr.sbin/pmcstat/Makefile9
-rw-r--r--usr.sbin/pmcstat/pmcpl_annotate.c111
-rw-r--r--usr.sbin/pmcstat/pmcpl_annotate.h41
-rw-r--r--usr.sbin/pmcstat/pmcpl_callgraph.c682
-rw-r--r--usr.sbin/pmcstat/pmcpl_callgraph.h67
-rw-r--r--usr.sbin/pmcstat/pmcpl_calltree.c1000
-rw-r--r--usr.sbin/pmcstat/pmcpl_calltree.h42
-rw-r--r--usr.sbin/pmcstat/pmcpl_gprof.c533
-rw-r--r--usr.sbin/pmcstat/pmcpl_gprof.h47
-rw-r--r--usr.sbin/pmcstat/pmcstat.828
-rw-r--r--usr.sbin/pmcstat/pmcstat.c286
-rw-r--r--usr.sbin/pmcstat/pmcstat.h75
-rw-r--r--usr.sbin/pmcstat/pmcstat_log.c1702
-rw-r--r--usr.sbin/pmcstat/pmcstat_log.h196
-rw-r--r--usr.sbin/pmcstat/pmcstat_top.h75
-rw-r--r--usr.sbin/pnpinfo/Makefile2
-rw-r--r--usr.sbin/portsnap/make_index/Makefile1
-rw-r--r--usr.sbin/portsnap/phttpget/Makefile1
-rw-r--r--usr.sbin/portsnap/portsnap/portsnap.sh18
-rw-r--r--usr.sbin/powerd/Makefile5
-rw-r--r--usr.sbin/powerd/powerd.89
-rw-r--r--usr.sbin/powerd/powerd.c6
-rw-r--r--usr.sbin/ppp/Makefile3
-rw-r--r--usr.sbin/ppp/id.c35
-rw-r--r--usr.sbin/ppp/id.h22
-rw-r--r--usr.sbin/ppp/physical.c28
-rw-r--r--usr.sbin/ppp/physical.h2
-rw-r--r--usr.sbin/ppp/ppp.8.m411
-rw-r--r--usr.sbin/pppctl/Makefile2
-rw-r--r--usr.sbin/praliases/Makefile2
-rw-r--r--usr.sbin/praudit/Makefile2
-rw-r--r--usr.sbin/procctl/Makefile2
-rw-r--r--usr.sbin/pstat/Makefile2
-rw-r--r--usr.sbin/pw/Makefile2
-rw-r--r--usr.sbin/pw/pw_user.c5
-rw-r--r--usr.sbin/pwd_mkdb/Makefile1
-rw-r--r--usr.sbin/quotaon/Makefile2
-rw-r--r--usr.sbin/quotaon/quotaon.c4
-rw-r--r--usr.sbin/repquota/Makefile2
-rw-r--r--usr.sbin/rip6query/Makefile1
-rw-r--r--usr.sbin/rip6query/rip6query.c12
-rw-r--r--usr.sbin/rmt/Makefile2
-rw-r--r--usr.sbin/rmt/rmt.c10
-rw-r--r--usr.sbin/rndc-confgen/Makefile2
-rw-r--r--usr.sbin/rndc/Makefile2
-rw-r--r--usr.sbin/route6d/Makefile2
-rw-r--r--usr.sbin/rpc.lockd/Makefile2
-rw-r--r--usr.sbin/rpc.statd/Makefile2
-rw-r--r--usr.sbin/rpc.umntall/Makefile2
-rw-r--r--usr.sbin/rpc.umntall/mounttab.c28
-rw-r--r--usr.sbin/rpc.yppasswdd/Makefile2
-rw-r--r--usr.sbin/rpc.ypupdated/Makefile2
-rw-r--r--usr.sbin/rpc.ypxfrd/Makefile2
-rw-r--r--usr.sbin/rpcbind/Makefile2
-rw-r--r--usr.sbin/rpcbind/rpcb_svc_com.c1
-rw-r--r--usr.sbin/rpcbind/rpcbind.c76
-rw-r--r--usr.sbin/rpcbind/rpcbind.h9
-rw-r--r--usr.sbin/rpcbind/util.c27
-rw-r--r--usr.sbin/rrenumd/Makefile2
-rw-r--r--usr.sbin/rtadvd/Makefile2
-rw-r--r--usr.sbin/rtprio/Makefile2
-rw-r--r--usr.sbin/rtsold/Makefile2
-rw-r--r--usr.sbin/rtsold/dump.c8
-rw-r--r--usr.sbin/rtsold/if.c1
-rw-r--r--usr.sbin/rtsold/probe.c2
-rw-r--r--usr.sbin/rtsold/rtsock.c6
-rw-r--r--usr.sbin/rtsold/rtsol.c17
-rw-r--r--usr.sbin/rtsold/rtsold.c42
-rw-r--r--usr.sbin/rtsold/rtsold.h2
-rw-r--r--usr.sbin/rwhod/Makefile3
-rw-r--r--usr.sbin/rwhod/rwhod.85
-rw-r--r--usr.sbin/rwhod/rwhod.c88
-rw-r--r--usr.sbin/sa/Makefile2
-rw-r--r--usr.sbin/sa/main.c2
-rw-r--r--usr.sbin/sa/pdb.c8
-rw-r--r--usr.sbin/sa/usrdb.c8
-rw-r--r--usr.sbin/sade/termcap.c4
-rw-r--r--usr.sbin/sendmail/Makefile2
-rw-r--r--usr.sbin/service/Makefile7
-rw-r--r--usr.sbin/service/service.8131
-rwxr-xr-xusr.sbin/service/service.sh120
-rw-r--r--usr.sbin/setfmac/Makefile2
-rw-r--r--usr.sbin/setpmac/Makefile2
-rw-r--r--usr.sbin/smbmsg/Makefile1
-rw-r--r--usr.sbin/smbmsg/smbmsg.82
-rw-r--r--usr.sbin/snapinfo/snapinfo.c2
-rw-r--r--usr.sbin/sysinstall/Makefile33
-rw-r--r--usr.sbin/sysinstall/acpi.c356
-rw-r--r--usr.sbin/sysinstall/acpidump.h177
-rw-r--r--usr.sbin/sysinstall/biosmptable.c275
-rw-r--r--usr.sbin/sysinstall/cdrom.c23
-rw-r--r--usr.sbin/sysinstall/devices.c1
-rw-r--r--usr.sbin/sysinstall/disks.c2
-rw-r--r--usr.sbin/sysinstall/dist.c12
-rw-r--r--usr.sbin/sysinstall/install.c15
-rw-r--r--usr.sbin/sysinstall/label.c4
-rw-r--r--usr.sbin/sysinstall/menus.c4
-rw-r--r--usr.sbin/sysinstall/package.c2
-rw-r--r--usr.sbin/sysinstall/sysinstall.82
-rw-r--r--usr.sbin/sysinstall/tcpip.c83
-rw-r--r--usr.sbin/sysinstall/termcap.c8
-rw-r--r--usr.sbin/sysinstall/user.c7
-rw-r--r--usr.sbin/syslogd/syslogd.c44
-rw-r--r--usr.sbin/tcpdchk/Makefile2
-rw-r--r--usr.sbin/tcpdmatch/Makefile2
-rw-r--r--usr.sbin/tcpdrop/Makefile1
-rw-r--r--usr.sbin/tcpdump/Makefile.inc2
-rw-r--r--usr.sbin/timed/timed/master.c12
-rw-r--r--usr.sbin/timed/timed/slave.c14
-rw-r--r--usr.sbin/traceroute/Makefile6
-rw-r--r--usr.sbin/traceroute/findsaddr-udp.c94
-rw-r--r--usr.sbin/traceroute6/Makefile2
-rw-r--r--usr.sbin/tzsetup/Makefile2
-rw-r--r--usr.sbin/tzsetup/tzsetup.847
-rw-r--r--usr.sbin/tzsetup/tzsetup.c259
-rw-r--r--usr.sbin/uathload/Makefile2
-rw-r--r--usr.sbin/uhsoctl/Makefile10
-rw-r--r--usr.sbin/uhsoctl/uhsoctl.1104
-rw-r--r--usr.sbin/uhsoctl/uhsoctl.c1532
-rw-r--r--usr.sbin/usbconfig/Makefile1
-rw-r--r--usr.sbin/usbconfig/dump.c106
-rw-r--r--usr.sbin/usbconfig/dump.h6
-rw-r--r--usr.sbin/usbconfig/usbconfig.847
-rw-r--r--usr.sbin/usbconfig/usbconfig.c163
-rw-r--r--usr.sbin/usbdevs/Makefile2
-rw-r--r--usr.sbin/usbdevs/usbdevs.87
-rw-r--r--usr.sbin/usbdevs/usbdevs.c7
-rw-r--r--usr.sbin/vidcontrol/Makefile2
-rw-r--r--usr.sbin/vidcontrol/vidcontrol.13
-rw-r--r--usr.sbin/vidcontrol/vidcontrol.c22
-rw-r--r--usr.sbin/vipw/Makefile2
-rw-r--r--usr.sbin/wake/Makefile3
-rw-r--r--usr.sbin/wake/wake.829
-rw-r--r--usr.sbin/wake/wake.c105
-rw-r--r--usr.sbin/watchdogd/Makefile1
-rw-r--r--usr.sbin/watchdogd/watchdogd.c6
-rw-r--r--usr.sbin/wlandebug/Makefile2
-rw-r--r--usr.sbin/wlconfig/Makefile2
-rw-r--r--usr.sbin/yp_mkdb/Makefile2
-rw-r--r--usr.sbin/ypbind/Makefile2
-rw-r--r--usr.sbin/yppoll/Makefile2
-rw-r--r--usr.sbin/yppoll/yppoll.87
-rw-r--r--usr.sbin/yppush/Makefile2
-rw-r--r--usr.sbin/yppush/yppush_main.c1
-rw-r--r--usr.sbin/ypserv/Makefile2
-rw-r--r--usr.sbin/ypserv/yp_main.c416
-rw-r--r--usr.sbin/ypserv/yp_server.c5
-rw-r--r--usr.sbin/ypserv/ypinit.sh2
-rw-r--r--usr.sbin/ypserv/ypserv.811
-rw-r--r--usr.sbin/ypset/Makefile2
-rw-r--r--usr.sbin/zic/Theory570
-rw-r--r--usr.sbin/zic/ialloc.c91
-rw-r--r--usr.sbin/zic/private.h272
-rw-r--r--usr.sbin/zic/scheck.c68
-rw-r--r--usr.sbin/zic/zdump.863
-rw-r--r--usr.sbin/zic/zdump.c675
-rw-r--r--usr.sbin/zic/zdump/Makefile6
-rw-r--r--usr.sbin/zic/zic.8465
-rw-r--r--usr.sbin/zic/zic.c2723
-rw-r--r--usr.sbin/zic/zic/Makefile6
357 files changed, 8272 insertions, 8721 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 160b122..cdcaaf3 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -167,6 +167,7 @@ SUBDIR= ${_ac} \
${_sa} \
${_sade} \
${_sendmail} \
+ service \
setfib \
setfmac \
setpmac \
@@ -188,6 +189,7 @@ SUBDIR= ${_ac} \
tzsetup \
${_uathload} \
ugidfw \
+ ${_uhsoctl} \
${_usbdevs} \
${_usbconfig} \
${_vidcontrol} \
@@ -409,6 +411,7 @@ _crunch= crunch
.if ${MACHINE_ARCH} != "ia64"
_uathload= uathload
.endif
+_uhsoctl= uhsoctl
#_usbdevs= usbdevs
_usbconfig= usbconfig
.endif
@@ -468,6 +471,9 @@ _boot98cfg= boot98cfg
.if ${MK_ACPI} != "no"
_acpi= acpi
.endif
+.if ${MK_APM} != "no"
+_apm= apm
+.endif
_asf= asf
_boot0cfg= boot0cfg
.if ${MK_TOOLCHAIN} != "no"
@@ -506,6 +512,7 @@ _ofwdump= ofwdump
.if ${MACHINE_ARCH} == "sparc64"
_eeprom= eeprom
+_mount_smbfs= mount_smbfs
_ofwdump= ofwdump
.endif
diff --git a/usr.sbin/Makefile.inc b/usr.sbin/Makefile.inc
index 4347591..bd13613 100644
--- a/usr.sbin/Makefile.inc
+++ b/usr.sbin/Makefile.inc
@@ -2,3 +2,5 @@
# $FreeBSD$
BINDIR?= /usr/sbin
+
+WARNS?= 6
diff --git a/usr.sbin/ac/Makefile b/usr.sbin/ac/Makefile
index c45a0d6..46064fc 100644
--- a/usr.sbin/ac/Makefile
+++ b/usr.sbin/ac/Makefile
@@ -3,8 +3,6 @@
PROG= ac
MAN= ac.8
-WARNS?= 4
-
# Temporary, while tracking down problem wrt 64-bit time_t's on sparc64
.if ${MACHINE_ARCH} == "sparc64"
CFLAGS+=-DDEBUG
diff --git a/usr.sbin/ac/ac.8 b/usr.sbin/ac/ac.8
index efe3e23..34484ab 100644
--- a/usr.sbin/ac/ac.8
+++ b/usr.sbin/ac/ac.8
@@ -45,7 +45,7 @@
.Op Ar users ...
.Sh DESCRIPTION
If the file
-.Pa /var/log/wtmp
+.Pa /var/log/utx.log
exists, a record of individual login and logout
times are written to it by
.Xr login 1
@@ -86,7 +86,7 @@ flags may be specified.
Read connect time data from
.Ar wtmp
instead of the default file,
-.Pa /var/log/wtmp .
+.Pa /var/log/utx.log .
.It Ar users ...
Display totals for the given individuals only.
.El
@@ -95,20 +95,20 @@ If no arguments are given,
.Nm
displays the total connect time for all
accounts with login sessions recorded in
-.Pa wtmp .
+.Pa utx.log .
.Pp
The default
-.Pa wtmp
+.Pa utx.log
file will increase without bound unless it is truncated.
It is normally truncated by the daily scripts run
by
.Xr cron 8 ,
which rename and rotate the
-.Pa wtmp
+.Pa utx.log
files, keeping a week's worth of data on
hand.
No login or connect time accounting is performed if
-.Pa /var/log/wtmp
+.Pa /var/log/utx.log
does not exist.
.Pp
For example,
@@ -122,15 +122,15 @@ allows times recorded in
to be charged out at a different rate than
.Pa other .
.Sh FILES
-.Bl -tag -width /var/log/wtmp -compact
-.It Pa /var/log/wtmp
+.Bl -tag -width /var/log/utx.log -compact
+.It Pa /var/log/utx.log
connect time accounting file
.El
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Xr login 1 ,
-.Xr utmp 5 ,
+.Xr getutxent 3 ,
.Xr init 8 ,
.Xr sa 8
.\" .Sh NOTES
diff --git a/usr.sbin/ac/ac.c b/usr.sbin/ac/ac.c
index 031099a..d6db2d8 100644
--- a/usr.sbin/ac/ac.c
+++ b/usr.sbin/ac/ac.c
@@ -27,14 +27,14 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <timeconv.h>
#include <unistd.h>
-#include <utmp.h>
+#include <utmpx.h>
/*
* this is for our list of currently logged in sessions
*/
struct utmp_list {
struct utmp_list *next;
- struct utmp usr;
+ struct utmpx usr;
};
/*
@@ -42,7 +42,7 @@ struct utmp_list {
*/
struct user_list {
struct user_list *next;
- char name[UT_NAMESIZE+1];
+ char name[sizeof(((struct utmpx *)0)->ut_user)];
time_t secs;
};
@@ -51,7 +51,7 @@ struct user_list {
*/
struct tty_list {
struct tty_list *next;
- char name[UT_LINESIZE+3];
+ char name[sizeof(((struct utmpx *)0)->ut_host) + 2];
size_t len;
int ret;
};
@@ -81,15 +81,14 @@ static int Debug = 0;
#endif
int main(int, char **);
-int ac(FILE *);
+int ac(const char *);
struct tty_list *add_tty(char *);
#ifdef DEBUG
-const char *debug_pfx(const struct utmp *, const struct utmp *);
+const char *debug_pfx(const struct utmpx *, const struct utmpx *);
#endif
int do_tty(char *);
-FILE *file(const char *);
-struct utmp_list *log_in(struct utmp_list *, struct utmp *);
-struct utmp_list *log_out(struct utmp_list *, struct utmp *);
+struct utmp_list *log_in(struct utmp_list *, struct utmpx *);
+struct utmp_list *log_out(struct utmp_list *, struct utmpx *);
int on_console(struct utmp_list *);
void show(const char *, time_t);
void show_today(struct user_list *, struct utmp_list *,
@@ -98,22 +97,6 @@ void show_users(struct user_list *);
struct user_list *update_user(struct user_list *, char *, time_t);
void usage(void);
-/*
- * open wtmp or die
- */
-FILE *
-file(const char *name)
-{
- FILE *fp;
-
- if ((fp = fopen(name, "r")) == NULL)
- err(1, "%s", name);
- /* in case we want to discriminate */
- if (strcmp(_PATH_WTMP, name))
- Flags |= AC_W;
- return fp;
-}
-
struct tty_list *
add_tty(char *name)
{
@@ -173,8 +156,7 @@ on_console(struct utmp_list *head)
struct utmp_list *up;
for (up = head; up; up = up->next) {
- if (strncmp(up->usr.ut_line, Console,
- sizeof (up->usr.ut_line)) == 0)
+ if (strcmp(up->usr.ut_line, Console) == 0)
return 1;
}
return 0;
@@ -190,7 +172,7 @@ update_user(struct user_list *head, char *name, time_t secs)
struct user_list *up;
for (up = head; up != NULL; up = up->next) {
- if (strncmp(up->name, name, UT_NAMESIZE) == 0) {
+ if (strcmp(up->name, name) == 0) {
up->secs += secs;
Total += secs;
return head;
@@ -217,9 +199,10 @@ update_user(struct user_list *head, char *name, time_t secs)
* includes a timestamp (perhaps with year), device-name, and user-name.
*/
const char *
-debug_pfx(const struct utmp *event_up, const struct utmp *userinf_up)
+debug_pfx(const struct utmpx *event_up, const struct utmpx *userinf_up)
{
- static char str_result[40+UT_LINESIZE+UT_NAMESIZE];
+ static char str_result[40 + sizeof(userinf_up->ut_line) +
+ sizeof(userinf_up->ut_user)];
static char thisyear[5];
size_t maxcopy;
time_t ut_timecopy;
@@ -231,15 +214,10 @@ debug_pfx(const struct utmp *event_up, const struct utmp *userinf_up)
strlcpy(thisyear, &str_result[20], sizeof(thisyear));
}
- if (event_up->ut_time == 0)
+ if (event_up->ut_tv.tv_sec == 0)
strlcpy(str_result, "*ZeroTime* --:--:-- ", sizeof(str_result));
else {
- /*
- * The type of utmp.ut_time is not necessary type time_t, as
- * it is explicitly defined as type int32_t. Copy the value
- * for platforms where sizeof(time_t) != sizeof(int32_t).
- */
- ut_timecopy = _time32_to_time(event_up->ut_time);
+ ut_timecopy = event_up->ut_tv.tv_sec;
strlcpy(str_result, ctime(&ut_timecopy), sizeof(str_result));
/*
* Include the year, if it is not the same year as "now".
@@ -255,22 +233,20 @@ debug_pfx(const struct utmp *event_up, const struct utmp *userinf_up)
if (userinf_up->ut_line[0] == '\0')
strlcat(str_result, "NoDev", sizeof(str_result));
else {
- /* ut_line is not necessarily null-terminated. */
- maxcopy = strlen(str_result) + UT_LINESIZE + 1;
+ maxcopy = strlen(str_result) + sizeof(userinf_up->ut_line);
if (maxcopy > sizeof(str_result))
maxcopy = sizeof(str_result);
strlcat(str_result, userinf_up->ut_line, maxcopy);
}
strlcat(str_result, ": ", sizeof(str_result));
- if (userinf_up->ut_name[0] == '\0')
+ if (userinf_up->ut_user[0] == '\0')
strlcat(str_result, "LogOff", sizeof(str_result));
else {
- /* ut_name is not necessarily null-terminated. */
- maxcopy = strlen(str_result) + UT_NAMESIZE + 1;
+ maxcopy = strlen(str_result) + sizeof(userinf_up->ut_user);
if (maxcopy > sizeof(str_result))
maxcopy = sizeof(str_result);
- strlcat(str_result, userinf_up->ut_name, maxcopy);
+ strlcat(str_result, userinf_up->ut_user, maxcopy);
}
return (str_result);
@@ -280,12 +256,11 @@ debug_pfx(const struct utmp *event_up, const struct utmp *userinf_up)
int
main(int argc, char *argv[])
{
- FILE *fp;
+ const char *wtmpf = NULL;
int c;
(void) setlocale(LC_TIME, "");
- fp = NULL;
while ((c = getopt(argc, argv, "Dc:dpt:w:")) != -1) {
switch (c) {
#ifdef DEBUG
@@ -310,7 +285,8 @@ main(int argc, char *argv[])
add_tty(optarg);
break;
case 'w':
- fp = file(optarg);
+ Flags |= AC_W;
+ wtmpf = optarg;
break;
case '?':
default:
@@ -329,16 +305,7 @@ main(int argc, char *argv[])
}
if (Flags & AC_D)
Flags &= ~AC_P;
- if (fp == NULL) {
- /*
- * if _PATH_WTMP does not exist, exit quietly
- */
- if (access(_PATH_WTMP, 0) != 0 && errno == ENOENT)
- return 0;
-
- fp = file(_PATH_WTMP);
- }
- ac(fp);
+ ac(wtmpf);
return 0;
}
@@ -349,7 +316,8 @@ main(int argc, char *argv[])
void
show(const char *name, time_t secs)
{
- (void)printf("\t%-*s %8.2f\n", UT_NAMESIZE, name,
+ (void)printf("\t%-*s %8.2f\n",
+ (int)sizeof(((struct utmpx *)0)->ut_user), name,
((double)secs / 3600));
}
@@ -384,9 +352,9 @@ show_today(struct user_list *users, struct utmp_list *logins, time_t secs)
yesterday++;
for (lp = logins; lp != NULL; lp = lp->next) {
- secs = yesterday - lp->usr.ut_time;
- Users = update_user(Users, lp->usr.ut_name, secs);
- lp->usr.ut_time = yesterday; /* as if they just logged in */
+ secs = yesterday - lp->usr.ut_tv.tv_sec;
+ Users = update_user(Users, lp->usr.ut_user, secs);
+ lp->usr.ut_tv.tv_sec = yesterday; /* as if they just logged in */
}
secs = 0;
for (up = users; up != NULL; up = up->next) {
@@ -403,16 +371,17 @@ show_today(struct user_list *users, struct utmp_list *logins, time_t secs)
* been shut down.
*/
struct utmp_list *
-log_out(struct utmp_list *head, struct utmp *up)
+log_out(struct utmp_list *head, struct utmpx *up)
{
struct utmp_list *lp, *lp2, *tlp;
time_t secs;
for (lp = head, lp2 = NULL; lp != NULL; )
- if (*up->ut_line == '~' || strncmp(lp->usr.ut_line, up->ut_line,
- sizeof (up->ut_line)) == 0) {
- secs = up->ut_time - lp->usr.ut_time;
- Users = update_user(Users, lp->usr.ut_name, secs);
+ if (up->ut_type == BOOT_TIME || up->ut_type == SHUTDOWN_TIME ||
+ (up->ut_type == DEAD_PROCESS &&
+ memcmp(lp->usr.ut_id, up->ut_id, sizeof up->ut_id) == 0)) {
+ secs = up->ut_tv.tv_sec - lp->usr.ut_tv.tv_sec;
+ Users = update_user(Users, lp->usr.ut_user, secs);
#ifdef DEBUG
if (Debug)
printf("%s logged out (%2d:%02d:%02d)\n",
@@ -442,7 +411,7 @@ log_out(struct utmp_list *head, struct utmp *up)
* if do_tty says ok, login a user
*/
struct utmp_list *
-log_in(struct utmp_list *head, struct utmp *up)
+log_in(struct utmp_list *head, struct utmpx *up)
{
struct utmp_list *lp;
@@ -491,7 +460,7 @@ log_in(struct utmp_list *head, struct utmp *up)
errx(1, "malloc failed");
lp->next = head;
head = lp;
- memmove((char *)&lp->usr, (char *)up, sizeof (struct utmp));
+ memmove(&lp->usr, up, sizeof *up);
#ifdef DEBUG
if (Debug) {
printf("%s logged in", debug_pfx(&lp->usr, up));
@@ -505,10 +474,10 @@ log_in(struct utmp_list *head, struct utmp *up)
}
int
-ac(FILE *fp)
+ac(const char *file)
{
struct utmp_list *lp, *head = NULL;
- struct utmp usr;
+ struct utmpx *usr, usht;
struct tm *ltm;
time_t prev_secs, secs, ut_timecopy;
int day, rfound, tchanged, tskipped;
@@ -517,14 +486,11 @@ ac(FILE *fp)
prev_secs = 1; /* Minimum acceptable date == 1970 */
rfound = tchanged = tskipped = 0;
secs = 0;
- while (fread((char *)&usr, sizeof(usr), 1, fp) == 1) {
+ if (setutxdb(UTXDB_LOG, file) != 0)
+ err(1, "%s", file);
+ while ((usr = getutxent()) != NULL) {
rfound++;
- /*
- * The type of utmp.ut_time is not necessary type time_t, as
- * it is explicitly defined as type int32_t. Copy the value
- * for platforms where sizeof(time_t) != size(int32_t).
- */
- ut_timecopy = _time32_to_time(usr.ut_time);
+ ut_timecopy = usr->ut_tv.tv_sec;
/*
* With sparc64 using 64-bit time_t's, there is some system
* routine which sets ut_time==0 (the high-order word of a
@@ -540,10 +506,10 @@ ac(FILE *fp)
#ifdef DEBUG
if (Debug)
printf("%s - date changed to: %s",
- debug_pfx(&usr, &usr), ctime(&prev_secs));
+ debug_pfx(usr, usr), ctime(&prev_secs));
#endif
tchanged++;
- usr.ut_time = ut_timecopy = prev_secs;
+ usr->ut_tv.tv_sec = ut_timecopy = prev_secs;
}
/*
* Skip records where the time goes backwards.
@@ -552,7 +518,7 @@ ac(FILE *fp)
#ifdef DEBUG
if (Debug)
printf("%s - bad date, record skipped\n",
- debug_pfx(&usr, &usr));
+ debug_pfx(usr, usr));
#endif
tskipped++;
continue; /* Skip this invalid record. */
@@ -576,50 +542,51 @@ ac(FILE *fp)
} else
day = ltm->tm_yday;
}
- switch(*usr.ut_line) {
- case '|':
+ switch(usr->ut_type) {
+ case OLD_TIME:
secs = ut_timecopy;
break;
- case '{':
+ case NEW_TIME:
secs -= ut_timecopy;
/*
* adjust time for those logged in
*/
for (lp = head; lp != NULL; lp = lp->next)
- lp->usr.ut_time -= secs;
+ lp->usr.ut_tv.tv_sec -= secs;
break;
- case '~': /* reboot or shutdown */
- head = log_out(head, &usr);
+ case BOOT_TIME:
+ case SHUTDOWN_TIME:
+ head = log_out(head, usr);
FirstTime = ut_timecopy; /* shouldn't be needed */
break;
- default:
+ case USER_PROCESS:
/*
* if they came in on tty[p-sP-S]*, then it is only
* a login session if the ut_host field is non-empty
*/
- if (*usr.ut_name) {
- if (strncmp(usr.ut_line, "tty", 3) == 0 ||
- strchr("pqrsPQRS", usr.ut_line[3]) != 0 ||
- *usr.ut_host != '\0')
- head = log_in(head, &usr);
+ if (strncmp(usr->ut_line, "tty", 3) != 0 ||
+ strchr("pqrsPQRS", usr->ut_line[3]) == NULL ||
+ *usr->ut_host != '\0')
+ head = log_in(head, usr);
#ifdef DEBUG
- else if (Debug > 1)
- /* Things such as 'screen' sessions. */
- printf("%s - record ignored\n",
- debug_pfx(&usr, &usr));
+ else if (Debug > 1)
+ /* Things such as 'screen' sessions. */
+ printf("%s - record ignored\n",
+ debug_pfx(usr, usr));
#endif
- } else
- head = log_out(head, &usr);
+ break;
+ case DEAD_PROCESS:
+ head = log_out(head, usr);
break;
}
}
- (void)fclose(fp);
+ endutxent();
if (!(Flags & AC_W))
- usr.ut_time = time((time_t *)0);
- (void)strcpy(usr.ut_line, "~");
+ usht.ut_tv.tv_sec = time(NULL);
+ usht.ut_type = SHUTDOWN_TIME;
if (Flags & AC_D) {
- ut_timecopy = _time32_to_time(usr.ut_time);
+ ut_timecopy = usht.ut_tv.tv_sec;
ltm = localtime(&ut_timecopy);
if (day >= 0 && day != ltm->tm_yday) {
/*
@@ -635,7 +602,7 @@ ac(FILE *fp)
/*
* anyone still logged in gets time up to now
*/
- head = log_out(head, &usr);
+ head = log_out(head, &usht);
if (Flags & AC_D)
show_today(Users, head, time((time_t *)0));
diff --git a/usr.sbin/accton/Makefile b/usr.sbin/accton/Makefile
index 7ea45a7..ea9b4f4 100644
--- a/usr.sbin/accton/Makefile
+++ b/usr.sbin/accton/Makefile
@@ -4,6 +4,4 @@
PROG= accton
MAN= accton.8
-WARNS?= 4
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/accton/accton.c b/usr.sbin/accton/accton.c
index c1bb8b6..33e6604 100644
--- a/usr.sbin/accton/accton.c
+++ b/usr.sbin/accton/accton.c
@@ -80,7 +80,7 @@ main(int argc, char *argv[])
}
static void
-usage()
+usage(void)
{
(void)fprintf(stderr, "usage: accton [file]\n");
exit(1);
diff --git a/usr.sbin/acpi/acpiconf/Makefile b/usr.sbin/acpi/acpiconf/Makefile
index bb0df4b..5f862a2 100644
--- a/usr.sbin/acpi/acpiconf/Makefile
+++ b/usr.sbin/acpi/acpiconf/Makefile
@@ -3,6 +3,5 @@
PROG= acpiconf
MAN= acpiconf.8
-WARNS?= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/acpi/acpidb/Makefile b/usr.sbin/acpi/acpidb/Makefile
index 8ad8239..5981f38 100644
--- a/usr.sbin/acpi/acpidb/Makefile
+++ b/usr.sbin/acpi/acpidb/Makefile
@@ -38,8 +38,8 @@ SRCS+= psargs.c psloop.c psopcode.c psparse.c psscope.c \
# namespace
SRCS+= nsaccess.c nsalloc.c nsdump.c nseval.c nsinit.c \
nsload.c nsnames.c nsobject.c nsparse.c nspredef.c \
- nsrepair.c nssearch.c nsutils.c nswalk.c nsxfeval.c \
- nsxfname.c nsxfobj.c
+ nsrepair.c nsrepair2.c nssearch.c nsutils.c nswalk.c \
+ nsxfeval.c nsxfname.c nsxfobj.c
# resources
SRCS+= rsaddr.c rscalc.c rscreate.c rsdump.c rsinfo.c \
diff --git a/usr.sbin/acpi/acpidb/acpidb.c b/usr.sbin/acpi/acpidb/acpidb.c
index 53d9db1..325dfae 100644
--- a/usr.sbin/acpi/acpidb/acpidb.c
+++ b/usr.sbin/acpi/acpidb/acpidb.c
@@ -81,7 +81,7 @@ static int aml_simulate_regcontent_read(int regtype,
static int aml_simulate_regcontent_write(int regtype,
ACPI_PHYSICAL_ADDRESS addr,
UINT8 *valuep);
-static ACPI_INTEGER aml_simulate_prompt(char *msg, ACPI_INTEGER def_val);
+static UINT64 aml_simulate_prompt(char *msg, UINT64 def_val);
static void aml_simulation_regload(const char *dumpfile);
static void aml_simulation_regdump(const char *dumpfile);
@@ -161,11 +161,11 @@ aml_simulate_regcontent_write(int regtype, ACPI_PHYSICAL_ADDRESS addr, UINT8 *va
return (aml_simulate_regcontent_add(regtype, addr, *valuep));
}
-static ACPI_INTEGER
-aml_simulate_prompt(char *msg, ACPI_INTEGER def_val)
+static UINT64
+aml_simulate_prompt(char *msg, UINT64 def_val)
{
char buf[16], *ep;
- ACPI_INTEGER val;
+ UINT64 val;
val = def_val;
printf("DEBUG");
@@ -271,12 +271,12 @@ aml_vm_space_handler(
UINT32 Function,
ACPI_PHYSICAL_ADDRESS Address,
UINT32 BitWidth,
- ACPI_INTEGER *Value,
+ UINT64 *Value,
int Prompt)
{
int state;
UINT8 val;
- ACPI_INTEGER value, i;
+ UINT64 value, i;
char msg[256];
static const char *space_names[] = {
"SYSTEM_MEMORY", "SYSTEM_IO", "PCI_CONFIG",
@@ -336,7 +336,7 @@ aml_vm_space_handler_##name ( \
UINT32 Function, \
ACPI_PHYSICAL_ADDRESS Address, \
UINT32 BitWidth, \
- ACPI_INTEGER *Value) \
+ UINT64 *Value) \
{ \
return (aml_vm_space_handler(id, Function, Address, \
BitWidth, Value, aml_debug_prompt)); \
diff --git a/usr.sbin/acpi/acpidump/Makefile b/usr.sbin/acpi/acpidump/Makefile
index 21a4140..e004500 100644
--- a/usr.sbin/acpi/acpidump/Makefile
+++ b/usr.sbin/acpi/acpidump/Makefile
@@ -3,6 +3,5 @@
PROG= acpidump
MAN= acpidump.8
SRCS= acpi.c acpi_user.c acpidump.c
-WARNS?= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/acpi/iasl/Makefile b/usr.sbin/acpi/iasl/Makefile
index 551bfc6..130c39e 100644
--- a/usr.sbin/acpi/iasl/Makefile
+++ b/usr.sbin/acpi/iasl/Makefile
@@ -5,7 +5,8 @@ SRCS= adfile.c adisasm.c adwalk.c
SRCS+= osunixxf.c
# common
-SRCS+= dmrestag.c dmtable.c dmtbdump.c dmtbinfo.c getopt.c
+SRCS+= dmextern.c dmrestag.c dmtable.c dmtbdump.c dmtbinfo.c \
+ getopt.c
# compiler
SRCS+= aslanalyze.c aslcodegen.c aslcompile.c aslcompiler.y.h \
@@ -49,6 +50,8 @@ SRCS+= utalloc.c utcache.c utcopy.c utdebug.c utdelete.c \
utglobal.c utinit.c utlock.c utmath.c utmisc.c \
utmutex.c utobject.c utresrc.c utstate.c utxface.c
+WARNS?= 2
+
MAN= iasl.8
CFLAGS+= -DACPI_ASL_COMPILER -I.
diff --git a/usr.sbin/adduser/adduser.sh b/usr.sbin/adduser/adduser.sh
index 3d1d6f8..8e05f33 100644
--- a/usr.sbin/adduser/adduser.sh
+++ b/usr.sbin/adduser/adduser.sh
@@ -28,20 +28,20 @@
#
# err msg
-# Display $msg on stderr, unless we're being quiet.
-#
+# Display $msg on stderr, unless we're being quiet.
+#
err() {
if [ -z "$quietflag" ]; then
- echo 1>&2 ${THISCMD}: ERROR: $*
+ echo 1>&2 ${THISCMD}: ERROR: $*
fi
}
# info msg
-# Display $msg on stdout, unless we're being quiet.
-#
+# Display $msg on stdout, unless we're being quiet.
+#
info() {
if [ -z "$quietflag" ]; then
- echo ${THISCMD}: INFO: $*
+ echo ${THISCMD}: INFO: $*
fi
}
@@ -50,7 +50,7 @@ info() {
# is not, output the value of the next higher uid that is available.
# If a uid is not specified, output the first available uid, as indicated
# by pw(8).
-#
+#
get_nextuid () {
_uid=$1
_nextuid=
@@ -163,8 +163,7 @@ fullpath_from_shell() {
# the path is invalid or it is not executable it
# will emit an informational message saying so.
#
-shell_exists()
-{
+shell_exists() {
_sh="$1"
_shellchk="${GREPCMD} '^$_sh$' ${ETCSHELLS} > /dev/null 2>&1"
@@ -647,7 +646,6 @@ input_from_file() {
# the user database.
#
input_interactive() {
-
_disable=
_pass=
_passconfirm=
@@ -887,7 +885,7 @@ defaultshell="${DEFAULTSHELL}"
defaultHomePerm=
# Make sure the user running this program is root. This isn't a security
-# measure as much as it is a usefull method of reminding the user to
+# measure as much as it is a useful method of reminding the user to
# 'su -' before he/she wastes time entering data that won't be saved.
#
procowner=${procowner:-`/usr/bin/id -u`}
diff --git a/usr.sbin/amd/Makefile.inc b/usr.sbin/amd/Makefile.inc
index c8451f6..673edc1 100644
--- a/usr.sbin/amd/Makefile.inc
+++ b/usr.sbin/amd/Makefile.inc
@@ -40,6 +40,8 @@ RPCCOM= rpcgen
MOUNT_X= ${DESTDIR}/usr/include/rpcsvc/mount.x
NFS_PROT_X= ${DESTDIR}/usr/include/rpcsvc/nfs_prot.x
+WARNS?= 1
+
.if exists(${.CURDIR}/../../Makefile.inc)
.include "${.CURDIR}/../../Makefile.inc"
.endif
diff --git a/usr.sbin/ancontrol/ancontrol.c b/usr.sbin/ancontrol/ancontrol.c
index 08d13d3..008970d 100644
--- a/usr.sbin/ancontrol/ancontrol.c
+++ b/usr.sbin/ancontrol/ancontrol.c
@@ -1327,8 +1327,8 @@ an_setkeys(const char *iface, const char *key, int keytype)
}
}
-static void an_readkeyinfo(iface)
- const char *iface;
+static void
+an_readkeyinfo(const char *iface)
{
struct an_req areq;
struct an_ltv_genconfig *cfg;
diff --git a/usr.sbin/apm/Makefile b/usr.sbin/apm/Makefile
index 043c3c7..08ed25f 100644
--- a/usr.sbin/apm/Makefile
+++ b/usr.sbin/apm/Makefile
@@ -3,7 +3,6 @@
PROG= apm
MAN= apm.8
MLINKS= apm.8 apmconf.8
-MANSUBDIR= /i386
-WARNS?= 6
+MANSUBDIR= /${MACHINE_ARCH}
.include <bsd.prog.mk>
diff --git a/usr.sbin/apm/apm.8 b/usr.sbin/apm/apm.8
index 1e36f63..3e039b0 100644
--- a/usr.sbin/apm/apm.8
+++ b/usr.sbin/apm/apm.8
@@ -7,15 +7,15 @@
.\" these terms are retained. Under no circumstances is the author
.\" responsible for the proper functioning of this software, nor does
.\" the author assume any responsibility for damages incurred with its
+.\" use.
.\"
.\" $FreeBSD$
.\"
-.\" use.
-.Dd November 1, 1994
+.Dd December 22, 2009
.Dt APM 8 i386
.Os
.Sh NAME
-.Nm apm , zzz
+.Nm apm
.Nd control the APM BIOS and display its information
.Sh SYNOPSIS
.Nm
@@ -24,27 +24,14 @@
.Op Fl e Ar enable
.Op Fl h Ar enable
.Op Fl r Ar delta
-.Pp
-.Nm zzz
.Sh DESCRIPTION
The
.Nm
utility
controls the Intel / Microsoft APM (Advanced Power Management) BIOS and
displays the current status of APM on laptop PCs.
-The
-.Nm zzz
-utility suspends the system by controlling APM.
.Pp
-The following options are available for
-.Nm
-(no options are available for
-.Nm zzz ) .
-If no options are specified,
-.Nm
-displays information and current status of APM in verbose mode.
-If multiple display options are given, the values are displayed one
-per line in the order given here.
+The options are as follows:
.Bl -tag -width indent
.It Fl a
Display the current AC-line status as an integer value.
@@ -126,9 +113,15 @@ output of
tells what your laptop claims to support.
.It Fl z
Suspend the system.
-It is equivalent to
-.Nm zzz .
+It is used by
+.Xr zzz 8 .
.El
+.Pp
+If no options are specified,
+.Nm
+displays information and current status of APM in verbose mode.
+If multiple display options are given, the values are displayed one
+per line in the order given here.
.Sh NOTES
.Xr apmconf 8
has been merged in
@@ -137,7 +130,8 @@ and thus
.Nm
replaces all of its functionality.
.Sh SEE ALSO
-.Xr apm 4
+.Xr apm 4 ,
+.Xr zzz 8
.Sh AUTHORS
.An Tatsumi Hosokawa Aq hosokawa@jp.FreeBSD.org
.Sh BUGS
diff --git a/usr.sbin/apm/apm.c b/usr.sbin/apm/apm.c
index 56432a4..a60f821 100644
--- a/usr.sbin/apm/apm.c
+++ b/usr.sbin/apm/apm.c
@@ -1,5 +1,5 @@
/*
- * apm / zzz APM BIOS utility for FreeBSD
+ * APM BIOS utility for FreeBSD
*
* Copyright (C) 1994-1996 by Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org>
*
@@ -43,10 +43,9 @@ int cmos_wall = 0; /* True when wall time is in cmos clock, else UTC */
static void
usage(void)
{
- fprintf(stderr, "%s\n%s\n",
+ fprintf(stderr,
"usage: apm [-ablstzZ] [-d enable ] [ -e enable ] "
- "[ -h enable ] [-r delta]",
- " zzz");
+ "[ -h enable ] [-r delta]\n");
exit(1);
}
@@ -397,11 +396,6 @@ main(int argc, char *argv[])
else
cmdname = argv[0];
- if (strcmp(cmdname, "zzz") == 0) {
- dosleep = 1;
- all_info = 0;
- goto finish_option;
- }
while ((c = getopt(argc, argv, "abe:h:lRr:stzd:Z")) != -1) {
switch (c) {
case 'a':
@@ -457,7 +451,6 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
}
-finish_option:
if (haltcpu != -1 || enable != -1 || display != -1 || delta || dosleep
|| standby) {
fd = open(APMDEV, O_RDWR);
diff --git a/usr.sbin/apmd/Makefile b/usr.sbin/apmd/Makefile
index 7e81b35..5ccf7e6 100644
--- a/usr.sbin/apmd/Makefile
+++ b/usr.sbin/apmd/Makefile
@@ -5,6 +5,8 @@ MAN= apmd.8
MANSUBDIR= /i386
SRCS= apmd.c apmdlex.l apmdparse.y y.tab.h
+WARNS?= 0
+
DPADD= ${LIBL}
LDADD= -ll
diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c
index 8a3410f..a0e228c 100644
--- a/usr.sbin/arp/arp.c
+++ b/usr.sbin/arp/arp.c
@@ -101,7 +101,8 @@ static int valid_type(int type);
static int nflag; /* no reverse dns lookups */
static char *rifname;
-static int expire_time, flags, doing_proxy, proxy_only;
+static time_t expire_time;
+static int flags, doing_proxy, proxy_only;
/* which function we're supposed to do */
#define F_GET 1
@@ -326,7 +327,6 @@ set(int argc, char **argv)
doing_proxy = 1;
if (argc && strncmp(argv[1], "only", 3) == 0) {
proxy_only = 1;
- dst->sin_other = SIN_PROXY;
argc--; argv++;
}
} else if (strncmp(argv[0], "blackhole", 9) == 0) {
@@ -365,33 +365,30 @@ set(int argc, char **argv)
sdl_m.sdl_alen = ETHER_ADDR_LEN;
}
}
- for (;;) { /* try at most twice */
- rtm = rtmsg(RTM_GET, dst, &sdl_m);
- if (rtm == NULL) {
- warn("%s", host);
- return (1);
- }
- addr = (struct sockaddr_inarp *)(rtm + 1);
- sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr);
- if (addr->sin_addr.s_addr != dst->sin_addr.s_addr)
- break;
- if (sdl->sdl_family == AF_LINK &&
- !(rtm->rtm_flags & RTF_GATEWAY) &&
- valid_type(sdl->sdl_type) )
- break;
- if (doing_proxy == 0) {
- printf("set: can only proxy for %s\n", host);
- return (1);
- }
- if (dst->sin_other & SIN_PROXY) {
- printf("set: proxy entry exists for non 802 device\n");
- return (1);
- }
- dst->sin_other = SIN_PROXY;
- proxy_only = 1;
+
+ /*
+ * In the case a proxy-arp entry is being added for
+ * a remote end point, the RTF_ANNOUNCE flag in the
+ * RTM_GET command is an indication to the kernel
+ * routing code that the interface associated with
+ * the prefix route covering the local end of the
+ * PPP link should be returned, on which ARP applies.
+ */
+ rtm = rtmsg(RTM_GET, dst, &sdl_m);
+ if (rtm == NULL) {
+ warn("%s", host);
+ return (1);
+ }
+ addr = (struct sockaddr_inarp *)(rtm + 1);
+ sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr);
+ if (addr->sin_addr.s_addr == dst->sin_addr.s_addr) {
+ printf("set: proxy entry exists for non 802 device\n");
+ return (1);
}
- if (sdl->sdl_family != AF_LINK) {
+ if ((sdl->sdl_family != AF_LINK) ||
+ (rtm->rtm_flags & RTF_GATEWAY) ||
+ !valid_type(sdl->sdl_type)) {
printf("cannot intuit interface index and type for %s\n", host);
return (1);
}
@@ -436,7 +433,11 @@ delete(char *host, int do_proxy)
dst = getaddr(host);
if (dst == NULL)
return (1);
- dst->sin_other = do_proxy;
+
+ /*
+ * Perform a regular entry delete first.
+ */
+ flags &= ~RTF_ANNOUNCE;
/*
* setup the data structure to notify the kernel
@@ -471,11 +472,16 @@ delete(char *host, int do_proxy)
break;
}
- if (dst->sin_other & SIN_PROXY) {
+ /*
+ * Regualar entry delete failed, now check if there
+ * is a proxy-arp entry to remove.
+ */
+ if (flags & RTF_ANNOUNCE) {
fprintf(stderr, "delete: cannot locate %s\n",host);
return (1);
}
- dst->sin_other = SIN_PROXY;
+
+ flags |= RTF_ANNOUNCE;
}
rtm->rtm_flags |= RTF_LLDATA;
if (rtmsg(RTM_DELETE, dst, NULL) != NULL) {
@@ -485,6 +491,7 @@ delete(char *host, int do_proxy)
return (1);
}
+
/*
* Search the arp table and do some action on matching entries
*/
@@ -493,7 +500,7 @@ search(u_long addr, action_fn *action)
{
int mib[6];
size_t needed;
- char *lim, *buf, *newbuf, *next;
+ char *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin2;
struct sockaddr_dl *sdl;
@@ -516,13 +523,9 @@ search(u_long addr, action_fn *action)
return 0;
buf = NULL;
for (;;) {
- newbuf = realloc(buf, needed);
- if (newbuf == NULL) {
- if (buf != NULL)
- free(buf);
+ buf = reallocf(buf, needed);
+ if (buf == NULL)
errx(1, "could not reallocate memory");
- }
- buf = newbuf;
st = sysctl(mib, 6, buf, &needed, NULL, 0);
if (st == 0 || errno != ENOMEM)
break;
@@ -592,6 +595,15 @@ print_entry(struct sockaddr_dl *sdl,
printf(" on %s", ifname);
if (rtm->rtm_rmx.rmx_expire == 0)
printf(" permanent");
+ else {
+ static struct timeval tv;
+ if (tv.tv_sec == 0)
+ gettimeofday(&tv, 0);
+ if ((expire_time = rtm->rtm_rmx.rmx_expire - tv.tv_sec) > 0)
+ printf(" expires in %d seconds", (int)expire_time);
+ else
+ printf(" expired");
+ }
if (addr->sin_other & SIN_PROXY)
printf(" published (proxy only)");
if (rtm->rtm_flags & RTF_ANNOUNCE)
diff --git a/usr.sbin/asf/Makefile b/usr.sbin/asf/Makefile
index b4b7af3..0db69e8 100644
--- a/usr.sbin/asf/Makefile
+++ b/usr.sbin/asf/Makefile
@@ -7,6 +7,4 @@ MAN= asf.8
DPADD= ${LIBKVM}
LDADD= -lkvm
-WARNS?= 4
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/asf/asf_kld.c b/usr.sbin/asf/asf_kld.c
index 1d6a2b7..f0bd699 100644
--- a/usr.sbin/asf/asf_kld.c
+++ b/usr.sbin/asf/asf_kld.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
* Works with a live kernel only.
*/
void
-asf_kld()
+asf_kld(void)
{
struct kld_file_stat kfs;
int fid = 0; /* indicates the beginning of the linker file list */
diff --git a/usr.sbin/audit/Makefile b/usr.sbin/audit/Makefile
index 9f31741..a3f7fbf 100644
--- a/usr.sbin/audit/Makefile
+++ b/usr.sbin/audit/Makefile
@@ -13,4 +13,6 @@ MAN= audit.8
DPADD= ${LIBBSM}
LDADD= -lbsm
+WARNS?= 5
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/auditd/Makefile b/usr.sbin/auditd/Makefile
index 839458d..47ffd0b 100644
--- a/usr.sbin/auditd/Makefile
+++ b/usr.sbin/auditd/Makefile
@@ -11,7 +11,9 @@ PROG= auditd
SRCS= auditd.c audit_warn.c auditd_fbsd.c
MAN= auditd.8
-DPADD= ${LIBBSM} ${LIBAUDITD}
-LDADD= -lbsm -lauditd
+DPADD= ${LIBAUDITD} ${LIBBSM}
+LDADD= -lauditd -lbsm
+
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/usr.sbin/auditreduce/Makefile b/usr.sbin/auditreduce/Makefile
index 73b355d..7dc9553 100644
--- a/usr.sbin/auditreduce/Makefile
+++ b/usr.sbin/auditreduce/Makefile
@@ -13,4 +13,6 @@ MAN= auditreduce.1
DPADD= ${LIBBSM}
LDADD= -lbsm
+WARNS?= 3
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/authpf/Makefile b/usr.sbin/authpf/Makefile
index b4c9b4f..0a24b8e 100644
--- a/usr.sbin/authpf/Makefile
+++ b/usr.sbin/authpf/Makefile
@@ -19,4 +19,6 @@ CFLAGS+= -DENABLE_ALTQ
LDADD+= -lm -lmd -lutil
DPADD+= ${LIBM} ${LIBMD} ${LIBUTIL}
+WARNS?= 3
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/boot0cfg/Makefile b/usr.sbin/boot0cfg/Makefile
index dc02cad..9b46701 100644
--- a/usr.sbin/boot0cfg/Makefile
+++ b/usr.sbin/boot0cfg/Makefile
@@ -3,9 +3,7 @@
PROG= boot0cfg
MAN= boot0cfg.8
-WARNS?= 2
-
-DPADD= ${LIBGEOM}
-LDADD= -lgeom
+DPADD= ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF}
+LDADD= -lgeom -lbsdxml -lsbuf
.include <bsd.prog.mk>
diff --git a/usr.sbin/bootparamd/Makefile.inc b/usr.sbin/bootparamd/Makefile.inc
index 1e4d46f..5c01215 100644
--- a/usr.sbin/bootparamd/Makefile.inc
+++ b/usr.sbin/bootparamd/Makefile.inc
@@ -2,3 +2,5 @@
# $FreeBSD$
BINDIR?= /usr/sbin
+
+WARNS?= 2
diff --git a/usr.sbin/bootparamd/bootparamd/bootparamd.c b/usr.sbin/bootparamd/bootparamd/bootparamd.c
index c638730..5c1d264 100644
--- a/usr.sbin/bootparamd/bootparamd/bootparamd.c
+++ b/usr.sbin/bootparamd/bootparamd/bootparamd.c
@@ -191,9 +191,9 @@ int blen;
{
FILE *bpf;
char *where;
+#ifdef YP
static char *result;
int resultlen;
-#ifdef YP
static char *yp_domain;
#endif
@@ -294,9 +294,9 @@ int len;
int ch, pch;
FILE *bpf;
int res = 0;
+#ifdef YP
static char *result;
int resultlen;
-#ifdef YP
static char *yp_domain;
#endif
diff --git a/usr.sbin/bsnmpd/bsnmpd/Makefile b/usr.sbin/bsnmpd/bsnmpd/Makefile
index 9fbf366..e74f675 100644
--- a/usr.sbin/bsnmpd/bsnmpd/Makefile
+++ b/usr.sbin/bsnmpd/bsnmpd/Makefile
@@ -14,7 +14,6 @@ XSYM= snmpMIB begemotSnmpdModuleTable begemotSnmpd begemotTrapSinkTable \
freeBSDVersion
CLEANFILES= oid.h tree.c tree.h
MAN= bsnmpd.1 snmpmod.3
-WARNS?= 6
NO_WERROR=
FILESGROUPS= BMIBS DEFS
diff --git a/usr.sbin/bsnmpd/gensnmptree/Makefile b/usr.sbin/bsnmpd/gensnmptree/Makefile
index 11c6a3b..a92f4eb 100644
--- a/usr.sbin/bsnmpd/gensnmptree/Makefile
+++ b/usr.sbin/bsnmpd/gensnmptree/Makefile
@@ -10,4 +10,6 @@ CFLAGS+= -I${CONTRIB}/lib
CFLAGS+= -DQUADFMT='"llu"' -DQUADXFMT='"llx"' -DHAVE_STDINT_H
CFLAGS+= -DHAVE_INTTYPES_H
+WARNS?= 5
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c
index 7e81436..cb38145 100644
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c
@@ -352,11 +352,11 @@ device_get_status(struct devinfo_dev *dev)
assert(dev != NULL);
switch (dev->dd_state) {
- case DIS_ALIVE: /* probe succeeded */
- case DIS_NOTPRESENT: /* not probed or probe failed */
+ case DS_ALIVE: /* probe succeeded */
+ case DS_NOTPRESENT: /* not probed or probe failed */
return (DS_DOWN);
- case DIS_ATTACHED: /* attach method called */
- case DIS_BUSY: /* device is open */
+ case DS_ATTACHED: /* attach method called */
+ case DS_BUSY: /* device is open */
return (DS_RUNNING);
default:
return (DS_UNKNOWN);
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c
index 945a9bd..f86334e 100644
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c
@@ -41,15 +41,12 @@
#include <stdint.h>
#include <string.h>
#include <syslog.h>
-#include <utmp.h>
+#include <utmpx.h>
#include "hostres_snmp.h"
#include "hostres_oid.h"
#include "hostres_tree.h"
-/* file pointer to keep an open instance of utmp */
-static FILE *utmp_fp;
-
/* boot timestamp in centi-seconds */
static uint64_t kernel_boot;
@@ -70,9 +67,6 @@ fini_scalars(void)
{
free(boot_line);
-
- if (utmp_fp != NULL)
- (void)fclose(utmp_fp);
}
/**
@@ -220,30 +214,15 @@ OS_getSystemInitialLoadParameters(u_char **params)
static int
OS_getSystemNumUsers(uint32_t *nu)
{
- struct utmp utmp;
- static int first_time = 1;
-
- if (utmp_fp == NULL) {
- if (!first_time)
- return (SNMP_ERR_GENERR);
- first_time = 0;
- if ((utmp_fp = fopen(_PATH_UTMP, "r")) == NULL) {
- syslog(LOG_ERR, "fopen(%s) failed: %m", _PATH_UTMP);
- return (SNMP_ERR_GENERR);
- }
- }
-
- /* start with the begining of the utmp file */
- (void)rewind(utmp_fp);
+ struct utmpx *utmp;
+ setutxent();
*nu = 0;
- while (fread(&utmp, sizeof(utmp), 1, utmp_fp) == 1) {
- if (utmp.ut_name[0] != '\0' && utmp.ut_line[0] != '\0') {
- if (getpwnam(utmp.ut_name) == NULL)
- continue;
+ while ((utmp = getutxent()) != NULL) {
+ if (utmp->ut_type == USER_PROCESS)
(*nu)++;
- }
}
+ endutxent();
return (SNMP_ERR_NOERROR);
}
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c
index 47112da..c2a06db 100644
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c
@@ -49,7 +49,6 @@
#include <string.h>
#include <syslog.h>
#include <unistd.h>
-#include <utmp.h>
#include "hostres_snmp.h"
#include "hostres_oid.h"
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/Makefile b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile
index 7472464..92b0a4ba 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/Makefile
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile
@@ -4,7 +4,6 @@
MOD= pf
SRCS= pf_snmp.c
-WARNS?= 6
XSYM= begemotPf
DEFS= ${MOD}_tree.def
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
index 919e5d4..4e554c0 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
@@ -1104,7 +1104,7 @@ pft_refresh(void)
}
for (i = 0; i < numtbls; i++) {
- e = malloc(sizeof(struct pfr_tstats));
+ e = malloc(sizeof(struct pft_entry));
if (e == NULL)
goto err1;
e->index = i + 1;
diff --git a/usr.sbin/btxld/Makefile b/usr.sbin/btxld/Makefile
index 6ca452e..32cf99d 100644
--- a/usr.sbin/btxld/Makefile
+++ b/usr.sbin/btxld/Makefile
@@ -4,6 +4,4 @@ PROG= btxld
MAN= btxld.8
SRCS= btxld.c elfh.c
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/burncd/Makefile b/usr.sbin/burncd/Makefile
index bd4f285..11e07c7 100644
--- a/usr.sbin/burncd/Makefile
+++ b/usr.sbin/burncd/Makefile
@@ -3,6 +3,4 @@
PROG= burncd
MAN= burncd.8
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/burncd/burncd.8 b/usr.sbin/burncd/burncd.8
index 18c1bc4..2501e72 100644
--- a/usr.sbin/burncd/burncd.8
+++ b/usr.sbin/burncd/burncd.8
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 2, 2005
+.Dd December 21, 2009
.Os
.Dt BURNCD 8
.Sh NAME
@@ -158,7 +158,11 @@ refers to stdin, and can only be used once.
.Sh ENVIRONMENT
The following environment variables affect the execution of
.Nm :
-.Bl -tag -width ".Ev CDROM"
+.Bl -tag -width ".Ev BURNCD_SPEED"
+.It Ev BURNCD_SPEED
+The write speed to use if one is not specified with the
+.Fl s
+flag.
.It Ev CDROM
The CD device to use if one is not specified with the
.Fl f
diff --git a/usr.sbin/burncd/burncd.c b/usr.sbin/burncd/burncd.c
index c4d1648..43a0a09 100644
--- a/usr.sbin/burncd/burncd.c
+++ b/usr.sbin/burncd/burncd.c
@@ -80,11 +80,13 @@ main(int argc, char **argv)
int dao = 0, eject = 0, fixate = 0, list = 0, multi = 0, preemp = 0;
int nogap = 0, speed = 4 * 177, test_write = 0, force = 0;
int block_size = 0, block_type = 0, cdopen = 0, dvdrw = 0;
- const char *dev;
+ const char *dev, *env_speed;
if ((dev = getenv("CDROM")) == NULL)
dev = "/dev/acd0";
+ env_speed = getenv("BURNCD_SPEED");
+
while ((ch = getopt(argc, argv, "def:Flmnpqs:tv")) != -1) {
switch (ch) {
case 'd':
@@ -124,12 +126,7 @@ main(int argc, char **argv)
break;
case 's':
- if (strcasecmp("max", optarg) == 0)
- speed = CDR_MAX_SPEED;
- else
- speed = atoi(optarg) * 177;
- if (speed <= 0)
- errx(EX_USAGE, "Invalid speed: %s", optarg);
+ env_speed = optarg;
break;
case 't':
@@ -147,6 +144,15 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
+ if (env_speed == NULL)
+ ;
+ else if (strcasecmp("max", env_speed) == 0)
+ speed = CDR_MAX_SPEED;
+ else
+ speed = atoi(env_speed) * 177;
+ if (speed <= 0)
+ errx(EX_USAGE, "Invalid speed: %s", env_speed);
+
if (argc == 0)
usage();
diff --git a/usr.sbin/cdcontrol/Makefile b/usr.sbin/cdcontrol/Makefile
index 40addad..a505e3a 100644
--- a/usr.sbin/cdcontrol/Makefile
+++ b/usr.sbin/cdcontrol/Makefile
@@ -2,8 +2,6 @@
PROG= cdcontrol
-WARNS?= 2
-
DPADD= ${LIBEDIT} ${LIBTERMCAP}
LDADD= -ledit -ltermcap
diff --git a/usr.sbin/cdcontrol/cdcontrol.c b/usr.sbin/cdcontrol/cdcontrol.c
index ede5904..526f599 100644
--- a/usr.sbin/cdcontrol/cdcontrol.c
+++ b/usr.sbin/cdcontrol/cdcontrol.c
@@ -152,7 +152,7 @@ __const char *strstatus(int);
static u_int dbprog_discid(void);
__const char *cdcontrol_prompt(void);
-void help ()
+void help (void)
{
struct cmdtab *c;
const char *s;
@@ -178,7 +178,7 @@ void help ()
printf ("\tThe plain target address is taken as a synonym for play.\n");
}
-void usage ()
+void usage (void)
{
fprintf (stderr, "usage: cdcontrol [-sv] [-f device] [command ...]\n");
exit (1);
@@ -241,7 +241,7 @@ int main (int argc, char **argv)
if (argc > 0) {
char buf[80], *p;
- int len;
+ int len, rc;
for (p=buf; argc-->0; ++argv) {
len = strlen (*argv);
@@ -257,7 +257,11 @@ int main (int argc, char **argv)
}
*p = 0;
arg = parse (buf, &cmd);
- return (run (cmd, arg));
+ rc = run (cmd, arg);
+ if (rc < 0 && verbose)
+ warn(NULL);
+
+ return (rc);
}
if (verbose == 1)
@@ -409,8 +413,11 @@ int run (int cmd, char *arg)
if (fd < 0 && !open_cd ())
return (0);
- if (! strlen (arg))
- return pstatus ("volume");
+ if (! strlen (arg)) {
+ char volume[] = "volume";
+
+ return pstatus (volume);
+ }
if (! strncasecmp (arg, "left", strlen(arg)))
return ioctl (fd, CDIOCSETLEFT);
@@ -895,7 +902,7 @@ dbprog_sum(int n)
* The integer disc ID.
*/
static u_int
-dbprog_discid()
+dbprog_discid(void)
{
struct ioc_toc_header h;
int rc;
@@ -926,7 +933,7 @@ dbprog_discid()
return((n % 0xff) << 24 | t << 8 | ntr);
}
-int cdid ()
+int cdid (void)
{
u_int id;
@@ -1126,7 +1133,7 @@ int status (int *trk, int *min, int *sec, int *frame)
}
const char *
-cdcontrol_prompt()
+cdcontrol_prompt(void)
{
return ("cdcontrol> ");
}
@@ -1245,7 +1252,7 @@ char *parse (char *buf, int *cmd)
return p;
}
-int open_cd ()
+int open_cd (void)
{
char devbuf[MAXPATHLEN];
const char *dev;
diff --git a/usr.sbin/chkgrp/Makefile b/usr.sbin/chkgrp/Makefile
index 1c52f46..a7bfc54 100644
--- a/usr.sbin/chkgrp/Makefile
+++ b/usr.sbin/chkgrp/Makefile
@@ -3,6 +3,4 @@
PROG= chkgrp
MAN= chkgrp.8
-WARNS?= 2
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/chown/Makefile b/usr.sbin/chown/Makefile
index 63c5a22..97972e5 100644
--- a/usr.sbin/chown/Makefile
+++ b/usr.sbin/chown/Makefile
@@ -5,6 +5,4 @@ PROG= chown
LINKS= ${BINDIR}/chown /usr/bin/chgrp
MAN= chgrp.1 chown.8
-WARNS?= 5
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/chown/chgrp.1 b/usr.sbin/chown/chgrp.1
index 71b6806..8a4c271 100644
--- a/usr.sbin/chown/chgrp.1
+++ b/usr.sbin/chown/chgrp.1
@@ -31,7 +31,7 @@
.\" @(#)chgrp.1 8.3 (Berkeley) 3/31/94
.\" $FreeBSD$
.\"
-.Dd April 25, 2003
+.Dd February 21, 2010
.Dt CHGRP 1
.Os
.Sh NAME
@@ -39,7 +39,7 @@
.Nd change group
.Sh SYNOPSIS
.Nm
-.Op Fl fhv
+.Op Fl fhvx
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
@@ -89,6 +89,8 @@ If the
flag is specified more than once,
.Nm
will print the filename, followed by the old and new numeric group ID.
+.It Fl x
+File system mount points are not traversed.
.El
.Pp
The
@@ -125,7 +127,9 @@ In previous versions of this system, symbolic links did not have groups.
.Pp
The
.Fl v
-option is non-standard and its use in scripts is not recommended.
+and
+.Fl x
+options are non-standard and their use in scripts is not recommended.
.Sh SEE ALSO
.Xr chown 2 ,
.Xr fts 3 ,
diff --git a/usr.sbin/chown/chown.8 b/usr.sbin/chown/chown.8
index f617f73..b5882a3 100644
--- a/usr.sbin/chown/chown.8
+++ b/usr.sbin/chown/chown.8
@@ -28,7 +28,7 @@
.\" @(#)chown.8 8.3 (Berkeley) 3/31/94
.\" $FreeBSD$
.\"
-.Dd April 25, 2003
+.Dd February 21, 2010
.Dt CHOWN 8
.Os
.Sh NAME
@@ -36,7 +36,7 @@
.Nd change file owner and group
.Sh SYNOPSIS
.Nm
-.Op Fl fhv
+.Op Fl fhvx
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
@@ -44,7 +44,7 @@
.Ar owner Ns Op : Ns Ar group
.Ar
.Nm
-.Op Fl fhv
+.Op Fl fhvx
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
@@ -97,6 +97,8 @@ If the
flag is specified more than once,
.Nm
will print the filename, followed by the old and new numeric user/group ID.
+.It Fl x
+File system mount points are not traversed.
.El
.Pp
The
@@ -146,7 +148,9 @@ owners.
.Pp
The
.Fl v
-option is non-standard and its use in scripts is not recommended.
+and
+.Fl x
+options are non-standard and their use in scripts is not recommended.
.Sh SEE ALSO
.Xr chgrp 1 ,
.Xr find 1 ,
diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c
index b79deca..7a22292 100644
--- a/usr.sbin/chown/chown.c
+++ b/usr.sbin/chown/chown.c
@@ -73,14 +73,14 @@ main(int argc, char **argv)
{
FTS *ftsp;
FTSENT *p;
- int Hflag, Lflag, Rflag, fflag, hflag, vflag;
+ int Hflag, Lflag, Rflag, fflag, hflag, vflag, xflag;
int ch, fts_options, rval;
char *cp;
ischown = (strcmp(basename(argv[0]), "chown") == 0);
- Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
- while ((ch = getopt(argc, argv, "HLPRfhv")) != -1)
+ Hflag = Lflag = Rflag = fflag = hflag = vflag = xflag = 0;
+ while ((ch = getopt(argc, argv, "HLPRfhvx")) != -1)
switch (ch) {
case 'H':
Hflag = 1;
@@ -105,6 +105,9 @@ main(int argc, char **argv)
case 'v':
vflag++;
break;
+ case 'x':
+ xflag = 1;
+ break;
case '?':
default:
usage();
@@ -128,6 +131,8 @@ main(int argc, char **argv)
}
} else
fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL;
+ if (xflag)
+ fts_options |= FTS_XDEV;
uid = (uid_t)-1;
gid = (gid_t)-1;
@@ -301,11 +306,11 @@ usage(void)
if (ischown)
(void)fprintf(stderr, "%s\n%s\n",
- "usage: chown [-fhv] [-R [-H | -L | -P]] owner[:group]"
+ "usage: chown [-fhvx] [-R [-H | -L | -P]] owner[:group]"
" file ...",
- " chown [-fhv] [-R [-H | -L | -P]] :group file ...");
+ " chown [-fhvx] [-R [-H | -L | -P]] :group file ...");
else
(void)fprintf(stderr, "%s\n",
- "usage: chgrp [-fhv] [-R [-H | -L | -P]] group file ...");
+ "usage: chgrp [-fhvx] [-R [-H | -L | -P]] group file ...");
exit(1);
}
diff --git a/usr.sbin/chroot/Makefile b/usr.sbin/chroot/Makefile
index d28de66..652de79 100644
--- a/usr.sbin/chroot/Makefile
+++ b/usr.sbin/chroot/Makefile
@@ -4,6 +4,4 @@
PROG= chroot
MAN= chroot.8
-WARNS?= 2
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/chroot/chroot.c b/usr.sbin/chroot/chroot.c
index cc924a0..a0122f7 100644
--- a/usr.sbin/chroot/chroot.c
+++ b/usr.sbin/chroot/chroot.c
@@ -61,9 +61,7 @@ char *group; /* group to switch to ... */
char *grouplist; /* group list to switch to ... */
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(int argc, char *argv[])
{
struct group *gp;
struct passwd *pw;
@@ -179,7 +177,7 @@ main(argc, argv)
}
static void
-usage()
+usage(void)
{
(void)fprintf(stderr, "usage: chroot [-g group] [-G group,group,...] "
"[-u user] newroot [command]\n");
diff --git a/usr.sbin/clear_locks/Makefile b/usr.sbin/clear_locks/Makefile
index dace0e1..00ff3ce 100644
--- a/usr.sbin/clear_locks/Makefile
+++ b/usr.sbin/clear_locks/Makefile
@@ -4,6 +4,5 @@ PROG= clear_locks
MAN= clear_locks.8
DPADD= ${LIBRPCSVC}
LDADD= -lrpcsvc
-WARNS= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/config/Makefile b/usr.sbin/config/Makefile
index ac82881..6faf847 100644
--- a/usr.sbin/config/Makefile
+++ b/usr.sbin/config/Makefile
@@ -9,7 +9,6 @@ SRCS= config.y main.c lang.l mkmakefile.c mkheaders.c \
kernconf.c: kernconf.tmpl
file2c 'char kernconfstr[] = {' ',0};' < ${.CURDIR}/kernconf.tmpl > kernconf.c
-WARNS?= 6
CFLAGS+= -I. -I${.CURDIR}
DPADD= ${LIBL} ${LIBSBUF}
diff --git a/usr.sbin/config/lang.l b/usr.sbin/config/lang.l
index 075f21f..c7845cb 100644
--- a/usr.sbin/config/lang.l
+++ b/usr.sbin/config/lang.l
@@ -285,7 +285,7 @@ include(const char *fname, int ateof)
* Terminate the most recent inclusion.
*/
static int
-endinclude()
+endinclude(void)
{
struct incl *in;
int ateof;
diff --git a/usr.sbin/cpucontrol/Makefile b/usr.sbin/cpucontrol/Makefile
index 00e7214..a048dd7 100644
--- a/usr.sbin/cpucontrol/Makefile
+++ b/usr.sbin/cpucontrol/Makefile
@@ -4,6 +4,4 @@ PROG= cpucontrol
MAN= cpucontrol.8
SRCS= cpucontrol.c intel.c amd.c
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/cpucontrol/cpucontrol.c b/usr.sbin/cpucontrol/cpucontrol.c
index 8b3ca1d..7193080 100644
--- a/usr.sbin/cpucontrol/cpucontrol.c
+++ b/usr.sbin/cpucontrol/cpucontrol.c
@@ -83,7 +83,7 @@ struct datadir {
const char *path;
SLIST_ENTRY(datadir) next;
};
-static SLIST_HEAD(, datadir) datadirs = SLIST_HEAD_INITIALIZER(&datadirs);
+static SLIST_HEAD(, datadir) datadirs = SLIST_HEAD_INITIALIZER(datadirs);
struct ucode_handler {
ucode_probe_t *probe;
@@ -102,7 +102,7 @@ static int do_update(const char *dev);
static void datadir_add(const char *path);
static void __dead2
-usage()
+usage(void)
{
const char *name;
diff --git a/usr.sbin/crashinfo/crashinfo.sh b/usr.sbin/crashinfo/crashinfo.sh
index cd41009..60f0360 100755
--- a/usr.sbin/crashinfo/crashinfo.sh
+++ b/usr.sbin/crashinfo/crashinfo.sh
@@ -147,6 +147,8 @@ fi
echo "Writing crash summary to $FILE."
+umask 077
+
# Simulate uname
ostype=$(echo -e printf '"%s", ostype' | gdb -x /dev/stdin -batch $KERNEL)
osrelease=$(echo -e printf '"%s", osrelease' | gdb -x /dev/stdin -batch $KERNEL)
@@ -304,3 +306,10 @@ echo "------------------------------------------------------------------------"
echo "kernel config"
echo
config -x $KERNEL
+
+echo
+echo "------------------------------------------------------------------------"
+echo "ddb capture buffer"
+echo
+
+ddb capture -M $VMCORE -N $KERNEL print
diff --git a/usr.sbin/cron/cron/Makefile b/usr.sbin/cron/cron/Makefile
index 77ca47a..d9a1d24 100644
--- a/usr.sbin/cron/cron/Makefile
+++ b/usr.sbin/cron/cron/Makefile
@@ -9,4 +9,6 @@ CFLAGS+= -DLOGIN_CAP -DPAM
DPADD= ${LIBCRON} ${LIBPAM} ${LIBUTIL}
LDADD= ${LIBCRON} ${MINUSLPAM} -lutil
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/cron/cron/cron.c b/usr.sbin/cron/cron/cron.c
index 101989c..52cdcc8 100644
--- a/usr.sbin/cron/cron/cron.c
+++ b/usr.sbin/cron/cron/cron.c
@@ -24,6 +24,7 @@ static const char rcsid[] =
#include "cron.h"
+#include <sys/mman.h>
#include <sys/signal.h>
#if SYS_TIME_H
# include <sys/time.h>
@@ -134,6 +135,9 @@ main(argc, argv)
}
}
+ if (madvise(NULL, 0, MADV_PROTECT) != 0)
+ log_it("CRON", getpid(), "WARNING", "madvise() failed");
+
pidfile_write(pfh);
database.head = NULL;
database.tail = NULL;
diff --git a/usr.sbin/crunch/Makefile.inc b/usr.sbin/crunch/Makefile.inc
index f8ffe67..36175b7 100644
--- a/usr.sbin/crunch/Makefile.inc
+++ b/usr.sbin/crunch/Makefile.inc
@@ -2,3 +2,5 @@
# modify to taste
BINDIR?= /usr/bin
+
+WARNS?= 2
diff --git a/usr.sbin/crunch/examples/really-big.conf b/usr.sbin/crunch/examples/really-big.conf
index 45a10de..ab8a939 100644
--- a/usr.sbin/crunch/examples/really-big.conf
+++ b/usr.sbin/crunch/examples/really-big.conf
@@ -27,7 +27,7 @@ progs badsect bim clri disklabel dmesg dump dumpfs fdisk fsck halt
progs ifconfig init mknod modload modunload mount mount_isofs
progs mount_lofs mount_msdosfs mount_portalfs mountd
progs newfs nfsd nfsiod ping quotacheck reboot restore route routed savecore
-progs shutdown slattach swapon ttyflags tunefs umount
+progs shutdown swapon ttyflags tunefs umount
# shell scripts: fastboot
ln dump rdump
@@ -71,7 +71,7 @@ progs ac accton amd arp bad144 catman chown chroot config config.new cron
progs dev_mkdb diskpart edquota flcopy gettable grfinfo hilinfo htable inetd
progs iostat iteconfig kvm_mkdb mtree named portmap pppd
progs pstat pwd_mkdb quot quotaon rarpd rbootd repquota rmt rpc.bootparamd
-progs rwhod sa sliplogin slstats spray sysctl syslogd tcpdump
+progs rwhod sa spray sysctl syslogd tcpdump
progs traceroute trpt trsp update vipw vnconfig ypbind yppoll ypset
special amd srcdir /usr/src/usr.sbin/amd/amd
diff --git a/usr.sbin/ctm/ctm/Makefile b/usr.sbin/ctm/ctm/Makefile
index c0cf79a..cc2c9b9 100644
--- a/usr.sbin/ctm/ctm/Makefile
+++ b/usr.sbin/ctm/ctm/Makefile
@@ -17,6 +17,8 @@ NOTYET= ctm_ed.c
LDADD= -lmd
DPADD= ${LIBMD}
+WARNS?= 2
+
.if exists(${.CURDIR}/../../Makefile.inc)
.include "${.CURDIR}/../../Makefile.inc"
.endif
diff --git a/usr.sbin/ctm/ctm_dequeue/Makefile b/usr.sbin/ctm/ctm_dequeue/Makefile
index 07a234f..18dd525 100644
--- a/usr.sbin/ctm/ctm_dequeue/Makefile
+++ b/usr.sbin/ctm/ctm_dequeue/Makefile
@@ -8,4 +8,6 @@ SRCS= ctm_dequeue.c error.c
CFLAGS+= -I${.CURDIR}/../ctm_rmail
+WARNS?= 1
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/ctm/ctm_rmail/Makefile b/usr.sbin/ctm/ctm_rmail/Makefile
index e2052b9..1278ab4 100644
--- a/usr.sbin/ctm/ctm_rmail/Makefile
+++ b/usr.sbin/ctm/ctm_rmail/Makefile
@@ -5,4 +5,6 @@ MLINKS= ctm_rmail.1 ctm_smail.1 \
ctm_rmail.1 ctm_dequeue.1
SRCS= ctm_rmail.c error.c
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/ctm/ctm_smail/Makefile b/usr.sbin/ctm/ctm_smail/Makefile
index 980e9bf..15209e4 100644
--- a/usr.sbin/ctm/ctm_smail/Makefile
+++ b/usr.sbin/ctm/ctm_smail/Makefile
@@ -8,4 +8,6 @@ SRCS= ctm_smail.c error.c
CFLAGS+= -I${.CURDIR}/../ctm_rmail
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/ctm/ctm_smail/ctm_smail.c b/usr.sbin/ctm/ctm_smail/ctm_smail.c
index a0dc03c..c90fa2f 100644
--- a/usr.sbin/ctm/ctm_smail/ctm_smail.c
+++ b/usr.sbin/ctm/ctm_smail/ctm_smail.c
@@ -29,7 +29,7 @@
#define DEF_MAX_MSG 64000 /* Default maximum mail msg minus headers. */
-#define LINE_LENGTH 76 /* Chars per encoded line. Divisible by 4. */
+#define LINE_LENGTH 72 /* Chars per encoded line. Divisible by 4. */
int chop_and_send_or_queue(FILE *dfp, char *delta, off_t ctm_size,
long max_msg_size, char *mail_alias, char *queue_dir);
diff --git a/usr.sbin/cxgbtool/Makefile b/usr.sbin/cxgbtool/Makefile
index d97c513..f8e5175 100644
--- a/usr.sbin/cxgbtool/Makefile
+++ b/usr.sbin/cxgbtool/Makefile
@@ -8,4 +8,4 @@ CFLAGS+= -DCONFIG_T3_REGS -DCHELSIO_INTERNAL
install:
-.include <bsd.prog.mk> \ No newline at end of file
+.include <bsd.prog.mk>
diff --git a/usr.sbin/cxgbtool/cxgbtool.c b/usr.sbin/cxgbtool/cxgbtool.c
index 8d7e677..28d91f9 100644
--- a/usr.sbin/cxgbtool/cxgbtool.c
+++ b/usr.sbin/cxgbtool/cxgbtool.c
@@ -85,7 +85,8 @@ struct reg_info {
static const char *progname;
-static void __attribute__((noreturn)) usage(FILE *fp)
+static void
+usage(FILE *fp)
{
fprintf(fp, "Usage: %s <interface> [operation]\n", progname);
fprintf(fp,
@@ -136,7 +137,8 @@ doit(const char *iff_name, unsigned long cmd, void *data)
return ioctl(fd, cmd, data) < 0 ? -1 : 0;
}
-static int get_int_arg(const char *s, uint32_t *valp)
+static int
+get_int_arg(const char *s, uint32_t *valp)
{
char *p;
@@ -172,11 +174,12 @@ write_reg(const char *iff_name, uint32_t addr, uint32_t val)
err(1, "register write");
}
-static int register_io(int argc, char *argv[], int start_arg,
+static int
+register_io(int argc, char *argv[], int start_arg,
const char *iff_name)
{
char *p;
- uint32_t addr, val = 0, write = 0;
+ uint32_t addr, val = 0, w = 0;
if (argc != start_arg + 1) return -1;
@@ -184,14 +187,14 @@ static int register_io(int argc, char *argv[], int start_arg,
if (p == argv[start_arg]) return -1;
if (*p == '=' && p[1]) {
val = strtoul(p + 1, &p, 0);
- write = 1;
+ w = 1;
}
if (*p) {
warnx("bad parameter \"%s\"", argv[start_arg]);
return -1;
}
- if (write)
+ if (w)
write_reg(iff_name, addr, val);
else {
val = read_reg(iff_name, addr);
@@ -200,9 +203,9 @@ static int register_io(int argc, char *argv[], int start_arg,
return 0;
}
-static int mdio_io(int argc, char *argv[], int start_arg, const char *iff_name)
+static int
+mdio_io(int argc, char *argv[], int start_arg, const char *iff_name)
{
- struct ifreq ifr;
struct ch_mii_data p;
unsigned int cmd, phy_addr, reg, mmd, val;
@@ -230,12 +233,14 @@ static int mdio_io(int argc, char *argv[], int start_arg, const char *iff_name)
return 0;
}
-static inline uint32_t xtract(uint32_t val, int shift, int len)
+static inline
+uint32_t xtract(uint32_t val, int shift, int len)
{
return (val >> shift) & ((1 << len) - 1);
}
-static int dump_block_regs(const struct reg_info *reg_array, uint32_t *regs)
+static int
+dump_block_regs(const struct reg_info *reg_array, uint32_t *regs)
{
uint32_t reg_val = 0; // silence compiler warning
@@ -254,7 +259,8 @@ static int dump_block_regs(const struct reg_info *reg_array, uint32_t *regs)
return 1;
}
-static int dump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs)
+static int
+dump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs)
{
int match = 0;
char *block_name = NULL;
@@ -292,8 +298,8 @@ static int dump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs)
}
#if defined(CONFIG_T3_REGS)
-static int dump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs,
- int is_pcie)
+static int
+dump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs, int is_pcie)
{
int match = 0;
char *block_name = NULL;
@@ -353,8 +359,9 @@ static int dump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs,
return 0;
}
-static int dump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs,
- int is_pcie)
+static int
+dump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs,
+ int is_pcie)
{
int match = 0;
char *block_name = NULL;
@@ -414,8 +421,9 @@ static int dump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs,
return 0;
}
-static int dump_regs_t3c(int argc, char *argv[], int start_arg, uint32_t *regs,
- int is_pcie)
+static int
+dump_regs_t3c(int argc, char *argv[], int start_arg, uint32_t *regs,
+ int is_pcie)
{
int match = 0;
char *block_name = NULL;
@@ -479,7 +487,7 @@ static int dump_regs_t3c(int argc, char *argv[], int start_arg, uint32_t *regs,
static int
dump_regs(int argc, char *argv[], int start_arg, const char *iff_name)
{
- int i, vers, revision, is_pcie;
+ int vers, revision, is_pcie;
struct ch_ifconf_regs regs;
regs.len = REGDUMP_SIZE;
@@ -514,7 +522,8 @@ dump_regs(int argc, char *argv[], int start_arg, const char *iff_name)
return 0;
}
-static int t3_meminfo(const uint32_t *regs)
+static int
+t3_meminfo(const uint32_t *regs)
{
enum {
SG_EGR_CNTX_BADDR = 0x58,
@@ -592,11 +601,16 @@ static int t3_meminfo(const uint32_t *regs)
return 0;
}
-static int meminfo(int argc, char *argv[], int start_arg, const char *iff_name)
+static int
+meminfo(int argc, char *argv[], int start_arg, const char *iff_name)
{
int vers;
struct ch_ifconf_regs regs;
+ (void) argc;
+ (void) argv;
+ (void) start_arg;
+
regs.len = REGDUMP_SIZE;
if ((regs.data = malloc(regs.len)) == NULL)
err(1, "can't malloc");
@@ -612,11 +626,11 @@ static int meminfo(int argc, char *argv[], int start_arg, const char *iff_name)
return 0;
}
-static int mtu_tab_op(int argc, char *argv[], int start_arg,
- const char *iff_name)
+static int
+mtu_tab_op(int argc, char *argv[], int start_arg, const char *iff_name)
{
struct ch_mtus m;
- int i;
+ unsigned int i;
if (argc == start_arg) {
if (doit(iff_name, CHELSIO_GETMTUTAB, &m) < 0)
@@ -649,13 +663,14 @@ static int mtu_tab_op(int argc, char *argv[], int start_arg,
}
#ifdef CHELSIO_INTERNAL
-static void show_egress_cntxt(uint32_t data[])
+static void
+show_egress_cntxt(uint32_t data[])
{
printf("credits: %u\n", data[0] & 0x7fff);
printf("GTS: %u\n", (data[0] >> 15) & 1);
printf("index: %u\n", data[0] >> 16);
printf("queue size: %u\n", data[1] & 0xffff);
- printf("base address: 0x%llx\n",
+ printf("base address: 0x%" PRIx64 "\n",
((data[1] >> 16) | ((uint64_t)data[2] << 16) |
(((uint64_t)data[3] & 0xf) << 48)) << 12);
printf("rsp queue #: %u\n", (data[3] >> 4) & 7);
@@ -667,9 +682,10 @@ static void show_egress_cntxt(uint32_t data[])
printf("valid: %u\n", (data[3] >> 31) & 1);
}
-static void show_fl_cntxt(uint32_t data[])
+static void
+show_fl_cntxt(uint32_t data[])
{
- printf("base address: 0x%llx\n",
+ printf("base address: 0x%" PRIx64 "\n",
((uint64_t)data[0] | ((uint64_t)data[1] & 0xfffff) << 32) << 12);
printf("index: %u\n", (data[1] >> 20) | ((data[2] & 0xf) << 12));
printf("queue size: %u\n", (data[2] >> 4) & 0xffff);
@@ -680,11 +696,12 @@ static void show_fl_cntxt(uint32_t data[])
printf("GTS: %u\n", (data[3] >> 31) & 1);
}
-static void show_response_cntxt(uint32_t data[])
+static void
+show_response_cntxt(uint32_t data[])
{
printf("index: %u\n", data[0] & 0xffff);
printf("size: %u\n", data[0] >> 16);
- printf("base address: 0x%llx\n",
+ printf("base address: 0x%" PRIx64 "\n",
((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12);
printf("MSI-X/RspQ: %u\n", (data[2] >> 20) & 0x3f);
printf("intr enable: %u\n", (data[2] >> 26) & 1);
@@ -694,11 +711,12 @@ static void show_response_cntxt(uint32_t data[])
printf("FL threshold: %u\n", data[3]);
}
-static void show_cq_cntxt(uint32_t data[])
+static void
+show_cq_cntxt(uint32_t data[])
{
printf("index: %u\n", data[0] & 0xffff);
printf("size: %u\n", data[0] >> 16);
- printf("base address: 0x%llx\n",
+ printf("base address: 0x%" PRIx64 "\n",
((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12);
printf("rsp queue #: %u\n", (data[2] >> 20) & 0x3f);
printf("AN: %u\n", (data[2] >> 26) & 1);
@@ -710,8 +728,8 @@ static void show_cq_cntxt(uint32_t data[])
printf("credit threshold: %u\n", data[3] >> 16);
}
-static int get_sge_context(int argc, char *argv[], int start_arg,
- const char *iff_name)
+static int
+get_sge_context(int argc, char *argv[], int start_arg, const char *iff_name)
{
struct ch_cntxt ctx;
@@ -750,8 +768,8 @@ static int get_sge_context(int argc, char *argv[], int start_arg,
#define ntohll(x) be64toh((x))
-static int get_sge_desc(int argc, char *argv[], int start_arg,
- const char *iff_name)
+static int
+get_sge_desc(int argc, char *argv[], int start_arg, const char *iff_name)
{
uint64_t *p, wr_hdr;
unsigned int n = 1, qset, qnum;
@@ -796,7 +814,8 @@ static int get_sge_desc(int argc, char *argv[], int start_arg,
}
#endif
-static int get_tcb2(int argc, char *argv[], int start_arg, const char *iff_name)
+static int
+get_tcb2(int argc, char *argv[], int start_arg, const char *iff_name)
{
uint64_t *d;
unsigned int i;
@@ -835,8 +854,9 @@ static int get_tcb2(int argc, char *argv[], int start_arg, const char *iff_name)
return 0;
}
-static int get_pm_page_spec(const char *s, unsigned int *page_size,
- unsigned int *num_pages)
+static int
+get_pm_page_spec(const char *s, unsigned int *page_size,
+ unsigned int *num_pages)
{
char *p;
unsigned long val;
@@ -854,7 +874,8 @@ static int get_pm_page_spec(const char *s, unsigned int *page_size,
return *p;
}
-static int conf_pm(int argc, char *argv[], int start_arg, const char *iff_name)
+static int
+conf_pm(int argc, char *argv[], int start_arg, const char *iff_name)
{
struct ch_pm pm;
@@ -884,8 +905,8 @@ static int conf_pm(int argc, char *argv[], int start_arg, const char *iff_name)
}
#ifdef CHELSIO_INTERNAL
-static int dump_tcam(int argc, char *argv[], int start_arg,
- const char *iff_name)
+static int
+dump_tcam(int argc, char *argv[], int start_arg, const char *iff_name)
{
unsigned int nwords;
struct ch_tcam_word op;
@@ -907,7 +928,8 @@ static int dump_tcam(int argc, char *argv[], int start_arg,
return 0;
}
-static void hexdump_8b(unsigned int start, uint64_t *data, unsigned int len)
+static void
+hexdump_8b(unsigned int start, uint64_t *data, unsigned int len)
{
int i;
@@ -920,8 +942,8 @@ static void hexdump_8b(unsigned int start, uint64_t *data, unsigned int len)
}
}
-static int dump_mc7(int argc, char *argv[], int start_arg,
- const char *iff_name)
+static int
+dump_mc7(int argc, char *argv[], int start_arg, const char *iff_name)
{
struct ch_mem_range mem;
unsigned int mem_id, addr, len;
@@ -959,10 +981,11 @@ static int dump_mc7(int argc, char *argv[], int start_arg,
}
#endif
-/* Max FW size is 32K including version, +4 bytes for the checksum. */
+/* Max FW size is 64K including version, +4 bytes for the checksum. */
#define MAX_FW_IMAGE_SIZE (64 * 1024)
-static int load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
+static int
+load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
{
int fd, len;
struct ch_mem_range op;
@@ -979,12 +1002,13 @@ static int load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
if (!op.buf)
err(1, "load firmware");
- op.len = read(fd, op.buf, MAX_FW_IMAGE_SIZE + 1);
- if (op.len < 0)
+ len = read(fd, op.buf, MAX_FW_IMAGE_SIZE + 1);
+ if (len < 0)
err(1, "load firmware");
- if (op.len > MAX_FW_IMAGE_SIZE)
+ if (len > MAX_FW_IMAGE_SIZE)
errx(1, "FW image too large");
+ op.len = len;
if (doit(iff_name, CHELSIO_LOAD_FW, &op) < 0)
err(1, "load firmware");
return 0;
@@ -993,8 +1017,8 @@ static int load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
/* Max BOOT size is 255*512 bytes including the BIOS boot ROM basic header */
#define MAX_BOOT_IMAGE_SIZE (0xff * 512)
-static int load_boot(int argc, char *argv[],
- int start_arg, const char *iff_name)
+static int
+load_boot(int argc, char *argv[], int start_arg, const char *iff_name)
{
int fd, len;
struct ch_mem_range op;
@@ -1024,7 +1048,8 @@ static int load_boot(int argc, char *argv[],
return 0;
}
-static int dump_proto_sram(const char *iff_name)
+static int
+dump_proto_sram(const char *iff_name)
{
int i, j;
uint8_t buf[PROTO_SRAM_SIZE];
@@ -1054,15 +1079,20 @@ static int dump_proto_sram(const char *iff_name)
return 0;
}
-static int proto_sram_op(int argc, char *argv[], int start_arg,
+static int
+proto_sram_op(int argc, char *argv[], int start_arg,
const char *iff_name)
{
+ (void) argv;
+ (void) start_arg;
+
if (argc == start_arg)
return dump_proto_sram(iff_name);
return -1;
}
-static int dump_qset_params(const char *iff_name)
+static int
+dump_qset_params(const char *iff_name)
{
struct ch_qset_params qp;
@@ -1084,10 +1114,10 @@ static int dump_qset_params(const char *iff_name)
return 0;
}
-static int qset_config(int argc, char *argv[], int start_arg,
- const char *iff_name)
+static int
+qset_config(int argc, char *argv[], int start_arg, const char *iff_name)
{
- struct ch_qset_params qp;
+ (void) argv;
if (argc == start_arg)
return dump_qset_params(iff_name);
@@ -1095,11 +1125,13 @@ static int qset_config(int argc, char *argv[], int start_arg,
return -1;
}
-static int qset_num_config(int argc, char *argv[], int start_arg,
- const char *iff_name)
+static int
+qset_num_config(int argc, char *argv[], int start_arg, const char *iff_name)
{
struct ch_reg reg;
+ (void) argv;
+
if (argc == start_arg) {
if (doit(iff_name, CHELSIO_GET_QSET_NUM, &reg) < 0)
err(1, "get qsets");
@@ -1113,7 +1145,8 @@ static int qset_num_config(int argc, char *argv[], int start_arg,
/*
* Parse a string containing an IP address with an optional network prefix.
*/
-static int parse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask)
+static int
+parse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask)
{
char *p, *slash;
struct in_addr ia;
@@ -1143,7 +1176,8 @@ static int parse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask)
/*
* Parse a string containing a value and an optional colon separated mask.
*/
-static int parse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask)
+static int
+parse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask)
{
char *p;
@@ -1156,14 +1190,15 @@ static int parse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask)
return *p ? -1 : 0;
}
-static int parse_trace_param(const char *s, uint32_t *val, uint32_t *mask)
+static int
+parse_trace_param(const char *s, uint32_t *val, uint32_t *mask)
{
return strchr(s, '.') ? parse_ipaddr(s, val, mask) :
parse_val_mask_param(s, val, mask);
}
-static int trace_config(int argc, char *argv[], int start_arg,
- const char *iff_name)
+static int
+trace_config(int argc, char *argv[], int start_arg, const char *iff_name)
{
uint32_t val, mask;
struct ch_trace trace;
@@ -1238,7 +1273,8 @@ static int trace_config(int argc, char *argv[], int start_arg,
return 0;
}
-static int get_sched_param(int argc, char *argv[], int pos, unsigned int *valp)
+static int
+get_sched_param(int argc, char *argv[], int pos, unsigned int *valp)
{
if (pos + 1 >= argc)
errx(1, "missing value for %s", argv[pos]);
@@ -1247,7 +1283,8 @@ static int get_sched_param(int argc, char *argv[], int pos, unsigned int *valp)
return 0;
}
-static int tx_sched(int argc, char *argv[], int start_arg, const char *iff_name)
+static int
+tx_sched(int argc, char *argv[], int start_arg, const char *iff_name)
{
struct ch_hw_sched op;
unsigned int idx, val;
@@ -1293,7 +1330,8 @@ static int tx_sched(int argc, char *argv[], int start_arg, const char *iff_name)
return 0;
}
-static int pktsched(int argc, char *argv[], int start_arg, const char *iff_name)
+static int
+pktsched(int argc, char *argv[], int start_arg, const char *iff_name)
{
struct ch_pktsched_params op;
unsigned int idx, min = -1, max, binding = -1;
@@ -1333,20 +1371,29 @@ static int pktsched(int argc, char *argv[], int start_arg, const char *iff_name)
return 0;
}
-static int clear_stats(int argc, char *argv[], int start_arg,
- const char *iff_name)
+static int
+clear_stats(int argc, char *argv[], int start_arg, const char *iff_name)
{
+ (void) argc;
+ (void) argv;
+ (void) start_arg;
+
if (doit(iff_name, CHELSIO_CLEAR_STATS, NULL) < 0)
err(1, "clearstats");
return 0;
}
-static int get_up_la(int argc, char *argv[], int start_arg, const char *iff_name)
+static int
+get_up_la(int argc, char *argv[], int start_arg, const char *iff_name)
{
struct ch_up_la la;
int i, idx, max_idx, entries;
+ (void) argc;
+ (void) argv;
+ (void) start_arg;
+
la.stopped = 0;
la.idx = -1;
la.bufsize = LA_BUFSIZE;
@@ -1372,11 +1419,16 @@ static int get_up_la(int argc, char *argv[], int start_arg, const char *iff_name
return 0;
}
-static int get_up_ioqs(int argc, char *argv[], int start_arg, const char *iff_name)
+static int
+get_up_ioqs(int argc, char *argv[], int start_arg, const char *iff_name)
{
struct ch_up_ioqs ioqs;
int i, entries;
+ (void) argc;
+ (void) argv;
+ (void) start_arg;
+
bzero(&ioqs, sizeof(ioqs));
ioqs.bufsize = IOQS_BUFSIZE;
ioqs.data = malloc(IOQS_BUFSIZE);
@@ -1465,10 +1517,12 @@ run_cmd(int argc, char *argv[], const char *iff_name)
static int
run_cmd_loop(int argc, char *argv[], const char *iff_name)
{
- int n, i;
+ int n;
+ unsigned int i;
char buf[64];
char *args[8], *s;
+ (void) argc;
args[0] = argv[0];
args[1] = argv[1];
@@ -1481,11 +1535,8 @@ run_cmd_loop(int argc, char *argv[], const char *iff_name)
for (;;) {
fprintf(stdout, "> ");
fflush(stdout);
- n = read(STDIN_FILENO, buf, sizeof(buf));
- if (n > sizeof(buf) - 1) {
- fprintf(stdout, "too much input.\n");
- return (0);
- } else if (n <= 0)
+ n = read(STDIN_FILENO, buf, sizeof(buf) - 1);
+ if (n <= 0)
return (0);
if (buf[--n] != '\n')
diff --git a/usr.sbin/cxgbtool/reg_defs.c b/usr.sbin/cxgbtool/reg_defs.c
index 734061f..687bb75 100644
--- a/usr.sbin/cxgbtool/reg_defs.c
+++ b/usr.sbin/cxgbtool/reg_defs.c
@@ -106,7 +106,7 @@ struct reg_info sge_regs[] = {
{ "Packet_Too_Big", 3, 1 },
{ "Packet_Mismatch", 4, 1 },
{ "SG_RESPACCUTIMER", 0xc0, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info mc3_regs[] = {
@@ -196,7 +196,7 @@ struct reg_info mc3_regs[] = {
{ "MC3_Uncorr_Err", 1, 1 },
{ "MC3_Parity_Err", 2, 8 },
{ "MC3_Addr_Err", 10, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info mc4_regs[] = {
@@ -276,7 +276,7 @@ struct reg_info mc4_regs[] = {
{ "MC4_Corr_Err", 0, 1 },
{ "MC4_Uncorr_Err", 1, 1 },
{ "MC4_Addr_Err", 2, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info tpi_regs[] = {
@@ -290,7 +290,7 @@ struct reg_info tpi_regs[] = {
{ "INT_DIR", 31, 1 },
{ "TPI_PAR", 0x29c, 0 },
{ "TPIPAR", 0, 7 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info tp_regs[] = {
@@ -509,7 +509,7 @@ struct reg_info tp_regs[] = {
{ "DROP_TICKS_CNT", 4, 26 },
{ "NUM_PKTS_DROPPED", 0, 4 },
{ "TP_TX_DROP_COUNT", 0x4bc, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info rat_regs[] = {
@@ -532,7 +532,7 @@ struct reg_info rat_regs[] = {
{ "CspiFramingError", 1, 1 },
{ "SgeFramingError", 2, 1 },
{ "TpFramingError", 3, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info cspi_regs[] = {
@@ -560,7 +560,7 @@ struct reg_info cspi_regs[] = {
{ "TXDrop", 2, 1 },
{ "RXOverflow", 3, 1 },
{ "RAMParityErr", 4, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info espi_regs[] = {
@@ -660,7 +660,7 @@ struct reg_info espi_regs[] = {
{ "Error_Ack", 9, 1 },
{ "Unmapped_Err", 10, 1 },
{ "Transaction_Timer", 16, 8 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info ulp_regs[] = {
@@ -682,7 +682,7 @@ struct reg_info ulp_regs[] = {
{ "Pm_E2C_Wrt_Full", 24, 1 },
{ "Pm_C2E_Wrt_Full", 25, 1 },
{ "ULP_PIO_CTRL", 0x998, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info pl_regs[] = {
@@ -712,7 +712,7 @@ struct reg_info pl_regs[] = {
{ "PL_Intr_CSPI", 9, 1 },
{ "PL_Intr_PCIX", 10, 1 },
{ "PL_Intr_EXT", 11, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info mc5_regs[] = {
@@ -833,5 +833,5 @@ struct reg_info mc5_regs[] = {
{ "MC5_DATA_WRITE_CMD", 0xcf4, 0 },
{ "MC5_DATA_READ_CMD", 0xcf8, 0 },
{ "MC5_MASK_WRITE_CMD", 0xcfc, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
diff --git a/usr.sbin/cxgbtool/reg_defs_t3.c b/usr.sbin/cxgbtool/reg_defs_t3.c
index ffa4aef..6e9b8b1 100644
--- a/usr.sbin/cxgbtool/reg_defs_t3.c
+++ b/usr.sbin/cxgbtool/reg_defs_t3.c
@@ -140,7 +140,7 @@ struct reg_info sge3_regs[] = {
{ "DrbPriThrsh", 0, 16 },
{ "SG_DEBUG_INDEX", 0x78, 0 },
{ "SG_DEBUG_DATA", 0x7c, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info pcix1_regs[] = {
@@ -212,7 +212,7 @@ struct reg_info pcix1_regs[] = {
{ "WakeUp0", 2, 1 },
{ "SleepMode1", 1, 1 },
{ "SleepMode0", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info pcie0_regs[] = {
@@ -411,7 +411,7 @@ struct reg_info pcie0_regs[] = {
{ "BISTDone", 24, 8 },
{ "BISTCycleThresh", 3, 16 },
{ "BISTMode", 0, 3 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3dbg_regs[] = {
@@ -557,7 +557,7 @@ struct reg_info t3dbg_regs[] = {
{ "PMON_CDEL_MANUAL", 4, 1 },
{ "PMON_MANUAL", 1, 1 },
{ "PMON_AUTO", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info mc7_pmrx_regs[] = {
@@ -674,7 +674,7 @@ struct reg_info mc7_pmrx_regs[] = {
{ "PE", 2, 15 },
{ "UE", 1, 1 },
{ "CE", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info mc7_pmtx_regs[] = {
@@ -791,7 +791,7 @@ struct reg_info mc7_pmtx_regs[] = {
{ "PE", 2, 15 },
{ "UE", 1, 1 },
{ "CE", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info mc7_cm_regs[] = {
@@ -908,7 +908,7 @@ struct reg_info mc7_cm_regs[] = {
{ "PE", 2, 15 },
{ "UE", 1, 1 },
{ "CE", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info cim_regs[] = {
@@ -1024,7 +1024,7 @@ struct reg_info cim_regs[] = {
{ "CIM_CDEBUGDATA", 0x2d0, 0 },
{ "CDebugDataH", 16, 16 },
{ "CDebugDataL", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info tp1_regs[] = {
@@ -1384,7 +1384,7 @@ struct reg_info tp1_regs[] = {
{ "TP_EMBED_OP_FIELD3", 0x4f4, 0 },
{ "TP_EMBED_OP_FIELD4", 0x4f8, 0 },
{ "TP_EMBED_OP_FIELD5", 0x4fc, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info ulp2_rx_regs[] = {
@@ -1428,7 +1428,7 @@ struct reg_info ulp2_rx_regs[] = {
{ "ULPRX_RQ_ULIMIT", 0x538, 0 },
{ "ULPRX_PBL_LLIMIT", 0x53c, 0 },
{ "ULPRX_PBL_ULIMIT", 0x540, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info ulp2_tx_regs[] = {
@@ -1456,7 +1456,7 @@ struct reg_info ulp2_tx_regs[] = {
{ "ULPTX_DMA_WEIGHT", 0x5ac, 0 },
{ "D1_WEIGHT", 16, 16 },
{ "D0_WEIGHT", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info pm1_rx_regs[] = {
@@ -1500,7 +1500,7 @@ struct reg_info pm1_rx_regs[] = {
{ "ocspi1_ofifo2x_Tx_framing_error", 6, 1 },
{ "iespi_par_error", 3, 3 },
{ "ocspi_par_error", 0, 3 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info pm1_tx_regs[] = {
@@ -1544,7 +1544,7 @@ struct reg_info pm1_tx_regs[] = {
{ "oespi1_ofifo2x_Tx_framing_error", 6, 1 },
{ "icspi_par_error", 3, 3 },
{ "oespi_par_error", 0, 3 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info mps0_regs[] = {
@@ -1585,7 +1585,7 @@ struct reg_info mps0_regs[] = {
{ "RXTpParErr", 4, 2 },
{ "TX1TpParErr", 2, 2 },
{ "TX0TpParErr", 0, 2 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info cpl_switch_regs[] = {
@@ -1616,7 +1616,7 @@ struct reg_info cpl_switch_regs[] = {
{ "cpl_map_tbl_idx", 0, 8 },
{ "CPL_MAP_TBL_DATA", 0x65c, 0 },
{ "cpl_map_tbl_data", 0, 8 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info smb0_regs[] = {
@@ -1682,7 +1682,7 @@ struct reg_info smb0_regs[] = {
{ "DebugDataL", 0, 16 },
{ "SMB_DEBUG_LA", 0x69c, 0 },
{ "DebugLAReqAddr", 0, 10 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info i2cm0_regs[] = {
@@ -1695,7 +1695,7 @@ struct reg_info i2cm0_regs[] = {
{ "Ack", 30, 1 },
{ "Cont", 1, 1 },
{ "Op", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info mi1_regs[] = {
@@ -1714,7 +1714,7 @@ struct reg_info mi1_regs[] = {
{ "Busy", 31, 1 },
{ "Inc", 2, 1 },
{ "Op", 0, 2 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info jm1_regs[] = {
@@ -1727,7 +1727,7 @@ struct reg_info jm1_regs[] = {
{ "JM_OP", 0x6cc, 0 },
{ "Busy", 31, 1 },
{ "Cnt", 0, 5 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info sf1_regs[] = {
@@ -1737,7 +1737,7 @@ struct reg_info sf1_regs[] = {
{ "Cont", 3, 1 },
{ "ByteCnt", 1, 2 },
{ "Op", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info pl3_regs[] = {
@@ -1839,7 +1839,7 @@ struct reg_info pl3_regs[] = {
{ "PL_REV", 0x6f4, 0 },
{ "Rev", 0, 4 },
{ "PL_CLI", 0x6f8, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info mc5a_regs[] = {
@@ -2010,7 +2010,7 @@ struct reg_info mc5a_regs[] = {
{ "ReadCmd", 0, 20 },
{ "MC5_DB_MASK_WRITE_CMD", 0x7fc, 0 },
{ "MaskWr", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info xgmac0_0_regs[] = {
@@ -2341,7 +2341,7 @@ struct reg_info xgmac0_0_regs[] = {
{ "XGM_RX_SPI4_SOP_EOP_CNT", 0x9ac, 0 },
{ "RxSPI4SopCnt", 16, 16 },
{ "RxSPI4EopCnt", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info xgmac0_1_regs[] = {
@@ -2672,5 +2672,5 @@ struct reg_info xgmac0_1_regs[] = {
{ "XGM_RX_SPI4_SOP_EOP_CNT", 0xbac, 0 },
{ "RxSPI4SopCnt", 16, 16 },
{ "RxSPI4EopCnt", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
diff --git a/usr.sbin/cxgbtool/reg_defs_t3b.c b/usr.sbin/cxgbtool/reg_defs_t3b.c
index 539742c..cd85d84 100644
--- a/usr.sbin/cxgbtool/reg_defs_t3b.c
+++ b/usr.sbin/cxgbtool/reg_defs_t3b.c
@@ -150,7 +150,7 @@ struct reg_info t3b_sge3_regs[] = {
{ "DrbPriThrsh", 0, 16 },
{ "SG_DEBUG_INDEX", 0x78, 0 },
{ "SG_DEBUG_DATA", 0x7c, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_pcix1_regs[] = {
@@ -222,7 +222,7 @@ struct reg_info t3b_pcix1_regs[] = {
{ "WakeUp0", 2, 1 },
{ "SleepMode1", 1, 1 },
{ "SleepMode0", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_pcie0_regs[] = {
@@ -376,7 +376,7 @@ struct reg_info t3b_pcie0_regs[] = {
{ "BeaconDetect", 2, 1 },
{ "RxDetect", 1, 1 },
{ "TxIdleDetect", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_t3dbg_regs[] = {
@@ -557,7 +557,7 @@ struct reg_info t3b_t3dbg_regs[] = {
{ "BSEnLane1", 4, 1 },
{ "BSInSelLane0", 1, 2 },
{ "BSEnLane0", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_mc7_pmrx_regs[] = {
@@ -678,7 +678,7 @@ struct reg_info t3b_mc7_pmrx_regs[] = {
{ "PE", 2, 15 },
{ "UE", 1, 1 },
{ "CE", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_mc7_pmtx_regs[] = {
@@ -799,7 +799,7 @@ struct reg_info t3b_mc7_pmtx_regs[] = {
{ "PE", 2, 15 },
{ "UE", 1, 1 },
{ "CE", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_mc7_cm_regs[] = {
@@ -920,7 +920,7 @@ struct reg_info t3b_mc7_cm_regs[] = {
{ "PE", 2, 15 },
{ "UE", 1, 1 },
{ "CE", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_cim_regs[] = {
@@ -1047,7 +1047,7 @@ struct reg_info t3b_cim_regs[] = {
{ "PILADbgWrPtr", 0, 9 },
{ "CIM_PO_LA_DEBUGDATA", 0x2e8, 0 },
{ "CIM_PI_LA_DEBUGDATA", 0x2ec, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_tp1_regs[] = {
@@ -1453,7 +1453,7 @@ struct reg_info t3b_tp1_regs[] = {
{ "TP_EMBED_OP_FIELD3", 0x4f4, 0 },
{ "TP_EMBED_OP_FIELD4", 0x4f8, 0 },
{ "TP_EMBED_OP_FIELD5", 0x4fc, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_ulp2_rx_regs[] = {
@@ -1497,7 +1497,7 @@ struct reg_info t3b_ulp2_rx_regs[] = {
{ "ULPRX_RQ_ULIMIT", 0x538, 0 },
{ "ULPRX_PBL_LLIMIT", 0x53c, 0 },
{ "ULPRX_PBL_ULIMIT", 0x540, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_ulp2_tx_regs[] = {
@@ -1525,7 +1525,7 @@ struct reg_info t3b_ulp2_tx_regs[] = {
{ "ULPTX_DMA_WEIGHT", 0x5ac, 0 },
{ "D1_WEIGHT", 16, 16 },
{ "D0_WEIGHT", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_pm1_rx_regs[] = {
@@ -1569,7 +1569,7 @@ struct reg_info t3b_pm1_rx_regs[] = {
{ "ocspi1_ofifo2x_Tx_framing_error", 6, 1 },
{ "iespi_par_error", 3, 3 },
{ "ocspi_par_error", 0, 3 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_pm1_tx_regs[] = {
@@ -1613,7 +1613,7 @@ struct reg_info t3b_pm1_tx_regs[] = {
{ "oespi1_ofifo2x_Tx_framing_error", 6, 1 },
{ "icspi_par_error", 3, 3 },
{ "oespi_par_error", 0, 3 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_mps0_regs[] = {
@@ -1655,7 +1655,7 @@ struct reg_info t3b_mps0_regs[] = {
{ "RXTpParErr", 4, 2 },
{ "TX1TpParErr", 2, 2 },
{ "TX0TpParErr", 0, 2 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_cpl_switch_regs[] = {
@@ -1686,7 +1686,7 @@ struct reg_info t3b_cpl_switch_regs[] = {
{ "cpl_map_tbl_idx", 0, 8 },
{ "CPL_MAP_TBL_DATA", 0x65c, 0 },
{ "cpl_map_tbl_data", 0, 8 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_smb0_regs[] = {
@@ -1752,7 +1752,7 @@ struct reg_info t3b_smb0_regs[] = {
{ "DebugDataL", 0, 16 },
{ "SMB_DEBUG_LA", 0x69c, 0 },
{ "DebugLAReqAddr", 0, 10 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_i2cm0_regs[] = {
@@ -1765,7 +1765,7 @@ struct reg_info t3b_i2cm0_regs[] = {
{ "Ack", 30, 1 },
{ "Cont", 1, 1 },
{ "Op", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_mi1_regs[] = {
@@ -1784,7 +1784,7 @@ struct reg_info t3b_mi1_regs[] = {
{ "Busy", 31, 1 },
{ "Inc", 2, 1 },
{ "Op", 0, 2 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_jm1_regs[] = {
@@ -1797,7 +1797,7 @@ struct reg_info t3b_jm1_regs[] = {
{ "JM_OP", 0x6cc, 0 },
{ "Busy", 31, 1 },
{ "Cnt", 0, 5 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_sf1_regs[] = {
@@ -1807,7 +1807,7 @@ struct reg_info t3b_sf1_regs[] = {
{ "Cont", 3, 1 },
{ "ByteCnt", 1, 2 },
{ "Op", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_pl3_regs[] = {
@@ -1917,7 +1917,7 @@ struct reg_info t3b_pl3_regs[] = {
{ "PL_CLI", 0x6f8, 0 },
{ "PL_LCK", 0x6fc, 0 },
{ "Lck", 0, 2 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_mc5a_regs[] = {
@@ -2100,7 +2100,7 @@ struct reg_info t3b_mc5a_regs[] = {
{ "ReadCmd", 0, 20 },
{ "MC5_DB_MASK_WRITE_CMD", 0x7fc, 0 },
{ "MaskWr", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_xgmac0_0_regs[] = {
@@ -2464,7 +2464,7 @@ struct reg_info t3b_xgmac0_0_regs[] = {
{ "XGM_RX_SPI4_SOP_EOP_CNT", 0x9ac, 0 },
{ "RxSPI4SopCnt", 16, 16 },
{ "RxSPI4EopCnt", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3b_xgmac0_1_regs[] = {
@@ -2828,5 +2828,5 @@ struct reg_info t3b_xgmac0_1_regs[] = {
{ "XGM_RX_SPI4_SOP_EOP_CNT", 0xbac, 0 },
{ "RxSPI4SopCnt", 16, 16 },
{ "RxSPI4EopCnt", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
diff --git a/usr.sbin/cxgbtool/reg_defs_t3c.c b/usr.sbin/cxgbtool/reg_defs_t3c.c
index 6127fa4..b9181b6 100644
--- a/usr.sbin/cxgbtool/reg_defs_t3c.c
+++ b/usr.sbin/cxgbtool/reg_defs_t3c.c
@@ -177,7 +177,7 @@ struct reg_info t3c_sge3_regs[] = {
{ "DrbPriThrsh", 0, 16 },
{ "SG_DEBUG_INDEX", 0x78, 0 },
{ "SG_DEBUG_DATA", 0x7c, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_pcix1_regs[] = {
@@ -282,7 +282,7 @@ struct reg_info t3c_pcix1_regs[] = {
{ "IntSt", 4, 3 },
{ "PIOSt", 2, 2 },
{ "RFReqRdSt", 0, 2 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_pcie0_regs[] = {
@@ -475,7 +475,7 @@ struct reg_info t3c_pcie0_regs[] = {
{ "P_WMark", 18, 11 },
{ "NP_WMark", 11, 7 },
{ "CPL_WMark", 0, 11 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_t3dbg_regs[] = {
@@ -656,7 +656,7 @@ struct reg_info t3c_t3dbg_regs[] = {
{ "BSEnLane1", 4, 1 },
{ "BSInSelLane0", 1, 2 },
{ "BSEnLane0", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_mc7_pmrx_regs[] = {
@@ -777,7 +777,7 @@ struct reg_info t3c_mc7_pmrx_regs[] = {
{ "PE", 2, 15 },
{ "UE", 1, 1 },
{ "CE", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_mc7_pmtx_regs[] = {
@@ -898,7 +898,7 @@ struct reg_info t3c_mc7_pmtx_regs[] = {
{ "PE", 2, 15 },
{ "UE", 1, 1 },
{ "CE", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_mc7_cm_regs[] = {
@@ -1019,7 +1019,7 @@ struct reg_info t3c_mc7_cm_regs[] = {
{ "PE", 2, 15 },
{ "UE", 1, 1 },
{ "CE", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_cim_regs[] = {
@@ -1194,7 +1194,7 @@ struct reg_info t3c_cim_regs[] = {
{ "PILADbgWrPtr", 0, 9 },
{ "CIM_PO_LA_DEBUGDATA", 0x2e8, 0 },
{ "CIM_PI_LA_DEBUGDATA", 0x2ec, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_tp1_regs[] = {
@@ -1667,7 +1667,7 @@ struct reg_info t3c_tp1_regs[] = {
{ "TP_EMBED_OP_FIELD3", 0x4f4, 0 },
{ "TP_EMBED_OP_FIELD4", 0x4f8, 0 },
{ "TP_EMBED_OP_FIELD5", 0x4fc, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_ulp2_rx_regs[] = {
@@ -1725,7 +1725,7 @@ struct reg_info t3c_ulp2_rx_regs[] = {
{ "ULPRX_RQ_ULIMIT", 0x538, 0 },
{ "ULPRX_PBL_LLIMIT", 0x53c, 0 },
{ "ULPRX_PBL_ULIMIT", 0x540, 0 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_ulp2_tx_regs[] = {
@@ -1766,7 +1766,7 @@ struct reg_info t3c_ulp2_tx_regs[] = {
{ "ULPTX_DMA_WEIGHT", 0x5ac, 0 },
{ "D1_WEIGHT", 16, 16 },
{ "D0_WEIGHT", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_pm1_rx_regs[] = {
@@ -1810,7 +1810,7 @@ struct reg_info t3c_pm1_rx_regs[] = {
{ "ocspi1_ofifo2x_Tx_framing_error", 6, 1 },
{ "iespi_par_error", 3, 3 },
{ "ocspi_par_error", 0, 3 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_pm1_tx_regs[] = {
@@ -1854,7 +1854,7 @@ struct reg_info t3c_pm1_tx_regs[] = {
{ "oespi1_ofifo2x_Tx_framing_error", 6, 1 },
{ "icspi_par_error", 3, 3 },
{ "oespi_par_error", 0, 3 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_mps0_regs[] = {
@@ -1896,7 +1896,7 @@ struct reg_info t3c_mps0_regs[] = {
{ "RXTpParErr", 4, 2 },
{ "TX1TpParErr", 2, 2 },
{ "TX0TpParErr", 0, 2 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_cpl_switch_regs[] = {
@@ -1930,7 +1930,7 @@ struct reg_info t3c_cpl_switch_regs[] = {
{ "cpl_map_tbl_idx", 0, 8 },
{ "CPL_MAP_TBL_DATA", 0x65c, 0 },
{ "cpl_map_tbl_data", 0, 8 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_smb0_regs[] = {
@@ -1996,7 +1996,7 @@ struct reg_info t3c_smb0_regs[] = {
{ "DebugDataL", 0, 16 },
{ "SMB_DEBUG_LA", 0x69c, 0 },
{ "DebugLAReqAddr", 0, 10 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_i2cm0_regs[] = {
@@ -2009,7 +2009,7 @@ struct reg_info t3c_i2cm0_regs[] = {
{ "Ack", 30, 1 },
{ "Cont", 1, 1 },
{ "Op", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_mi1_regs[] = {
@@ -2028,7 +2028,7 @@ struct reg_info t3c_mi1_regs[] = {
{ "Busy", 31, 1 },
{ "Inc", 2, 1 },
{ "Op", 0, 2 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_jm1_regs[] = {
@@ -2041,7 +2041,7 @@ struct reg_info t3c_jm1_regs[] = {
{ "JM_OP", 0x6cc, 0 },
{ "Busy", 31, 1 },
{ "Cnt", 0, 5 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_sf1_regs[] = {
@@ -2051,7 +2051,7 @@ struct reg_info t3c_sf1_regs[] = {
{ "Cont", 3, 1 },
{ "ByteCnt", 1, 2 },
{ "Op", 0, 1 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_pl3_regs[] = {
@@ -2162,7 +2162,7 @@ struct reg_info t3c_pl3_regs[] = {
{ "PL_CLI", 0x6f8, 0 },
{ "PL_LCK", 0x6fc, 0 },
{ "Lck", 0, 2 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_mc5a_regs[] = {
@@ -2346,7 +2346,7 @@ struct reg_info t3c_mc5a_regs[] = {
{ "ReadCmd", 0, 20 },
{ "MC5_DB_MASK_WRITE_CMD", 0x7fc, 0 },
{ "MaskWr", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_xgmac0_0_regs[] = {
@@ -2730,7 +2730,7 @@ struct reg_info t3c_xgmac0_0_regs[] = {
{ "XGM_RX_SPI4_SOP_EOP_CNT", 0x9ac, 0 },
{ "RxSPI4SopCnt", 16, 16 },
{ "RxSPI4EopCnt", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
struct reg_info t3c_xgmac0_1_regs[] = {
@@ -3114,6 +3114,6 @@ struct reg_info t3c_xgmac0_1_regs[] = {
{ "XGM_RX_SPI4_SOP_EOP_CNT", 0xbac, 0 },
{ "RxSPI4SopCnt", 16, 16 },
{ "RxSPI4EopCnt", 0, 16 },
- { NULL }
+ { NULL, 0, 0 }
};
diff --git a/usr.sbin/daemon/Makefile b/usr.sbin/daemon/Makefile
index 3ca3e91..2def803 100644
--- a/usr.sbin/daemon/Makefile
+++ b/usr.sbin/daemon/Makefile
@@ -6,6 +6,4 @@ MAN= daemon.8
DPADD= ${LIBUTIL}
LDADD= -lutil
-WARNS?= 2
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/dconschat/Makefile b/usr.sbin/dconschat/Makefile
index 47efe52..2836a66 100644
--- a/usr.sbin/dconschat/Makefile
+++ b/usr.sbin/dconschat/Makefile
@@ -8,4 +8,6 @@ CFLAGS+= -I${.CURDIR}/../../sys
DPADD= ${LIBKVM}
LDADD= -lkvm
+WARNS?= 1
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/devinfo/Makefile b/usr.sbin/devinfo/Makefile
index 52e4d6d..2a2301b 100644
--- a/usr.sbin/devinfo/Makefile
+++ b/usr.sbin/devinfo/Makefile
@@ -3,8 +3,6 @@
PROG= devinfo
MAN= devinfo.8
-WARNS?= 2
-
DPADD= ${LIBDEVINFO}
LDADD= -ldevinfo
diff --git a/usr.sbin/devinfo/devinfo.c b/usr.sbin/devinfo/devinfo.c
index c32e57b..73dcfd5 100644
--- a/usr.sbin/devinfo/devinfo.c
+++ b/usr.sbin/devinfo/devinfo.c
@@ -137,7 +137,7 @@ print_device(struct devinfo_dev *dev, void *arg)
struct indent_arg ia;
int i, indent;
- if (vflag || (dev->dd_name[0] != 0 && dev->dd_state >= DIS_ATTACHED)) {
+ if (vflag || (dev->dd_name[0] != 0 && dev->dd_state >= DS_ATTACHED)) {
indent = (int)(intptr_t)arg;
for (i = 0; i < indent; i++)
printf(" ");
diff --git a/usr.sbin/digictl/Makefile b/usr.sbin/digictl/Makefile
index 029dfee..cb3745b 100644
--- a/usr.sbin/digictl/Makefile
+++ b/usr.sbin/digictl/Makefile
@@ -3,6 +3,4 @@
PROG= digictl
MAN= digictl.8
-WARNS?= 2
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/diskinfo/Makefile b/usr.sbin/diskinfo/Makefile
index 5ffa27f6..b16b933 100644
--- a/usr.sbin/diskinfo/Makefile
+++ b/usr.sbin/diskinfo/Makefile
@@ -3,8 +3,6 @@
PROG= diskinfo
MAN= diskinfo.8
-WARNS?= 5
-
DPADD= ${LIBUTIL}
LDADD= -lutil
diff --git a/usr.sbin/diskinfo/diskinfo.8 b/usr.sbin/diskinfo/diskinfo.8
index dfc7040..f68d426 100644
--- a/usr.sbin/diskinfo/diskinfo.8
+++ b/usr.sbin/diskinfo/diskinfo.8
@@ -46,7 +46,8 @@ and optionally runs a naive performance test on the device.
.Pp
If given no arguments, the output will be a single line per specified device
with the following fields: device name, sectorsize, media size in bytes,
-media size in sectors, firmware cylinders, firmware heads, and firmware sectors.
+media size in sectors, stripe size, stripe offset, firmware cylinders,
+firmware heads, and firmware sectors.
The last three fields are only present if the information is available.
.Pp
If given the
diff --git a/usr.sbin/diskinfo/diskinfo.c b/usr.sbin/diskinfo/diskinfo.c
index 7ecf7cb..1f967b7 100644
--- a/usr.sbin/diskinfo/diskinfo.c
+++ b/usr.sbin/diskinfo/diskinfo.c
@@ -58,7 +58,7 @@ main(int argc, char **argv)
{
int i, ch, fd, error;
char buf[BUFSIZ], ident[DISK_IDENT_SIZE];
- off_t mediasize;
+ off_t mediasize, stripesize, stripeoffset;
u_int sectorsize, fwsectors, fwheads;
while ((ch = getopt(argc, argv, "ctv")) != -1) {
@@ -104,11 +104,19 @@ main(int argc, char **argv)
error = ioctl(fd, DIOCGFWHEADS, &fwheads);
if (error)
fwheads = 0;
+ error = ioctl(fd, DIOCGSTRIPESIZE, &stripesize);
+ if (error)
+ stripesize = 0;
+ error = ioctl(fd, DIOCGSTRIPEOFFSET, &stripeoffset);
+ if (error)
+ stripeoffset = 0;
if (!opt_v) {
printf("%s", argv[i]);
printf("\t%u", sectorsize);
printf("\t%jd", (intmax_t)mediasize);
printf("\t%jd", (intmax_t)mediasize/sectorsize);
+ printf("\t%jd", (intmax_t)stripesize);
+ printf("\t%jd", (intmax_t)stripeoffset);
if (fwsectors != 0 && fwheads != 0) {
printf("\t%jd", (intmax_t)mediasize /
(fwsectors * fwheads * sectorsize));
@@ -124,6 +132,8 @@ main(int argc, char **argv)
(intmax_t)mediasize, buf);
printf("\t%-12jd\t# mediasize in sectors\n",
(intmax_t)mediasize/sectorsize);
+ printf("\t%-12jd\t# stripesize\n", stripesize);
+ printf("\t%-12jd\t# stripeoffset\n", stripeoffset);
if (fwsectors != 0 && fwheads != 0) {
printf("\t%-12jd\t# Cylinders according to firmware.\n", (intmax_t)mediasize /
(fwsectors * fwheads * sectorsize));
diff --git a/usr.sbin/dnssec-dsfromkey/Makefile b/usr.sbin/dnssec-dsfromkey/Makefile
index ee7c75e..0b57eb5 100644
--- a/usr.sbin/dnssec-dsfromkey/Makefile
+++ b/usr.sbin/dnssec-dsfromkey/Makefile
@@ -17,6 +17,8 @@ CFLAGS+= -I${SRCDIR}/unix/include -I${SRCDIR}/include
DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
+WARNS?= 3
+
MAN= dnssec-dsfromkey.8
.include <bsd.prog.mk>
diff --git a/usr.sbin/dnssec-keyfromlabel/Makefile b/usr.sbin/dnssec-keyfromlabel/Makefile
index a698bff..fd6a341 100644
--- a/usr.sbin/dnssec-keyfromlabel/Makefile
+++ b/usr.sbin/dnssec-keyfromlabel/Makefile
@@ -17,6 +17,8 @@ CFLAGS+= -I${SRCDIR}/unix/include -I${SRCDIR}/include
DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
+WARNS?= 3
+
MAN= dnssec-keyfromlabel.8
.include <bsd.prog.mk>
diff --git a/usr.sbin/dnssec-keygen/Makefile b/usr.sbin/dnssec-keygen/Makefile
index 3ac9005..1bdf0c0 100644
--- a/usr.sbin/dnssec-keygen/Makefile
+++ b/usr.sbin/dnssec-keygen/Makefile
@@ -17,6 +17,8 @@ CFLAGS+= -I${SRCDIR}/unix/include -I${SRCDIR}/include
DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
+WARNS?= 3
+
MAN= dnssec-keygen.8
.include <bsd.prog.mk>
diff --git a/usr.sbin/dnssec-signzone/Makefile b/usr.sbin/dnssec-signzone/Makefile
index 7c4ca65..70ddc3e 100644
--- a/usr.sbin/dnssec-signzone/Makefile
+++ b/usr.sbin/dnssec-signzone/Makefile
@@ -17,6 +17,8 @@ CFLAGS+= -I${SRCDIR}/unix/include -I${SRCDIR}/include
DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
+WARNS?= 3
+
MAN= dnssec-signzone.8
.include <bsd.prog.mk>
diff --git a/usr.sbin/dumpcis/Makefile b/usr.sbin/dumpcis/Makefile
index 283de3a..7a5a590 100644
--- a/usr.sbin/dumpcis/Makefile
+++ b/usr.sbin/dumpcis/Makefile
@@ -5,6 +5,5 @@
PROG= dumpcis
MAN= dumpcis.8
SRCS= main.c readcis.c printcis.c
-WARNS?= 5
.include <bsd.prog.mk>
diff --git a/usr.sbin/editmap/Makefile b/usr.sbin/editmap/Makefile
index 93e3e07..92d8392 100644
--- a/usr.sbin/editmap/Makefile
+++ b/usr.sbin/editmap/Makefile
@@ -10,6 +10,8 @@ MAN= editmap.8
CFLAGS+= -I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
CFLAGS+= -DNEWDB -DNOT_SENDMAIL
+WARNS?= 2
+
LIBSMDIR= ${.OBJDIR}/../../lib/libsm
LIBSM= ${LIBSMDIR}/libsm.a
diff --git a/usr.sbin/eeprom/Makefile b/usr.sbin/eeprom/Makefile
index fa5f411..61b48a2 100644
--- a/usr.sbin/eeprom/Makefile
+++ b/usr.sbin/eeprom/Makefile
@@ -6,7 +6,6 @@ PROG= eeprom
MAN= eeprom.8
MANSUBDIR= /sparc64
SRCS= eeprom.c ofw_options.c ofw_util.c
-WARNS?= 6
CFLAGS+= -I${.CURDIR}/../ofwdump
.include <bsd.prog.mk>
diff --git a/usr.sbin/eeprom/eeprom.8 b/usr.sbin/eeprom/eeprom.8
index 81cb2d3..e132da9 100644
--- a/usr.sbin/eeprom/eeprom.8
+++ b/usr.sbin/eeprom/eeprom.8
@@ -13,13 +13,6 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with 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 NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/usr.sbin/eeprom/eeprom.c b/usr.sbin/eeprom/eeprom.c
index ecd9267..30c1a93 100644
--- a/usr.sbin/eeprom/eeprom.c
+++ b/usr.sbin/eeprom/eeprom.c
@@ -13,13 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with 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 NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -146,7 +139,7 @@ action(char *line)
}
static void
-dump_config()
+dump_config(void)
{
ofwo_dump();
diff --git a/usr.sbin/extattr/Makefile b/usr.sbin/extattr/Makefile
index ae34975..8e2b5f7 100644
--- a/usr.sbin/extattr/Makefile
+++ b/usr.sbin/extattr/Makefile
@@ -11,6 +11,4 @@ MLINKS+= rmextattr.8 setextattr.8
MLINKS+= rmextattr.8 getextattr.8
MLINKS+= rmextattr.8 lsextattr.8
-WARNS?= 5
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/extattr/rmextattr.c b/usr.sbin/extattr/rmextattr.c
index 2b2689b..7ed92b6 100644
--- a/usr.sbin/extattr/rmextattr.c
+++ b/usr.sbin/extattr/rmextattr.c
@@ -269,7 +269,7 @@ main(int argc, char *argv[])
printf("\n");
continue;
} else {
- fwrite(buf, buflen, 1, stdout);
+ fwrite(buf, error, 1, stdout);
printf("\n");
continue;
}
diff --git a/usr.sbin/extattrctl/Makefile b/usr.sbin/extattrctl/Makefile
index 5eb1945..496a8aa 100644
--- a/usr.sbin/extattrctl/Makefile
+++ b/usr.sbin/extattrctl/Makefile
@@ -3,6 +3,4 @@
PROG= extattrctl
MAN= extattrctl.8
-WARNS?= 2
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/extattrctl/extattrctl.c b/usr.sbin/extattrctl/extattrctl.c
index 103fcd3..1929f79 100644
--- a/usr.sbin/extattrctl/extattrctl.c
+++ b/usr.sbin/extattrctl/extattrctl.c
@@ -54,7 +54,7 @@ long num_inodes_by_path(char *path);
void usage(void);
void
-usage()
+usage(void)
{
fprintf(stderr,
diff --git a/usr.sbin/faithd/Makefile b/usr.sbin/faithd/Makefile
index e1898ed..dec45b9 100644
--- a/usr.sbin/faithd/Makefile
+++ b/usr.sbin/faithd/Makefile
@@ -20,4 +20,6 @@ SRCS= faithd.c tcp.c ftp.c prefix.c
CFLAGS+= -DHAVE_POLL_H
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/faithd/faithd.8 b/usr.sbin/faithd/faithd.8
index 5d16989..25c118d 100644
--- a/usr.sbin/faithd/faithd.8
+++ b/usr.sbin/faithd/faithd.8
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 17, 1998
+.Dd January 9, 2010
.Dt FAITHD 8
.Os
.Sh NAME
@@ -44,20 +44,18 @@
.Sh DESCRIPTION
The
.Nm
-utility provides IPv6-to-IPv4 TCP relay.
-It must be used on an IPv4/v6 dual stack router.
+utility provides IPv6-to-IPv4 TCP relaying.
+It can only be used on an IPv4/v6 dual stack router.
.Pp
When
.Nm
receives
.Tn TCPv6
-traffic,
-.Nm
-will relay the
+traffic, it will relay the
.Tn TCPv6
traffic to
.Tn TCPv4 .
-Destination for relayed
+The destination for the relayed
.Tn TCPv4
connection will be determined by the last 4 octets of the original
.Tn IPv6
@@ -73,14 +71,14 @@ destination address is
the traffic will be relayed to IPv4 destination
.Li 10.1.1.1 .
.Pp
-To use
+To use the
.Nm
translation service,
an IPv6 address prefix must be reserved for mapping IPv4 addresses into.
-Kernel must be properly configured to route all the TCP connection
+The kernel must be properly configured to route all the TCP connections
toward the reserved IPv6 address prefix into the
.Xr faith 4
-pseudo interface, by using
+pseudo interface, using the
.Xr route 8
command.
Also,
@@ -91,7 +89,7 @@ to
.Dv 1 .
.Pp
The router must be configured to capture all the TCP traffic
-toward reserved
+for the reserved
.Tn IPv6
address prefix, by using
.Xr route 8
@@ -101,21 +99,20 @@ commands.
.Pp
The
.Nm
-utility needs a special name-to-address translation logic, so that
-hostnames gets resolved into special
+utility needs special name-to-address translation logic, so that
+hostnames get resolved into the special
.Tn IPv6
address prefix.
-For small-scale installation, use
-.Xr hosts 5 .
-For large-scale installation, it is useful to have
+For small-scale installations, use
+.Xr hosts 5 ;
+For large-scale installations, it is useful to have
a DNS server with special address translation support.
An implementation called
.Nm totd
-is available
-at
-.Pa http://www.vermicelli.pasta.cs.uit.no/ipv6/software.html .
-Make sure you do not propagate translated DNS records to normal DNS cloud,
-it is highly harmful.
+is available at
+.Pa http://www.vermicelli.pasta.cs.uit.no/software/totd.html .
+Make sure you do not propagate translated DNS records over to normal
+DNS, as it can cause severe problems.
.Ss Daemon mode
When
.Nm
@@ -150,9 +147,9 @@ to
you can run local daemons on the router.
The
.Nm
-utility will invoke local daemon at
+utility will invoke a local daemon at
.Ar serverpath
-if the destination address is local interface address,
+if the destination address is a local interface address,
and will perform translation to IPv4 TCP in other cases.
You can also specify
.Ar serverargs
@@ -182,7 +179,7 @@ The
.Nm
utility includes special support for protocols used by
.Xr ftp 1 .
-When translating FTP protocol,
+When translating the FTP protocol,
.Nm
translates network level addresses in
.Li PORT/LPRT/EPRT
@@ -191,8 +188,8 @@ and
commands.
.Pp
Inactive sessions will be disconnected in 30 minutes,
-to avoid stale sessions from chewing up resources.
-This may be inappropriate for some of the services
+to prevent stale sessions from chewing up resources.
+This may be inappropriate for some services
(should this be configurable?).
.Ss inetd mode
When
@@ -200,13 +197,13 @@ When
is invoked via
.Xr inetd 8 ,
.Nm
-will handle connection passed from standard input.
+will handle connections passed from standard input.
If the connection endpoint is in the reserved IPv6 address prefix,
.Nm
will relay the connection.
Otherwise,
.Nm
-will invoke service-specific daemon like
+will invoke a service-specific daemon like
.Xr telnetd 8 ,
by using the command argument passed from
.Xr inetd 8 .
@@ -219,16 +216,16 @@ For example, if
.Nm
is invoked via
.Xr inetd 8
-on FTP port, it will operate as a FTP relay.
+on the FTP port, it will operate as an FTP relay.
.Pp
The operation mode requires special support for
.Nm
in
.Xr inetd 8 .
.Ss Access control
-To prevent malicious accesses,
+To prevent malicious access,
.Nm
-implements a simple address-based access control.
+implements simple address-based access control.
With
.Pa /etc/faithd.conf
(or
@@ -239,7 +236,7 @@ specified by
will avoid relaying unwanted traffic.
The
.Pa faithd.conf
-contains directives with the following format:
+configuration file contains directives of the following format:
.Bl -bullet
.It
.Ar src Ns / Ns Ar slen Cm deny Ar dst Ns / Ns Ar dlen
@@ -281,6 +278,7 @@ on error.
.Sh EXAMPLES
Before invoking
.Nm ,
+the
.Xr faith 4
interface has to be configured properly.
.Bd -literal -offset
@@ -334,12 +332,12 @@ ssh stream tcp6/faith nowait root faithd /usr/sbin/sshd -i
.Ed
.Pp
.Xr inetd 8
-will open listening sockets with enabling kernel TCP relay support.
-Whenever connection comes in,
+will open listening sockets with kernel TCP relay support enabled.
+Whenever a connection comes in,
.Nm
will be invoked by
.Xr inetd 8 .
-If it the connection endpoint is in the reserved IPv6 address prefix.
+If the connection endpoint is in the reserved IPv6 address prefix.
The
.Nm
utility will relay the connection.
@@ -370,19 +368,19 @@ setting.
.%A Kazu Yamamoto
.%T "An IPv6-to-IPv4 transport relay translator"
.%B RFC3142
-.%O ftp://ftp.isi.edu/in-notes/rfc3142.txt
+.%U ftp://ftp.isi.edu/in-notes/rfc3142.txt
.%D June 2001
.Re
.\"
.Sh HISTORY
The
.Nm
-utility first appeared in WIDE Hydrangea IPv6 protocol stack kit.
+utility first appeared in the WIDE Hydrangea IPv6 protocol stack kit.
.\"
.Pp
IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
was initially integrated into
-.Fx 4.0
+.Fx 4.0 .
.Sh SECURITY CONSIDERATIONS
It is very insecure to use IP-address based authentication, for connections relayed by
.Nm ,
@@ -392,16 +390,15 @@ Administrators are advised to limit accesses to
.Nm
using
.Pa faithd.conf ,
-or by using IPv6 packet filters.
-It is to protect
+or by using IPv6 packet filters, to protect the
.Nm
-service from malicious parties and avoid theft of service/bandwidth.
-IPv6 destination address can be limited by
-carefully configuring routing entries that points to
+service from malicious parties, and to avoid theft of service/bandwidth.
+IPv6 destination addresses can be limited by
+carefully configuring routing entries that point to
.Xr faith 4 ,
using
.Xr route 8 .
-IPv6 source address needs to be filtered by using packet filters.
-Documents listed in
+The IPv6 source address needs to be filtered using packet filters.
+The documents listed in
.Sx SEE ALSO
-have more discussions on this topic.
+have more information on this topic.
diff --git a/usr.sbin/faithd/faithd.c b/usr.sbin/faithd/faithd.c
index f192fbd..9caf0e9 100644
--- a/usr.sbin/faithd/faithd.c
+++ b/usr.sbin/faithd/faithd.c
@@ -791,7 +791,7 @@ exit_success(const char *fmt, ...)
#ifdef USE_ROUTE
static void
-grab_myaddrs()
+grab_myaddrs(void)
{
struct ifaddrs *ifap, *ifa;
struct myaddrs *p;
@@ -847,7 +847,7 @@ grab_myaddrs()
}
static void
-free_myaddrs()
+free_myaddrs(void)
{
struct myaddrs *p, *q;
@@ -861,7 +861,7 @@ free_myaddrs()
}
static void
-update_myaddrs()
+update_myaddrs(void)
{
char msg[BUFSIZ];
int len;
@@ -900,7 +900,7 @@ update_myaddrs()
#endif /*USE_ROUTE*/
static void
-usage()
+usage(void)
{
fprintf(stderr, "usage: %s [-dp] [-f conf] service [serverpath [serverargs]]\n",
faithdname);
diff --git a/usr.sbin/fdcontrol/Makefile b/usr.sbin/fdcontrol/Makefile
index e2b54aa..5f1426b 100644
--- a/usr.sbin/fdcontrol/Makefile
+++ b/usr.sbin/fdcontrol/Makefile
@@ -4,7 +4,6 @@
PROG= fdcontrol
SRCS= fdcontrol.c fdutil.c
-WARNS?= 6
CFLAGS+= -I${.CURDIR}/../fdread
MAN= fdcontrol.8
diff --git a/usr.sbin/fdformat/Makefile b/usr.sbin/fdformat/Makefile
index a172811..59cd124 100644
--- a/usr.sbin/fdformat/Makefile
+++ b/usr.sbin/fdformat/Makefile
@@ -5,7 +5,6 @@
PROG= fdformat
SRCS= fdformat.c fdutil.c
-WARNS?= 6
CFLAGS+= -I${.CURDIR}/../fdread
.if ${MACHINE} == "pc98"
diff --git a/usr.sbin/fdread/Makefile b/usr.sbin/fdread/Makefile
index 2868a3c..e99c620 100644
--- a/usr.sbin/fdread/Makefile
+++ b/usr.sbin/fdread/Makefile
@@ -3,8 +3,6 @@
PROG= fdread
SRCS= fdread.c fdutil.c
-WARNS?= 6
-
.if ${MACHINE} == "pc98"
CFLAGS+= -DPC98
.endif
diff --git a/usr.sbin/fdwrite/Makefile b/usr.sbin/fdwrite/Makefile
index ba6f047..b97bdd4 100644
--- a/usr.sbin/fdwrite/Makefile
+++ b/usr.sbin/fdwrite/Makefile
@@ -8,6 +8,5 @@
# $FreeBSD$
PROG= fdwrite
-WARNS?= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/fifolog/Makefile.inc b/usr.sbin/fifolog/Makefile.inc
index 7fb2a9e..5ec27dd 100644
--- a/usr.sbin/fifolog/Makefile.inc
+++ b/usr.sbin/fifolog/Makefile.inc
@@ -2,8 +2,6 @@
LIBFIFOLOG= ${.OBJDIR}/../lib/libfifolog.a
-WARNS?= 6
-
#LINT= flint
#LINTFLAGS= ${.CURDIR}/../flint.lnt -I/usr/include
diff --git a/usr.sbin/fifolog/fifolog_writer/fifolog_writer.c b/usr.sbin/fifolog/fifolog_writer/fifolog_writer.c
index fd10711..346297f 100644
--- a/usr.sbin/fifolog/fifolog_writer/fifolog_writer.c
+++ b/usr.sbin/fifolog/fifolog_writer/fifolog_writer.c
@@ -42,7 +42,7 @@
static void
usage(void)
{
- fprintf(stderr, "fifolog_writer [-w write-rate] [-s sync-rate] "
+ fprintf(stderr, "Usage: fifolog_writer [-w write-rate] [-s sync-rate] "
"[-z compression] file\n");
exit(EX_USAGE);
}
diff --git a/usr.sbin/fifolog/lib/getdate.y b/usr.sbin/fifolog/lib/getdate.y
index 93b5b6b..8e63e81 100644
--- a/usr.sbin/fifolog/lib/getdate.y
+++ b/usr.sbin/fifolog/lib/getdate.y
@@ -762,7 +762,7 @@ LookupWord(char *buff)
static int
-yylex()
+yylex(void)
{
char c;
char *p;
diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh
index 2eacca8..e1453c6 100644
--- a/usr.sbin/freebsd-update/freebsd-update.sh
+++ b/usr.sbin/freebsd-update/freebsd-update.sh
@@ -284,6 +284,9 @@ config_TargetRelease () {
else
return 1
fi
+ if echo ${TARGETRELEASE} | grep -qE '^[0-9.]+$'; then
+ TARGETRELEASE="${TARGETRELEASE}-RELEASE"
+ fi
}
# Define what happens to output of utilities
@@ -600,6 +603,7 @@ fetch_check_params () {
echo ${WORKDIR}
exit 1
fi
+ chmod 700 ${WORKDIR}
cd ${WORKDIR} || exit 1
# Generate release number. The s/SECURITY/RELEASE/ bit exists
diff --git a/usr.sbin/ftp-proxy/Makefile.inc b/usr.sbin/ftp-proxy/Makefile.inc
index 5abb7c0..9043d09 100644
--- a/usr.sbin/ftp-proxy/Makefile.inc
+++ b/usr.sbin/ftp-proxy/Makefile.inc
@@ -2,4 +2,4 @@
LIBEVENT= ${.OBJDIR}/../libevent/libevent.a
-.include "../Makefile.inc" \ No newline at end of file
+.include "../Makefile.inc"
diff --git a/usr.sbin/ftp-proxy/libevent/Makefile b/usr.sbin/ftp-proxy/libevent/Makefile
index acc546f..a8ff09b 100644
--- a/usr.sbin/ftp-proxy/libevent/Makefile
+++ b/usr.sbin/ftp-proxy/libevent/Makefile
@@ -22,4 +22,6 @@ CFLAGS+= -I${.CURDIR} \
-DHAVE_WORKING_KQUEUE \
-DVERSION='"1.3b"'
+WARNS?= 2
+
.include <bsd.lib.mk>
diff --git a/usr.sbin/getfmac/Makefile b/usr.sbin/getfmac/Makefile
index ad49657..f9fa1b2 100644
--- a/usr.sbin/getfmac/Makefile
+++ b/usr.sbin/getfmac/Makefile
@@ -3,6 +3,4 @@
PROG= getfmac
MAN= getfmac.8
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/getpmac/Makefile b/usr.sbin/getpmac/Makefile
index 87e6d28..5974728 100644
--- a/usr.sbin/getpmac/Makefile
+++ b/usr.sbin/getpmac/Makefile
@@ -3,6 +3,4 @@
PROG= getpmac
MAN= getpmac.8
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/gstat/Makefile b/usr.sbin/gstat/Makefile
index a02cf46..2a6da40 100644
--- a/usr.sbin/gstat/Makefile
+++ b/usr.sbin/gstat/Makefile
@@ -2,7 +2,6 @@
PROG= gstat
MAN= gstat.8
-WARNS?= 5
DPADD= ${LIBDEVSTAT} ${LIBKVM} ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} ${LIBEDIT} ${LIBCURSES}
LDADD= -ldevstat -lkvm -lgeom -lbsdxml -lsbuf -ledit -lcurses
diff --git a/usr.sbin/i2c/i2c.8 b/usr.sbin/i2c/i2c.8
index 0067be7..e2bea3c 100644
--- a/usr.sbin/i2c/i2c.8
+++ b/usr.sbin/i2c/i2c.8
@@ -26,7 +26,7 @@
.\" $FreeBSD$
.\"
-.Dd Jan 23, 2009
+.Dd January 23, 2009
.Dt I2C 8
.Os
.Sh NAME
diff --git a/usr.sbin/inetd/Makefile b/usr.sbin/inetd/Makefile
index 35f2c22..29aacd1 100644
--- a/usr.sbin/inetd/Makefile
+++ b/usr.sbin/inetd/Makefile
@@ -8,7 +8,7 @@ MAN= inetd.8
MLINKS= inetd.8 inetd.conf.5
SRCS= inetd.c builtins.c
-WARNS?= 2
+WARNS?= 3
CFLAGS+= -DLOGIN_CAP
#CFLAGS+= -DSANITY_CHECK
diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c
index 6bcbac6..0a39fdf 100644
--- a/usr.sbin/inetd/inetd.c
+++ b/usr.sbin/inetd/inetd.c
@@ -110,6 +110,7 @@ __FBSDID("$FreeBSD$");
*/
#include <sys/param.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
@@ -497,6 +498,9 @@ main(int argc, char **argv)
}
}
+ if (madvise(NULL, 0, MADV_PROTECT) != 0)
+ syslog(LOG_WARNING, "madvise() failed: %s", strerror(errno));
+
for (i = 0; i < PERIPSIZE; ++i)
LIST_INIT(&proctable[i]);
@@ -1393,8 +1397,7 @@ setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
#ifdef IPSEC
void
-ipsecsetup(sep)
- struct servtab *sep;
+ipsecsetup(struct servtab *sep)
{
char *buf;
char *policy_in = NULL;
diff --git a/usr.sbin/iostat/Makefile b/usr.sbin/iostat/Makefile
index 558b09b..9fd4809 100644
--- a/usr.sbin/iostat/Makefile
+++ b/usr.sbin/iostat/Makefile
@@ -7,4 +7,6 @@ MAN= iostat.8
DPADD= ${LIBDEVSTAT} ${LIBKVM} ${LIBM}
LDADD= -ldevstat -lkvm -lm
+WARNS?= 1
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/ip6addrctl/Makefile b/usr.sbin/ip6addrctl/Makefile
index cd2510e..93a2990 100644
--- a/usr.sbin/ip6addrctl/Makefile
+++ b/usr.sbin/ip6addrctl/Makefile
@@ -3,4 +3,6 @@
PROG= ip6addrctl
MAN= ip6addrctl.8
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/ipfwpcap/Makefile b/usr.sbin/ipfwpcap/Makefile
index 5615eb1..d16f888 100644
--- a/usr.sbin/ipfwpcap/Makefile
+++ b/usr.sbin/ipfwpcap/Makefile
@@ -11,8 +11,6 @@ DPADD= ${LIBPCAP}
MAN= ipfwpcap.8
-WARNS?= 6
-
.include <bsd.prog.mk>
test: $(CMD)
diff --git a/usr.sbin/jail/Makefile b/usr.sbin/jail/Makefile
index 74fd6c4..de35dcf 100644
--- a/usr.sbin/jail/Makefile
+++ b/usr.sbin/jail/Makefile
@@ -7,8 +7,6 @@ MAN= jail.8
DPADD= ${LIBJAIL} ${LIBUTIL}
LDADD= -ljail -lutil
-WARNS?= 6
-
.if ${MK_INET6_SUPPORT} != "no"
CFLAGS+= -DINET6
.endif
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index f3340bd..77f1b95 100644
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -34,7 +34,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 25, 2009
+.Dd January 17, 2010
.Dt JAIL 8
.Os
.Sh NAME
@@ -252,6 +252,13 @@ match.
It is only possible to start multiple jails with the same IP address,
if none of the jails has more than this single overlapping IP address
assigned to itself.
+.It Va ip4.saddrsel
+A boolean option to change the formerly mentioned behaviour and disable
+IPv4 source address selection for the prison in favour of the primary
+IPv4 address of the jail.
+Source address selection is enabled by default for all jails and a
+.Va ip4.nosaddrsel
+setting of a parent jail is not inherited for any child jails.
.It Va ip4
Control the availablity of IPv4 addresses.
Possible values are
@@ -267,9 +274,10 @@ Setting the
.Va ip4.addr
parameter implies a value of
.Dq new .
-.It Va ip6.addr , Va ip6
-A list of IPv6 addresses assigned to the prison, the counterpart to
-.Va ip4.addr
+.It Va ip6.addr , Va ip6.saddrsel , Va ip6
+A set of IPv6 options for the prison, the counterparts to
+.Va ip4.addr ,
+.Va ip4.saddrsel
and
.Va ip4
above.
@@ -377,7 +385,7 @@ Since raw sockets can be used to configure and interact with various
network subsystems, extra caution should be used where privileged access
to jails is given out to untrusted parties.
.It Va allow.chflags
-Normally, priveleged users inside a jail are treated as unprivileged by
+Normally, privileged users inside a jail are treated as unprivileged by
.Xr chflags 2 .
When this parameter is set, such users are treated as privileged, and
may manipulate system file flags subject to the usual constraints on
@@ -561,7 +569,7 @@ or for running a virtual server.
Start a shell in the jail:
.Pp
.Bd -literal -offset indent
-jail path=/data/jail/192.0.2.100 host.hostname=testhostname \\
+jail -c path=/data/jail/192.0.2.100 host.hostname=testhostname \\
ip4.addr=192.0.2.100 command=/bin/sh
.Ed
.Pp
@@ -636,7 +644,7 @@ script from within the jail.
.Bd -literal -offset indent
ifconfig ed0 inet alias 192.0.2.100/32
mount -t procfs proc /data/jail/192.0.2.100/proc
-jail path=/data/jail/192.0.2.100 host.hostname=testhostname \\
+jail -c path=/data/jail/192.0.2.100 host.hostname=testhostname \\
ip4.addr=192.0.2.100 command=/bin/sh /etc/rc
.Ed
.Pp
diff --git a/usr.sbin/jexec/Makefile b/usr.sbin/jexec/Makefile
index d55ea0fc..7a2e6821 100644
--- a/usr.sbin/jexec/Makefile
+++ b/usr.sbin/jexec/Makefile
@@ -4,6 +4,5 @@ PROG= jexec
MAN= jexec.8
DPADD= ${LIBJAIL} ${LIBUTIL}
LDADD= -ljail -lutil
-WARNS?= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/jls/Makefile b/usr.sbin/jls/Makefile
index 2d02c56..e1157af 100644
--- a/usr.sbin/jls/Makefile
+++ b/usr.sbin/jls/Makefile
@@ -5,6 +5,4 @@ MAN= jls.8
DPADD= ${LIBJAIL}
LDADD= -ljail
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/jls/jls.c b/usr.sbin/jls/jls.c
index 0661ee3..3f4800c 100644
--- a/usr.sbin/jls/jls.c
+++ b/usr.sbin/jls/jls.c
@@ -425,11 +425,6 @@ print_jail(int pflags, int jflags)
if (params[i].jp_flags & JP_USER)
free(param_values[i]);
}
- for (i = 0; i < nparams; i++)
- if (!(params[i].jp_flags & JP_RAWVALUE)) {
- free(params[i].jp_value);
- params[i].jp_value = NULL;
- }
return (jid);
}
diff --git a/usr.sbin/kbdcontrol/kbdcontrol.c b/usr.sbin/kbdcontrol/kbdcontrol.c
index 5d20b16..280faa1 100644
--- a/usr.sbin/kbdcontrol/kbdcontrol.c
+++ b/usr.sbin/kbdcontrol/kbdcontrol.c
@@ -1148,7 +1148,7 @@ mux_keyboard(u_int op, char *kbd)
}
void
-usage()
+usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n",
"usage: kbdcontrol [-dFKix] [-A name] [-a name] [-b duration.pitch | [quiet.]belltype]",
diff --git a/usr.sbin/kernbb/Makefile b/usr.sbin/kernbb/Makefile
index 7da462b..f3bf37c 100644
--- a/usr.sbin/kernbb/Makefile
+++ b/usr.sbin/kernbb/Makefile
@@ -8,6 +8,5 @@ LDADD= -lkvm
CFLAGS+= -I${.CURDIR}/../../contrib/gcc
-WARNS?= 3
.include <bsd.prog.mk>
diff --git a/usr.sbin/lastlogin/Makefile b/usr.sbin/lastlogin/Makefile
index 017aadf..715badd 100644
--- a/usr.sbin/lastlogin/Makefile
+++ b/usr.sbin/lastlogin/Makefile
@@ -3,6 +3,4 @@
PROG= lastlogin
MAN= lastlogin.8
-WARNS?= 2
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/lastlogin/lastlogin.8 b/usr.sbin/lastlogin/lastlogin.8
index 03a587d..4d07a2b 100644
--- a/usr.sbin/lastlogin/lastlogin.8
+++ b/usr.sbin/lastlogin/lastlogin.8
@@ -64,13 +64,13 @@ utility differs from
in that it only prints information regarding the very last login session.
The last login database is never turned over or deleted in standard usage.
.Sh FILES
-.Bl -tag -width /var/log/lastlog -compact
-.It Pa /var/log/lastlog
+.Bl -tag -width /var/log/utx.lastlogin -compact
+.It Pa /var/log/utx.lastlogin
last login database
.El
.Sh SEE ALSO
.Xr last 1 ,
-.Xr lastlog 5 ,
+.Xr getutxent 3 ,
.Xr ac 8
.Sh AUTHORS
.An John M. Vinopal
diff --git a/usr.sbin/lastlogin/lastlogin.c b/usr.sbin/lastlogin/lastlogin.c
index 21c82c3..a1b5b6e 100644
--- a/usr.sbin/lastlogin/lastlogin.c
+++ b/usr.sbin/lastlogin/lastlogin.c
@@ -36,98 +36,67 @@ __RCSID("$FreeBSD$");
__RCSID("$NetBSD: lastlogin.c,v 1.4 1998/02/03 04:45:35 perry Exp $");
#endif
-#include <sys/types.h>
#include <err.h>
-#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
-#include <timeconv.h>
-#include <utmp.h>
#include <unistd.h>
-
-static const char *logfile = _PATH_LASTLOG;
+#include <utmpx.h>
int main(int, char **);
-static void output(struct passwd *, struct lastlog *);
+static void output(struct utmpx *);
static void usage(void);
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(int argc, char *argv[])
{
int ch, i;
- FILE *fp;
- struct passwd *passwd;
- struct lastlog last;
+ struct utmpx *u;
while ((ch = getopt(argc, argv, "")) != -1) {
usage();
}
- fp = fopen(logfile, "r");
- if (fp == NULL)
- err(1, "%s", logfile);
-
- setpassent(1); /* Keep passwd file pointers open */
-
/* Process usernames given on the command line. */
if (argc > 1) {
- long offset;
for (i = 1; i < argc; ++i) {
- if ((passwd = getpwnam(argv[i])) == NULL) {
+ if (setutxdb(UTXDB_LASTLOGIN, NULL) != 0)
+ errx(1, "failed to open lastlog database");
+ if ((u = getutxuser(argv[i])) == NULL) {
warnx("user '%s' not found", argv[i]);
continue;
}
- /* Calculate the offset into the lastlog file. */
- offset = (long)(passwd->pw_uid * sizeof(last));
- if (fseek(fp, offset, SEEK_SET)) {
- warn("fseek error");
- continue;
- }
- if (fread(&last, sizeof(last), 1, fp) != 1) {
- warnx("fread error on '%s'", passwd->pw_name);
- clearerr(fp);
- continue;
- }
- output(passwd, &last);
+ output(u);
+ endutxent();
}
}
/* Read all lastlog entries, looking for active ones */
else {
- for (i = 0; fread(&last, sizeof(last), 1, fp) == 1; i++) {
- if (last.ll_time == 0)
+ if (setutxdb(UTXDB_LASTLOGIN, NULL) != 0)
+ errx(1, "failed to open lastlog database");
+ while ((u = getutxent()) != NULL) {
+ if (u->ut_type != USER_PROCESS)
continue;
- if ((passwd = getpwuid((uid_t)i)) != NULL)
- output(passwd, &last);
+ output(u);
}
- if (ferror(fp))
- warnx("fread error");
+ endutxent();
}
- setpassent(0); /* Close passwd file pointers */
-
- fclose(fp);
exit(0);
}
/* Duplicate the output of last(1) */
static void
-output(p, l)
- struct passwd *p;
- struct lastlog *l;
+output(struct utmpx *u)
{
- time_t t = _int_to_time(l->ll_time);
- printf("%-*.*s %-*.*s %-*.*s %s",
- UT_NAMESIZE, UT_NAMESIZE, p->pw_name,
- UT_LINESIZE, UT_LINESIZE, l->ll_line,
- UT_HOSTSIZE, UT_HOSTSIZE, l->ll_host,
- (l->ll_time) ? ctime(&t) : "Never logged in\n");
+ time_t t = u->ut_tv.tv_sec;
+
+ printf("%-10s %-8s %-22s %s",
+ u->ut_user, u->ut_line, u->ut_host, ctime(&t));
}
static void
-usage()
+usage(void)
{
fprintf(stderr, "usage: lastlogin [user ...]\n");
exit(1);
diff --git a/usr.sbin/lmcconfig/Makefile b/usr.sbin/lmcconfig/Makefile
index b75ec2c..842431a 100644
--- a/usr.sbin/lmcconfig/Makefile
+++ b/usr.sbin/lmcconfig/Makefile
@@ -6,4 +6,6 @@ MAN= lmcconfig.8
DPADD= ${LIBNETGRAPH}
LDADD= -lnetgraph
+WARNS?= 0
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/lpr/common_source/Makefile b/usr.sbin/lpr/common_source/Makefile
index 14db0b7..4f148f9 100644
--- a/usr.sbin/lpr/common_source/Makefile
+++ b/usr.sbin/lpr/common_source/Makefile
@@ -10,4 +10,6 @@ INTERNALLIB=
SRCS= common.c ctlinfo.c displayq.c matchjobs.c net.c \
printcap.c request.c rmjob.c startdaemon.c
+WARNS?= 1
+
.include <bsd.lib.mk>
diff --git a/usr.sbin/lpr/common_source/lp.h b/usr.sbin/lpr/common_source/lp.h
index 891ed2f..63f2ff1 100644
--- a/usr.sbin/lpr/common_source/lp.h
+++ b/usr.sbin/lpr/common_source/lp.h
@@ -280,7 +280,7 @@ void inform(const struct printer *_pp, char *_cf);
void init_printer(struct printer *_pp);
void init_request(struct request *_rp);
int inlist(char *_uname, char *_cfile);
-int iscf(struct dirent *_d);
+int iscf(const struct dirent *_d);
void ldump(const char *_nfile, const char *_datafile, int _copies);
void lastprinter(void);
int lockchk(struct printer *_pp, char *_slockf);
diff --git a/usr.sbin/lpr/common_source/rmjob.c b/usr.sbin/lpr/common_source/rmjob.c
index d6fd614..33fcdac 100644
--- a/usr.sbin/lpr/common_source/rmjob.c
+++ b/usr.sbin/lpr/common_source/rmjob.c
@@ -384,7 +384,7 @@ rmremote(const struct printer *pp)
* Return 1 if the filename begins with 'cf'
*/
int
-iscf(struct dirent *d)
+iscf(const struct dirent *d)
{
return(d->d_name[0] == 'c' && d->d_name[1] == 'f');
}
diff --git a/usr.sbin/lpr/filters.ru/Makefile.inc b/usr.sbin/lpr/filters.ru/Makefile.inc
index a312e73..36a6f46 100644
--- a/usr.sbin/lpr/filters.ru/Makefile.inc
+++ b/usr.sbin/lpr/filters.ru/Makefile.inc
@@ -1,3 +1,5 @@
# $FreeBSD$
BINDIR= /usr/libexec/lpr/ru
+
+WARNS?= 3
diff --git a/usr.sbin/lpr/lp/lp.sh b/usr.sbin/lpr/lp/lp.sh
index 03ad887..dbec053 100644
--- a/usr.sbin/lpr/lp/lp.sh
+++ b/usr.sbin/lpr/lp/lp.sh
@@ -70,7 +70,7 @@ do
s) # (silent option)
: ;;
t) # title for banner page
- title="-J${OPTARG}";;
+ title="${OPTARG}";;
*) # (error msg printed by getopts)
exit 2;;
esac
@@ -78,4 +78,4 @@ done
shift $(($OPTIND - 1))
-exec /usr/bin/lpr "-P${dest}" ${symlink} ${ncopies} ${mailafter} "${title}" "$@"
+exec /usr/bin/lpr "-P${dest}" ${symlink} ${ncopies} ${mailafter} ${title:+-J"${title}"} "$@"
diff --git a/usr.sbin/lpr/lpc/Makefile b/usr.sbin/lpr/lpc/Makefile
index f050857..35fa52a 100644
--- a/usr.sbin/lpr/lpc/Makefile
+++ b/usr.sbin/lpr/lpc/Makefile
@@ -11,6 +11,8 @@ BINMODE= 2555
CFLAGS+= -I${.CURDIR}/../common_source
+WARNS?= 0
+
DPADD= ${LIBLPR} ${LIBEDIT} ${LIBTERMCAP}
LDADD= ${LIBLPR} -ledit -ltermcap
diff --git a/usr.sbin/lpr/lpd/Makefile b/usr.sbin/lpr/lpd/Makefile
index 9af3655..0d7d93e 100644
--- a/usr.sbin/lpr/lpd/Makefile
+++ b/usr.sbin/lpr/lpd/Makefile
@@ -7,6 +7,8 @@ SRCS= lpd.c printjob.c recvjob.c lpdchar.c modes.c
CFLAGS+= -I${.CURDIR}/../common_source
+WARNS?= 1
+
DPADD= ${LIBLPR}
LDADD= ${LIBLPR}
diff --git a/usr.sbin/lpr/lpr/Makefile b/usr.sbin/lpr/lpr/Makefile
index 1ff376d..1894b00 100644
--- a/usr.sbin/lpr/lpr/Makefile
+++ b/usr.sbin/lpr/lpr/Makefile
@@ -13,6 +13,8 @@ BINMODE= 6555
CFLAGS+= -I${.CURDIR}/../common_source
+WARNS?= 2
+
DPADD= ${LIBLPR}
LDADD= ${LIBLPR}
diff --git a/usr.sbin/lptcontrol/Makefile b/usr.sbin/lptcontrol/Makefile
index 3f7a939..0cff620 100644
--- a/usr.sbin/lptcontrol/Makefile
+++ b/usr.sbin/lptcontrol/Makefile
@@ -3,6 +3,4 @@
PROG= lptcontrol
MAN= lptcontrol.8
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/mailstats/Makefile b/usr.sbin/mailstats/Makefile
index 86137b0..bd72fc6 100644
--- a/usr.sbin/mailstats/Makefile
+++ b/usr.sbin/mailstats/Makefile
@@ -11,6 +11,8 @@ MAN= mailstats.8
CFLAGS+= -I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
CFLAGS+= -DNOT_SENDMAIL
+WARNS?= 2
+
LIBSMDIR= ${.OBJDIR}/../../lib/libsm
LIBSM= ${LIBSMDIR}/libsm.a
diff --git a/usr.sbin/mailwrapper/Makefile b/usr.sbin/mailwrapper/Makefile
index 252f5e7..3f305f7 100644
--- a/usr.sbin/mailwrapper/Makefile
+++ b/usr.sbin/mailwrapper/Makefile
@@ -8,7 +8,6 @@ MAN= mailwrapper.8
DPADD= ${LIBUTIL}
LDADD= -lutil
-WARNS?= 6
.endif
.if ${MK_MAILWRAPPER} != "no" || ${MK_SENDMAIL} != "no"
diff --git a/usr.sbin/makefs/compat/pwcache.c b/usr.sbin/makefs/compat/pwcache.c
index 0579d26..d0c45c2 100644
--- a/usr.sbin/makefs/compat/pwcache.c
+++ b/usr.sbin/makefs/compat/pwcache.c
@@ -45,13 +45,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with 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 NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/usr.sbin/makefs/compat/strsuftoll.c b/usr.sbin/makefs/compat/strsuftoll.c
index f73e3ad..657e525 100644
--- a/usr.sbin/makefs/compat/strsuftoll.c
+++ b/usr.sbin/makefs/compat/strsuftoll.c
@@ -14,13 +14,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with 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 NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/usr.sbin/makefs/getid.c b/usr.sbin/makefs/getid.c
index ca52fa3..939d943 100644
--- a/usr.sbin/makefs/getid.c
+++ b/usr.sbin/makefs/getid.c
@@ -46,13 +46,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with 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 NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/usr.sbin/makefs/makefs.8 b/usr.sbin/makefs/makefs.8
index 101366a..6c1615c 100644
--- a/usr.sbin/makefs/makefs.8
+++ b/usr.sbin/makefs/makefs.8
@@ -159,7 +159,7 @@ free files (inodes) exist in the image.
An optional
.Ql %
suffix may be provided to indicate that
-.Ar free-blocks
+.Ar free-files
indicates a percentage of the calculated image size
.It Fl F Ar specfile
Use
diff --git a/usr.sbin/makemap/Makefile b/usr.sbin/makemap/Makefile
index 5d30c67..80cafcb 100644
--- a/usr.sbin/makemap/Makefile
+++ b/usr.sbin/makemap/Makefile
@@ -11,6 +11,8 @@ MAN= makemap.8
CFLAGS+= -I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
CFLAGS+= -DNEWDB -DNOT_SENDMAIL
+WARNS?= 2
+
LIBSMDIR= ${.OBJDIR}/../../lib/libsm
LIBSM= ${LIBSMDIR}/libsm.a
diff --git a/usr.sbin/memcontrol/Makefile b/usr.sbin/memcontrol/Makefile
index 25009db..d465d53 100644
--- a/usr.sbin/memcontrol/Makefile
+++ b/usr.sbin/memcontrol/Makefile
@@ -2,6 +2,5 @@
PROG= memcontrol
MAN= memcontrol.8
-WARNS?= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/mergemaster/mergemaster.8 b/usr.sbin/mergemaster/mergemaster.8
index 2bff4be..a56897c 100644
--- a/usr.sbin/mergemaster/mergemaster.8
+++ b/usr.sbin/mergemaster/mergemaster.8
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1998-2009 Douglas Barton
+.\" Copyright (c) 1998-2010 Douglas Barton
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 18, 2009
+.Dd January 7, 2010
.Dt MERGEMASTER 8
.Os
.Sh NAME
@@ -61,10 +61,10 @@ down, populating that environment with the various
files.
You can specify a different source directory
with the
-.Op Fl m
+.Fl m
command line option, or specify the destination
directory with the
-.Op Fl D
+.Fl D
option.
It then compares each file in that environment
to its installed counterpart.
@@ -91,10 +91,10 @@ compares the files themselves.
You can
also specify that the script ignore the Id strings and
compare every file with the
-.Op Fl s
+.Fl s
option.
Using the
-.Op Fl F
+.Fl F
option
.Nm
will install the new file for you if they differ only by
@@ -126,7 +126,7 @@ installing an updated version of this file you should
probably run
.Xr pwd_mkdb 8
with the
-.Op Fl p
+.Fl p
option to rebuild your password databases
and recreate
.Pa /etc/passwd .
@@ -165,6 +165,14 @@ which will be read before
Options specified on the command line are updated last,
and therefore can override both files.
.Pp
+When the comparison is done if there are any files remaining
+in the temproot directory they will be listed, and if the
+.Fl a
+option is not in use the user will be given the option of
+deleting the temproot directory.
+If there are no files remaining in the temproot directory
+it will be deleted.
+.Pp
The options are as follows:
.Bl -tag -width Fl
.It Fl s
@@ -198,11 +206,13 @@ If the
directory exists, it creates a new one in a previously
non-existent directory.
This option unsets the verbose flag,
-but is compatible with all other options.
+but other than
+.Fl U
+it is compatible with all other options.
Setting
-.Op Fl a
+.Fl a
makes
-.Op Fl w
+.Fl w
superfluous.
.It Fl h
Display usage and help information.
@@ -253,7 +263,7 @@ instead of the default
Add the date and time to the name of the temporary
root directory.
If
-.Op Fl t
+.Fl t
is specified, this option must
follow it if you want the date added too.
.It Fl u Ar N
@@ -320,44 +330,44 @@ with all values commented out:
# These are options for mergemaster, with their default values listed
# The following options have command line overrides
#
-# The target architecture (unset by default)
+# The target architecture (-A, unset by default)
#ARCHSTRING='TARGET_ARCH=<foo>'
#
-# Sourcedir is the directory to do the 'make' in (where the new files are)
+# Sourcedir is the directory to do the 'make' in (-m)
#SOURCEDIR='/usr/src'
#
-# Directory to install the temporary root environment into
+# Directory to install the temporary root environment into (-t)
#TEMPROOT='/var/tmp/temproot'
#
-# Specify the destination directory for the installed files
+# Specify the destination directory for the installed files (-D)
#DESTDIR=
#
-# Strict comparison skips the VCS Id test and compares every file
+# Strict comparison skips the VCS Id test and compares every file (-s)
#STRICT=no
#
-# Type of diff, such as unified, context, etc.
+# Type of diff, such as unified, context, etc. (-c)
#DIFF_FLAG='-u'
#
-# Install the new file if it differs only by VCS Id ($FreeBSD)
+# Install the new file if it differs only by VCS Id ($FreeBSD, -F)
#FREEBSD_ID=
#
-# Verbose mode includes more details and additional checks
+# Verbose mode includes more details and additional checks (-v)
#VERBOSE=
#
-# Automatically install files that do not exist on the system already
+# Automatically install files that do not exist on the system already (-i)
#AUTO_INSTALL=
#
-# Automatically upgrade files that have not been user modified
+# Automatically upgrade files that have not been user modified (-U)
#AUTO_UPGRADE=
#
-# Compare /etc/rc.conf[.local] to /etc/defaults/rc.conf
-#COMP_CONFS=yes
+# Compare /etc/rc.conf[.local] to /etc/defaults/rc.conf (-C)
+#COMP_CONFS=
#
-# Preserve files that you replace
-#PRESERVE_FILES=yes
+# Preserve files that you replace (-P)
+#PRESERVE_FILES=
#PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S`
#
-# The umask for mergemaster to compare the default file's modes to
+# The umask for mergemaster to compare the default file's modes to (-u)
#NEW_UMASK=022
#
# The following options have no command line overrides
@@ -377,6 +387,9 @@ with all values commented out:
# If you set 'yes' above, make sure to include the PATH to your pager
#PATH=/bin:/usr/bin:/usr/sbin
#
+# Delete stale files in /etc/rc.d without prompting
+#DELETE_STALE_RC_FILES=
+#
# Specify the path to scripts to run before the comparison starts,
# and/or after the script has finished its work
#MM_PRE_COMPARE_SCRIPT=
@@ -430,7 +443,7 @@ comparison, use:
.Pp
.Pa /usr/src/etc/Makefile
.Rs
-.%O http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html
+.%U http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html
.%T The Cutting Edge (using make world)
.%A Nik Clayton
.Re
diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh
index 4d2ffc0..2fa9906 100755
--- a/usr.sbin/mergemaster/mergemaster.sh
+++ b/usr.sbin/mergemaster/mergemaster.sh
@@ -5,7 +5,7 @@
# Compare files created by /usr/src/etc/Makefile (or the directory
# the user specifies) with the currently installed copies.
-# Copyright 1998-2009 Douglas Barton
+# Copyright 1998-2010 Douglas Barton
# DougB@FreeBSD.org
# $FreeBSD$
@@ -261,11 +261,6 @@ if [ -r "$HOME/.mergemasterrc" ]; then
. "$HOME/.mergemasterrc"
fi
-# Assign the location of the mtree database
-#
-MTREEDB=${MTREEDB:-/var/db}
-MTREEFILE="${MTREEDB}/mergemaster.mtree"
-
# Check the command line options
#
while getopts ":ascrvhipCPm:t:du:w:D:A:FU" COMMAND_LINE_ARGUMENT ; do
@@ -342,21 +337,32 @@ while getopts ":ascrvhipCPm:t:du:w:D:A:FU" COMMAND_LINE_ARGUMENT ; do
esac
done
+# Assign the location of the mtree database
+#
+MTREEDB=${MTREEDB:-${DESTDIR}/var/db}
+MTREEFILE="${MTREEDB}/mergemaster.mtree"
+
# Don't force the user to set this in the mergemaster rc file
if [ -n "${PRESERVE_FILES}" -a -z "${PRESERVE_FILES_DIR}" ]; then
PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S`
+ mkdir -p ${PRESERVE_FILES_DIR}
fi
# Check for the mtree database in DESTDIR
case "${AUTO_UPGRADE}" in
'') ;; # If the option is not set no need to run the test or warn the user
*)
- if [ ! -s "${DESTDIR}${MTREEFILE}" ]; then
+ if [ ! -s "${MTREEFILE}" ]; then
echo ''
- echo "*** Unable to find mtree database. Skipping auto-upgrade on this run."
+ echo "*** Unable to find mtree database (${MTREEFILE})."
+ echo " Skipping auto-upgrade on this run."
echo " It will be created for the next run when this one is complete."
echo ''
- press_to_continue
+ case "${AUTO_RUN}" in
+ '')
+ press_to_continue
+ ;;
+ esac
unset AUTO_UPGRADE
fi
;;
@@ -463,9 +469,9 @@ MM_MAKE="make ${ARCHSTRING} -m ${SOURCEDIR}/share/mk"
# Check DESTDIR against the mergemaster mtree database to see what
# files the user changed from the reference files.
#
-if [ -n "${AUTO_UPGRADE}" -a -s "${DESTDIR}${MTREEFILE}" ]; then
+if [ -n "${AUTO_UPGRADE}" -a -s "${MTREEFILE}" ]; then
CHANGED=:
- for file in `mtree -eqL -f ${DESTDIR}${MTREEFILE} -p ${DESTDIR}/ \
+ for file in `mtree -eqL -f ${MTREEFILE} -p ${DESTDIR}/ \
2>/dev/null | awk '($2 == "changed") {print $1}'`; do
if [ -f "${DESTDIR}/$file" ]; then
CHANGED="${CHANGED}${DESTDIR}/${file}:"
@@ -505,7 +511,7 @@ CVS_ID_TAG=FreeBSD
delete_temproot () {
rm -rf "${TEMPROOT}" 2>/dev/null
chflags -R 0 "${TEMPROOT}" 2>/dev/null
- rm -rf "${TEMPROOT}" || exit 1
+ rm -rf "${TEMPROOT}" || { echo "*** Unable to delete ${TEMPROOT}"; exit 1; }
}
case "${RERUN}" in
@@ -536,7 +542,7 @@ case "${RERUN}" in
echo ''
echo " *** Deleting the old ${TEMPROOT}"
echo ''
- delete_temproot || exit 1
+ delete_temproot
unset TEST_TEMP_ROOT
;;
[tT])
@@ -645,17 +651,15 @@ case "${RERUN}" in
;;
esac
- # Avoid comparing the motd if the user specifies it in .mergemasterrc
- # Compatibility shim to be removed in FreeBSD 9.x
case "${IGNORE_MOTD}" in
'') ;;
- *) IGNORE_FILES="${IGNORE_FILES} /etc/motd"
+ *)
echo ''
echo "*** You have the IGNORE_MOTD option set in your mergemaster rc file."
echo " This option is deprecated in favor of the IGNORE_FILES option."
echo " Please update your rc file accordingly."
echo ''
- press_to_continue
+ exit 1
;;
esac
@@ -663,31 +667,32 @@ case "${RERUN}" in
for file in ${IGNORE_FILES}; do
test -e ${TEMPROOT}/${file} && unlink ${TEMPROOT}/${file}
done
- ;; # End of the "RERUN" test
-esac
-# We really don't want to have to deal with files like login.conf.db, pwd.db,
-# or spwd.db. Instead, we want to compare the text versions, and run *_mkdb.
-# Prompt the user to do so below, as needed.
-#
-rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd
+ # We really don't want to have to deal with files like login.conf.db, pwd.db,
+ # or spwd.db. Instead, we want to compare the text versions, and run *_mkdb.
+ # Prompt the user to do so below, as needed.
+ #
+ rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd
-# We only need to compare things like freebsd.cf once
-find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null
+ # We only need to compare things like freebsd.cf once
+ find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null
-# Delete stuff we do not need to keep the mtree database small,
-# and to make the actual comparison faster.
-find ${TEMPROOT}/usr -type l -delete 2>/dev/null
-find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null
-find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null
+ # Delete stuff we do not need to keep the mtree database small,
+ # and to make the actual comparison faster.
+ find ${TEMPROOT}/usr -type l -delete 2>/dev/null
+ find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null
+ find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null
-# Build the mtree database in a temporary location.
-MTREENEW=`mktemp -t mergemaster.mtree`
-case "${PRE_WORLD}" in
-'') mtree -ci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null
- ;;
-*) # We don't want to mess with the mtree database on a pre-world run.
- ;;
+ # Build the mtree database in a temporary location.
+ case "${PRE_WORLD}" in
+ '') MTREENEW=`mktemp -t mergemaster.mtree`
+ mtree -ci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null
+ ;;
+ *) # We don't want to mess with the mtree database on a pre-world run or
+ # when re-scanning a previously-built tree.
+ ;;
+ esac
+ ;; # End of the "RERUN" test
esac
# Get ready to start comparing files
@@ -818,7 +823,8 @@ mm_install () {
if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then
DIR_MODE=`find_mode "${TEMPROOT}/${INSTALL_DIR}"`
- install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}"
+ install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}" ||
+ install_error $1 ${DESTDIR}${INSTALL_DIR}
fi
FILE_MODE=`find_mode "${1}"`
@@ -837,32 +843,39 @@ mm_install () {
DONT_INSTALL=yes
;;
/.cshrc | /.profile)
- case "${AUTO_INSTALL}" in
- '')
- case "${LINK_EXPLAINED}" in
- '')
- echo " *** Historically BSD derived systems have had a"
- echo " hard link from /.cshrc and /.profile to"
- echo " their namesakes in /root. Please indicate"
- echo " your preference below for bringing your"
- echo " installed files up to date."
- echo ''
- LINK_EXPLAINED=yes
- ;;
- esac
+ local st_nlink
- echo " Use 'd' to delete the temporary ${COMPFILE}"
- echo " Use 'l' to delete the existing ${DESTDIR}${COMPFILE#.} and create the link"
- echo ''
- echo " Default is to leave the temporary file to deal with by hand"
- echo ''
- echo -n " How should I handle ${COMPFILE}? [Leave it to install later] "
- read HANDLE_LINK
- ;;
- *) # Part of AUTO_INSTALL
- HANDLE_LINK=l
- ;;
- esac
+ # install will unlink the file before it installs the new one,
+ # so we have to restore/create the link afterwards.
+ #
+ st_nlink=0 # In case the file does not yet exist
+ eval $(stat -s ${DESTDIR}${COMPFILE#.} 2>/dev/null)
+
+ do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
+
+ if [ -n "${AUTO_INSTALL}" -a $st_nlink -gt 1 ]; then
+ HANDLE_LINK=l
+ else
+ case "${LINK_EXPLAINED}" in
+ '')
+ echo " *** Historically BSD derived systems have had a"
+ echo " hard link from /.cshrc and /.profile to"
+ echo " their namesakes in /root. Please indicate"
+ echo " your preference below for bringing your"
+ echo " installed files up to date."
+ echo ''
+ LINK_EXPLAINED=yes
+ ;;
+ esac
+
+ echo " Use 'd' to delete the temporary ${COMPFILE}"
+ echo " Use 'l' to delete the existing ${DESTDIR}/root/${COMPFILE##*/} and create the link"
+ echo ''
+ echo " Default is to leave the temporary file to deal with by hand"
+ echo ''
+ echo -n " How should I handle ${COMPFILE}? [Leave it to install later] "
+ read HANDLE_LINK
+ fi
case "${HANDLE_LINK}" in
[dD]*)
@@ -872,19 +885,19 @@ mm_install () {
;;
[lL]*)
echo ''
- rm -f "${DESTDIR}${COMPFILE#.}"
- if ln "${DESTDIR}/root/${COMPFILE##*/}" "${DESTDIR}${COMPFILE#.}"; then
+ unlink ${DESTDIR}/root/${COMPFILE##*/}
+ if ln ${DESTDIR}${COMPFILE#.} ${DESTDIR}/root/${COMPFILE##*/}; then
echo " *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully"
- rm "${COMPFILE}"
else
- echo " *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand"
+ echo " *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}"
+ echo " *** ${COMPFILE} will remain for your consideration"
fi
;;
*)
echo " *** ${COMPFILE} will remain for your consideration"
;;
esac
- DONT_INSTALL=yes
+ return
;;
esac
@@ -955,6 +968,12 @@ if [ -z "${PRE_WORLD}" -a -z "${RERUN}" ]; then
esac
sleep 2
;;
+ *)
+ if [ -n "${DELETE_STALE_RC_FILES}" ]; then
+ echo ' *** Deleting ... '
+ rm ${STALE_RC_FILES}
+ echo ' done.'
+ fi
esac
;;
esac
@@ -967,7 +986,58 @@ if [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then
. "${MM_PRE_COMPARE_SCRIPT}"
fi
-for COMPFILE in `find . -type f`; do
+# Things that were files/directories/links in one version can sometimes
+# change to something else in a newer version. So we need to explicitly
+# test for this, and warn the user if what we find does not match.
+#
+for COMPFILE in `find . | sort` ; do
+ if [ -e "${DESTDIR}${COMPFILE#.}" ]; then
+ INSTALLED_TYPE=`stat -f '%HT' ${DESTDIR}${COMPFILE#.}`
+ else
+ continue
+ fi
+ TEMPROOT_TYPE=`stat -f '%HT' $COMPFILE`
+
+ if [ ! "$TEMPROOT_TYPE" = "$INSTALLED_TYPE" ]; then
+ [ "$COMPFILE" = '.' ] && continue
+ TEMPROOT_TYPE=`echo $TEMPROOT_TYPE | tr [:upper:] [:lower:]`
+ INSTALLED_TYPE=`echo $INSTALLED_TYPE | tr [:upper:] [:lower:]`
+
+ echo "*** The installed file ${DESTDIR}${COMPFILE#.} has the type \"$INSTALLED_TYPE\""
+ echo " but the new version has the type \"$TEMPROOT_TYPE\""
+ echo ''
+ echo " How would you like to handle this?"
+ echo ''
+ echo " Use 'r' to remove ${DESTDIR}${COMPFILE#.}"
+ case "$TEMPROOT_TYPE" in
+ 'symbolic link')
+ TARGET=`readlink $COMPFILE`
+ echo " and create a link to $TARGET in its place" ;;
+ *) echo " You will be able to install it as a \"$TEMPROOT_TYPE\"" ;;
+ esac
+ echo ''
+ echo " Use 'i' to ignore this"
+ echo ''
+ echo -n " How to proceed? [i] "
+ read ANSWER
+ case "$ANSWER" in
+ [rR]) case "${PRESERVE_FILES}" in
+ [Yy][Ee][Ss])
+ mv ${DESTDIR}${COMPFILE#.} ${PRESERVE_FILES_DIR}/ || exit 1 ;;
+ *) rm -rf ${DESTDIR}${COMPFILE#.} ;;
+ esac
+ case "$TEMPROOT_TYPE" in
+ 'symbolic link') ln -sf $TARGET ${DESTDIR}${COMPFILE#.} ;;
+ esac ;;
+ *) echo ''
+ echo "*** See the man page about adding ${COMPFILE#.} to the list of IGNORE_FILES"
+ press_to_continue ;;
+ esac
+ echo ''
+ fi
+done
+
+for COMPFILE in `find . -type f | sort`; do
# First, check to see if the file exists in DESTDIR. If not, the
# diff_loop function knows how to handle it.
@@ -1032,7 +1102,7 @@ for COMPFILE in `find . -type f`; do
# If the user chose the -F option, test for that before proceeding
#
if [ -n "$FREEBSD_ID" ]; then
- if diff -q -I'[$]FreeBSD:.*$' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \
+ if diff -q -I'[$]FreeBSD.*[$]' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \
/dev/null 2>&1; then
if mm_install "${COMPFILE}"; then
echo "*** Updated revision control Id for ${DESTDIR}${COMPFILE#.}"
@@ -1061,8 +1131,8 @@ echo "*** Comparison complete"
if [ -s "${MTREENEW}" ]; then
echo "*** Saving mtree database for future upgrades"
- test -e "${DESTDIR}${MTREEFILE}" && unlink ${DESTDIR}${MTREEFILE}
- mv ${MTREENEW} ${DESTDIR}${MTREEFILE}
+ test -e "${MTREEFILE}" && unlink ${MTREEFILE}
+ mv ${MTREENEW} ${MTREEFILE}
fi
echo ''
@@ -1070,30 +1140,28 @@ echo ''
TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null`
if [ -n "${TEST_FOR_FILES}" ]; then
echo "*** Files that remain for you to merge by hand:"
- find "${TEMPROOT}" -type f -size +0
+ find "${TEMPROOT}" -type f -size +0 | sort
echo ''
-fi
-
-case "${AUTO_RUN}" in
-'')
- echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] "
- read DEL_TEMPROOT
- case "${DEL_TEMPROOT}" in
- [yY]*)
- if delete_temproot; then
- echo " *** ${TEMPROOT} has been deleted"
- else
- echo " *** Unable to delete ${TEMPROOT}"
- fi
- ;;
- *)
- echo " *** ${TEMPROOT} will remain"
+ case "${AUTO_RUN}" in
+ '')
+ echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] "
+ read DEL_TEMPROOT
+ case "${DEL_TEMPROOT}" in
+ [yY]*)
+ delete_temproot
+ ;;
+ *)
+ echo " *** ${TEMPROOT} will remain"
+ ;;
+ esac
;;
+ *) ;;
esac
- ;;
-*) ;;
-esac
+else
+ echo "*** ${TEMPROOT} is empty, deleting"
+ delete_temproot
+fi
case "${AUTO_INSTALLED_FILES}" in
'') ;;
@@ -1268,5 +1336,9 @@ case "${PRE_WORLD}" in
;;
esac
-exit 0
+if [ -n "${PRESERVE_FILES}" ]; then
+ find -d $PRESERVE_FILES_DIR -type d -empty -delete 2>/dev/null
+ rmdir $PRESERVE_FILES_DIR 2>/dev/null
+fi
+exit 0
diff --git a/usr.sbin/mfiutil/Makefile b/usr.sbin/mfiutil/Makefile
index 03ded03..dbf158d 100644
--- a/usr.sbin/mfiutil/Makefile
+++ b/usr.sbin/mfiutil/Makefile
@@ -8,6 +8,7 @@ MAN8= mfiutil.8
CFLAGS+= -fno-builtin-strftime
WARNS?=3
+DPADD= ${LIBUTIL}
LDADD= -lutil
# Here be dragons
diff --git a/usr.sbin/mixer/Makefile b/usr.sbin/mixer/Makefile
index deb3539..abc0182 100644
--- a/usr.sbin/mixer/Makefile
+++ b/usr.sbin/mixer/Makefile
@@ -3,6 +3,4 @@
PROG= mixer
MAN= mixer.8
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/mld6query/Makefile b/usr.sbin/mld6query/Makefile
index 0e9da49..1d4b443 100644
--- a/usr.sbin/mld6query/Makefile
+++ b/usr.sbin/mld6query/Makefile
@@ -20,4 +20,6 @@ SRCS= mld6.c
CFLAGS+= -DIPSEC -DUSE_RFC2292BIS
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/mlxcontrol/Makefile b/usr.sbin/mlxcontrol/Makefile
index 95964a5..038544b 100644
--- a/usr.sbin/mlxcontrol/Makefile
+++ b/usr.sbin/mlxcontrol/Makefile
@@ -6,4 +6,6 @@ SRCS= command.c config.c interface.c util.c
CFLAGS+= -I${.CURDIR}/../../sys
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/mount_portalfs/mount_portalfs.c b/usr.sbin/mount_portalfs/mount_portalfs.c
index 8f61efc..3c37b95 100644
--- a/usr.sbin/mount_portalfs/mount_portalfs.c
+++ b/usr.sbin/mount_portalfs/mount_portalfs.c
@@ -272,7 +272,7 @@ main(int argc, char *argv[])
}
static void
-usage()
+usage(void)
{
(void)fprintf(stderr,
"usage: mount_portalfs [-o options] config mount-point\n");
diff --git a/usr.sbin/mount_smbfs/Makefile b/usr.sbin/mount_smbfs/Makefile
index ade4fad..9b73944 100644
--- a/usr.sbin/mount_smbfs/Makefile
+++ b/usr.sbin/mount_smbfs/Makefile
@@ -2,7 +2,6 @@
PROG= mount_smbfs
SRCS= mount_smbfs.c getmntopts.c
-WARNS?= 6
MAN= mount_smbfs.8
MOUNTDIR= ${.CURDIR}/../../sbin/mount
diff --git a/usr.sbin/mountd/exports.5 b/usr.sbin/mountd/exports.5
index 93d0cec..c8a3b70 100644
--- a/usr.sbin/mountd/exports.5
+++ b/usr.sbin/mountd/exports.5
@@ -28,7 +28,7 @@
.\" @(#)exports.5 8.3 (Berkeley) 3/29/95
.\" $FreeBSD$
.\"
-.Dd June 30, 2008
+.Dd December 3, 2009
.Dt EXPORTS 5
.Os
.Sh NAME
@@ -473,6 +473,7 @@ operations on the server, so long as valid Kerberos credentials are provided.
The machine grumpy.cis.uoguelph.ca is permitted to perform NFSv4 state
operations on the server using AUTH_SYS credentials, as well as Kerberos ones.
.Sh SEE ALSO
+.Xr nfsv4 4 ,
.Xr netgroup 5 ,
.Xr mountd 8 ,
.Xr nfsd 8 ,
diff --git a/usr.sbin/moused/Makefile b/usr.sbin/moused/Makefile
index 623954e..a313a21 100644
--- a/usr.sbin/moused/Makefile
+++ b/usr.sbin/moused/Makefile
@@ -3,8 +3,6 @@
PROG= moused
MAN= moused.8
-WARNS?=6
-
DPADD= ${LIBUTIL} ${LIBM}
LDADD= -lutil -lm
diff --git a/usr.sbin/mptable/Makefile b/usr.sbin/mptable/Makefile
index a9221f9..cff7602 100644
--- a/usr.sbin/mptable/Makefile
+++ b/usr.sbin/mptable/Makefile
@@ -1,6 +1,5 @@
# $FreeBSD$
PROG= mptable
-WARNS?= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/mptable/mptable.c b/usr.sbin/mptable/mptable.c
index 1ca6dfe..a16a1b9 100644
--- a/usr.sbin/mptable/mptable.c
+++ b/usr.sbin/mptable/mptable.c
@@ -147,7 +147,7 @@ tableEntry basetableEntryTypes[] =
tableEntry extendedtableEntryTypes[] =
{
{ 128, 20, "System Address Space" },
- { 129, 8, "Bus Heirarchy" },
+ { 129, 8, "Bus Hierarchy" },
{ 130, 8, "Compatibility Bus Address" }
};
diff --git a/usr.sbin/mptutil/Makefile b/usr.sbin/mptutil/Makefile
index 4abf66e..53d75b3 100644
--- a/usr.sbin/mptutil/Makefile
+++ b/usr.sbin/mptutil/Makefile
@@ -8,8 +8,8 @@ MAN= mptutil.8
WARNS?= 3
-DPADD+= ${LIBCAM} ${LIBUTIL}
-LDADD+= -lcam -lutil
+DPADD= ${LIBCAM} ${LIBSBUF} ${LIBUTIL}
+LDADD= -lcam -lsbuf -lutil
# Here be dragons
.ifdef DEBUG
diff --git a/usr.sbin/mptutil/mpt_cam.c b/usr.sbin/mptutil/mpt_cam.c
index 0d20c7d..b14451a 100644
--- a/usr.sbin/mptutil/mpt_cam.c
+++ b/usr.sbin/mptutil/mpt_cam.c
@@ -56,15 +56,75 @@ xpt_open(void)
return (xptfd);
}
+/* Fetch the path id of bus 0 for the opened mpt controller. */
+static int
+fetch_path_id(path_id_t *path_id)
+{
+ struct bus_match_pattern *b;
+ union ccb ccb;
+ size_t bufsize;
+
+ if (xpt_open() < 0)
+ return (ENXIO);
+
+ /* First, find the path id of bus 0 for this mpt controller. */
+ bzero(&ccb, sizeof(ccb));
+
+ ccb.ccb_h.func_code = XPT_DEV_MATCH;
+
+ bufsize = sizeof(struct dev_match_result) * 1;
+ ccb.cdm.num_matches = 0;
+ ccb.cdm.match_buf_len = bufsize;
+ ccb.cdm.matches = calloc(1, bufsize);
+
+ bufsize = sizeof(struct dev_match_pattern) * 1;
+ ccb.cdm.num_patterns = 1;
+ ccb.cdm.pattern_buf_len = bufsize;
+ ccb.cdm.patterns = calloc(1, bufsize);
+
+ /* Match mptX bus 0. */
+ ccb.cdm.patterns[0].type = DEV_MATCH_BUS;
+ b = &ccb.cdm.patterns[0].pattern.bus_pattern;
+ snprintf(b->dev_name, sizeof(b->dev_name), "mpt");
+ b->unit_number = mpt_unit;
+ b->bus_id = 0;
+ b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID;
+
+ if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) {
+ free(ccb.cdm.matches);
+ free(ccb.cdm.patterns);
+ return (errno);
+ }
+ free(ccb.cdm.patterns);
+
+ if (((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) ||
+ (ccb.cdm.status != CAM_DEV_MATCH_LAST)) {
+ warnx("fetch_path_id got CAM error %#x, CDM error %d\n",
+ ccb.ccb_h.status, ccb.cdm.status);
+ free(ccb.cdm.matches);
+ return (EIO);
+ }
+
+ /* We should have exactly 1 match for the bus. */
+ if (ccb.cdm.num_matches != 1 ||
+ ccb.cdm.matches[0].type != DEV_MATCH_BUS) {
+ free(ccb.cdm.matches);
+ return (ENOENT);
+ }
+ *path_id = ccb.cdm.matches[0].result.bus_result.path_id;
+ free(ccb.cdm.matches);
+ return (0);
+}
+
int
mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd)
{
- struct bus_match_pattern *b;
struct periph_match_pattern *p;
struct periph_match_result *r;
union ccb ccb;
+ path_id_t path_id;
size_t bufsize;
- int i;
+ int error, i;
/* mpt(4) only handles devices on bus 0. */
if (VolumeBus != 0)
@@ -73,6 +133,11 @@ mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd)
if (xpt_open() < 0)
return (ENXIO);
+ /* Find the path ID of bus 0. */
+ error = fetch_path_id(&path_id);
+ if (error)
+ return (error);
+
bzero(&ccb, sizeof(ccb));
ccb.ccb_h.func_code = XPT_DEV_MATCH;
@@ -85,25 +150,18 @@ mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd)
ccb.cdm.match_buf_len = bufsize;
ccb.cdm.matches = calloc(1, bufsize);
- bufsize = sizeof(struct dev_match_pattern) * 2;
- ccb.cdm.num_patterns = 2;
+ bufsize = sizeof(struct dev_match_pattern) * 1;
+ ccb.cdm.num_patterns = 1;
ccb.cdm.pattern_buf_len = bufsize;
ccb.cdm.patterns = calloc(1, bufsize);
- /* Match mptX bus 0. */
- ccb.cdm.patterns[0].type = DEV_MATCH_BUS;
- b = &ccb.cdm.patterns[0].pattern.bus_pattern;
- snprintf(b->dev_name, sizeof(b->dev_name), "mpt");
- b->unit_number = mpt_unit;
- b->bus_id = 0;
- b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID;
-
/* Look for a "da" device at the specified target and lun. */
- ccb.cdm.patterns[1].type = DEV_MATCH_PERIPH;
- p = &ccb.cdm.patterns[1].pattern.periph_pattern;
+ ccb.cdm.patterns[0].type = DEV_MATCH_PERIPH;
+ p = &ccb.cdm.patterns[0].pattern.periph_pattern;
+ p->path_id = path_id;
snprintf(p->periph_name, sizeof(p->periph_name), "da");
p->target_id = VolumeID;
- p->flags = PERIPH_MATCH_NAME | PERIPH_MATCH_TARGET;
+ p->flags = PERIPH_MATCH_PATH | PERIPH_MATCH_NAME | PERIPH_MATCH_TARGET;
if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) {
i = errno;
@@ -122,25 +180,22 @@ mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd)
}
/*
- * We should have exactly 2 matches, 1 for the bus and 1 for
- * the peripheral. However, if we only have 1 match and it is
- * for the bus, don't print an error message and return
- * ENOENT.
+ * We should have exactly 1 match for the peripheral.
+ * However, if we don't get a match, don't print an error
+ * message and return ENOENT.
*/
- if (ccb.cdm.num_matches == 1 &&
- ccb.cdm.matches[0].type == DEV_MATCH_BUS) {
+ if (ccb.cdm.num_matches == 0) {
free(ccb.cdm.matches);
return (ENOENT);
}
- if (ccb.cdm.num_matches != 2) {
- warnx("mpt_query_disk got %d matches, expected 2",
+ if (ccb.cdm.num_matches != 1) {
+ warnx("mpt_query_disk got %d matches, expected 1",
ccb.cdm.num_matches);
free(ccb.cdm.matches);
return (EIO);
}
- if (ccb.cdm.matches[0].type != DEV_MATCH_BUS ||
- ccb.cdm.matches[1].type != DEV_MATCH_PERIPH) {
- warnx("mpt_query_disk got wrong CAM matches");
+ if (ccb.cdm.matches[0].type != DEV_MATCH_PERIPH) {
+ warnx("mpt_query_disk got wrong CAM match");
free(ccb.cdm.matches);
return (EIO);
}
@@ -336,47 +391,44 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp)
{
CONFIG_PAGE_IOC_2 *ioc2;
struct mpt_standalone_disk *disks;
- struct bus_match_pattern *b;
struct periph_match_pattern *p;
struct periph_match_result *r;
struct cam_device *dev;
union ccb ccb;
+ path_id_t path_id;
size_t bufsize;
u_int i;
- int count;
+ int count, error;
if (xpt_open() < 0)
return (ENXIO);
+ error = fetch_path_id(&path_id);
+ if (error)
+ return (error);
+
for (count = 100;; count+= 100) {
/* Try to fetch 'count' disks in one go. */
bzero(&ccb, sizeof(ccb));
ccb.ccb_h.func_code = XPT_DEV_MATCH;
- bufsize = sizeof(struct dev_match_result) * (count + 2);
+ bufsize = sizeof(struct dev_match_result) * (count + 1);
ccb.cdm.num_matches = 0;
ccb.cdm.match_buf_len = bufsize;
ccb.cdm.matches = calloc(1, bufsize);
- bufsize = sizeof(struct dev_match_pattern) * 2;
- ccb.cdm.num_patterns = 2;
+ bufsize = sizeof(struct dev_match_pattern) * 1;
+ ccb.cdm.num_patterns = 1;
ccb.cdm.pattern_buf_len = bufsize;
ccb.cdm.patterns = calloc(1, bufsize);
- /* Match mptX bus 0. */
- ccb.cdm.patterns[0].type = DEV_MATCH_BUS;
- b = &ccb.cdm.patterns[0].pattern.bus_pattern;
- snprintf(b->dev_name, sizeof(b->dev_name), "mpt");
- b->unit_number = mpt_unit;
- b->bus_id = 0;
- b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID;
-
/* Match any "da" peripherals. */
- ccb.cdm.patterns[1].type = DEV_MATCH_PERIPH;
- p = &ccb.cdm.patterns[1].pattern.periph_pattern;
+ ccb.cdm.patterns[0].type = DEV_MATCH_PERIPH;
+ p = &ccb.cdm.patterns[0].pattern.periph_pattern;
+ p->path_id = path_id;
snprintf(p->periph_name, sizeof(p->periph_name), "da");
- p->flags = PERIPH_MATCH_NAME;
+ p->flags = PERIPH_MATCH_PATH | PERIPH_MATCH_NAME;
if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) {
i = errno;
@@ -406,21 +458,16 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp)
break;
}
- /*
- * We should have N + 1 matches, 1 for the bus and 1 for each
- * "da" device.
- */
- if (ccb.cdm.num_matches < 1) {
- warnx("mpt_fetch_disks didn't get any matches");
- free(ccb.cdm.matches);
- return (EIO);
- }
- if (ccb.cdm.matches[0].type != DEV_MATCH_BUS) {
- warnx("mpt_fetch_disks got wrong CAM matches");
+ /* Shortcut if we don't have any "da" devices. */
+ if (ccb.cdm.num_matches == 0) {
free(ccb.cdm.matches);
- return (EIO);
+ *ndisks = 0;
+ *disksp = NULL;
+ return (0);
}
- for (i = 1; i < ccb.cdm.num_matches; i++) {
+
+ /* We should have N matches, 1 for each "da" device. */
+ for (i = 0; i < ccb.cdm.num_matches; i++) {
if (ccb.cdm.matches[i].type != DEV_MATCH_PERIPH) {
warnx("mpt_fetch_disks got wrong CAM matches");
free(ccb.cdm.matches);
@@ -428,14 +475,6 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp)
}
}
- /* Shortcut if we don't have any "da" devices. */
- if (ccb.cdm.num_matches == 1) {
- free(ccb.cdm.matches);
- *ndisks = 0;
- *disksp = NULL;
- return (0);
- }
-
/*
* Some of the "da" peripherals may be for RAID volumes, so
* fetch the IOC 2 page (list of RAID volumes) so we can
@@ -444,7 +483,7 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp)
ioc2 = mpt_read_ioc_page(fd, 2, NULL);
disks = calloc(ccb.cdm.num_matches, sizeof(*disks));
count = 0;
- for (i = 1; i < ccb.cdm.num_matches; i++) {
+ for (i = 0; i < ccb.cdm.num_matches; i++) {
r = &ccb.cdm.matches[i].result.periph_result;
if (periph_is_volume(ioc2, r))
continue;
@@ -480,10 +519,9 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp)
int
mpt_rescan_bus(int bus, int id)
{
- struct bus_match_pattern *b;
union ccb ccb;
path_id_t path_id;
- size_t bufsize;
+ int error;
/* mpt(4) only handles devices on bus 0. */
if (bus != -1 && bus != 0)
@@ -492,54 +530,12 @@ mpt_rescan_bus(int bus, int id)
if (xpt_open() < 0)
return (ENXIO);
- /* First, find the path id of bus 0 for this mpt controller. */
- bzero(&ccb, sizeof(ccb));
-
- ccb.ccb_h.func_code = XPT_DEV_MATCH;
-
- bufsize = sizeof(struct dev_match_result) * 1;
- ccb.cdm.num_matches = 0;
- ccb.cdm.match_buf_len = bufsize;
- ccb.cdm.matches = calloc(1, bufsize);
-
- bufsize = sizeof(struct dev_match_pattern) * 1;
- ccb.cdm.num_patterns = 1;
- ccb.cdm.pattern_buf_len = bufsize;
- ccb.cdm.patterns = calloc(1, bufsize);
-
- /* Match mptX bus 0. */
- ccb.cdm.patterns[0].type = DEV_MATCH_BUS;
- b = &ccb.cdm.patterns[0].pattern.bus_pattern;
- snprintf(b->dev_name, sizeof(b->dev_name), "mpt");
- b->unit_number = mpt_unit;
- b->bus_id = 0;
- b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID;
-
- if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) {
- free(ccb.cdm.matches);
- free(ccb.cdm.patterns);
- return (errno);
- }
- free(ccb.cdm.patterns);
-
- if (((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) ||
- (ccb.cdm.status != CAM_DEV_MATCH_LAST)) {
- warnx("mpt_rescan_bus got CAM error %#x, CDM error %d\n",
- ccb.ccb_h.status, ccb.cdm.status);
- free(ccb.cdm.matches);
- return (EIO);
- }
-
- /* We should have exactly 1 match for the bus. */
- if (ccb.cdm.num_matches != 1 ||
- ccb.cdm.matches[0].type != DEV_MATCH_BUS) {
- free(ccb.cdm.matches);
- return (ENOENT);
- }
- path_id = ccb.cdm.matches[0].result.bus_result.path_id;
- free(ccb.cdm.matches);
+ error = fetch_path_id(&path_id);
+ if (error)
+ return (error);
- /* Now perform the actual rescan. */
+ /* Perform the actual rescan. */
+ bzero(&ccb, sizeof(ccb));
ccb.ccb_h.path_id = path_id;
if (id == -1) {
ccb.ccb_h.func_code = XPT_SCAN_BUS;
diff --git a/usr.sbin/mptutil/mpt_show.c b/usr.sbin/mptutil/mpt_show.c
index e0b6b74..5a2a946 100644
--- a/usr.sbin/mptutil/mpt_show.c
+++ b/usr.sbin/mptutil/mpt_show.c
@@ -78,6 +78,7 @@ show_adapter(int ac, char **av)
CONFIG_PAGE_MANUFACTURING_0 *man0;
CONFIG_PAGE_IOC_2 *ioc2;
CONFIG_PAGE_IOC_6 *ioc6;
+ U16 IOCStatus;
int fd, comma;
if (ac != 1) {
@@ -108,7 +109,7 @@ show_adapter(int ac, char **av)
free(man0);
- ioc2 = mpt_read_ioc_page(fd, 2, NULL);
+ ioc2 = mpt_read_ioc_page(fd, 2, &IOCStatus);
if (ioc2 != NULL) {
printf(" RAID Levels:");
comma = 0;
@@ -151,9 +152,11 @@ show_adapter(int ac, char **av)
printf(" none");
printf("\n");
free(ioc2);
- }
+ } else if ((IOCStatus & MPI_IOCSTATUS_MASK) !=
+ MPI_IOCSTATUS_CONFIG_INVALID_PAGE)
+ warnx("mpt_read_ioc_page(2): %s", mpt_ioc_status(IOCStatus));
- ioc6 = mpt_read_ioc_page(fd, 6, NULL);
+ ioc6 = mpt_read_ioc_page(fd, 6, &IOCStatus);
if (ioc6 != NULL) {
display_stripe_map(" RAID0 Stripes",
ioc6->SupportedStripeSizeMapIS);
@@ -172,7 +175,9 @@ show_adapter(int ac, char **av)
printf("-%u", ioc6->MaxDrivesIME);
printf("\n");
free(ioc6);
- }
+ } else if ((IOCStatus & MPI_IOCSTATUS_MASK) !=
+ MPI_IOCSTATUS_CONFIG_INVALID_PAGE)
+ warnx("mpt_read_ioc_page(6): %s", mpt_ioc_status(IOCStatus));
/* TODO: Add an ioctl to fetch IOC_FACTS and print firmware version. */
@@ -541,7 +546,8 @@ show_physdisks(int ac, char **av)
for (i = 0; i <= 0xff; i++) {
pinfo = mpt_pd_info(fd, i, &IOCStatus);
if (pinfo == NULL) {
- if (IOCStatus != MPI_IOCSTATUS_CONFIG_INVALID_PAGE)
+ if ((IOCStatus & MPI_IOCSTATUS_MASK) !=
+ MPI_IOCSTATUS_CONFIG_INVALID_PAGE)
warnx("mpt_pd_info(%d): %s", i,
mpt_ioc_status(IOCStatus));
continue;
diff --git a/usr.sbin/mtree/Makefile b/usr.sbin/mtree/Makefile
index b66c8bb..cbc4fd9 100644
--- a/usr.sbin/mtree/Makefile
+++ b/usr.sbin/mtree/Makefile
@@ -8,8 +8,6 @@ MAN= mtree.8 mtree.5
SRCS= compare.c crc.c create.c excludes.c misc.c mtree.c spec.c verify.c
SRCS+= specspec.c
-WARNS?= 4
-
CFLAGS+= -DMD5 -DSHA1 -DRMD160 -DSHA256
DPADD= ${LIBMD}
LDADD= -lmd
diff --git a/usr.sbin/mtree/mtree.5 b/usr.sbin/mtree/mtree.5
index 375cc78..8f17d90 100644
--- a/usr.sbin/mtree/mtree.5
+++ b/usr.sbin/mtree/mtree.5
@@ -33,12 +33,12 @@
.Os
.Sh NAME
.Nm mtree
-.Nd format of mtree dir heirarchy files
+.Nd format of mtree dir hierarchy files
.Sh DESCRIPTION
The
.Nm
format is a textual format that describes a collection of filesystem objects.
-Such files are typically used to create or verify directory heirarchies.
+Such files are typically used to create or verify directory hierarchies.
.Ss General Format
An
.Nm
diff --git a/usr.sbin/named-checkconf/Makefile b/usr.sbin/named-checkconf/Makefile
index 8728b4a..618cc13 100644
--- a/usr.sbin/named-checkconf/Makefile
+++ b/usr.sbin/named-checkconf/Makefile
@@ -14,6 +14,8 @@ SRCS+= named-checkconf.c check-tool.c
CFLAGS+= -I${LIB_BIND_DIR}
+WARNS?= 3
+
DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
diff --git a/usr.sbin/named-checkzone/Makefile b/usr.sbin/named-checkzone/Makefile
index 169c00a..05cc9f2 100644
--- a/usr.sbin/named-checkzone/Makefile
+++ b/usr.sbin/named-checkzone/Makefile
@@ -14,6 +14,8 @@ SRCS+= named-checkzone.c check-tool.c
CFLAGS+= -I${LIB_BIND_DIR}
+WARNS?= 3
+
DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
diff --git a/usr.sbin/named/Makefile b/usr.sbin/named/Makefile
index 608866a..296afe9 100644
--- a/usr.sbin/named/Makefile
+++ b/usr.sbin/named/Makefile
@@ -51,6 +51,8 @@ CFLAGS+= -I${BIND_DIR}/lib/isc/${ISC_ATOMIC_ARCH}/include
# Remove the date stamp to make it more obvious when real changes happen
CFLAGS+= -U__DATE__
+WARNS?= 0
+
DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
diff --git a/usr.sbin/ndiscvt/ndiscvt.c b/usr.sbin/ndiscvt/ndiscvt.c
index 34d3120..5de7519 100644
--- a/usr.sbin/ndiscvt/ndiscvt.c
+++ b/usr.sbin/ndiscvt/ndiscvt.c
@@ -91,10 +91,8 @@ extern const char *__progname;
nt_hdr = (image_nt_header *)(x + dos_hdr->idh_lfanew); \
sect_hdr = IMAGE_FIRST_SECTION(nt_hdr);
-static
-int insert_padding(imgbase, imglen)
- void **imgbase;
- int *imglen;
+static int
+insert_padding(void **imgbase, int *imglen)
{
image_section_header *sect_hdr;
image_dos_header *dos_hdr;
diff --git a/usr.sbin/ndp/Makefile b/usr.sbin/ndp/Makefile
index f156691..552ac53 100644
--- a/usr.sbin/ndp/Makefile
+++ b/usr.sbin/ndp/Makefile
@@ -22,4 +22,6 @@ SRCS= ndp.c gmt2local.c
CFLAGS+= -I. -I${.CURDIR} -I${.CURDIR}/../../contrib/tcpdump
CFLAGS+= -D_U_=""
+WARNS?= 1
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/ndp/gnuc.h b/usr.sbin/ndp/gnuc.h
deleted file mode 100644
index c641296..0000000
--- a/usr.sbin/ndp/gnuc.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* $FreeBSD$ */
-/* this is dummy to pacify gmt2local.c. */
diff --git a/usr.sbin/newsyslog/Makefile b/usr.sbin/newsyslog/Makefile
index 9c301a1..ebc297b 100644
--- a/usr.sbin/newsyslog/Makefile
+++ b/usr.sbin/newsyslog/Makefile
@@ -4,6 +4,4 @@ PROG= newsyslog
MAN= newsyslog.8 newsyslog.conf.5
SRCS= newsyslog.c ptimes.c
-WARNS?= 2
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/newsyslog/newsyslog.8 b/usr.sbin/newsyslog/newsyslog.8
index 3db563f..06714aa 100644
--- a/usr.sbin/newsyslog/newsyslog.8
+++ b/usr.sbin/newsyslog/newsyslog.8
@@ -17,7 +17,7 @@
.\" the suitability of this software for any purpose. It is
.\" provided "as is" without express or implied warranty.
.\"
-.Dd February 24, 2005
+.Dd January 19, 2010
.Dt NEWSYSLOG 8
.Os
.Sh NAME
@@ -25,7 +25,7 @@
.Nd maintain system log files to manageable sizes
.Sh SYNOPSIS
.Nm
-.Op Fl CFNnrsv
+.Op Fl CFNPnrsv
.Op Fl R Ar tagname
.Op Fl a Ar directory
.Op Fl d Ar directory
@@ -169,6 +169,10 @@ This option is intended to be used with the
or
.Fl CC
options when creating log files is the only objective.
+.It Fl P
+Prevent further action if we should send signal but the
+.Dq pidfile
+is empty or does not exist.
.It Fl R Ar tagname
Specify that
.Nm
diff --git a/usr.sbin/newsyslog/newsyslog.c b/usr.sbin/newsyslog/newsyslog.c
index ef74f23..4cadda4 100644
--- a/usr.sbin/newsyslog/newsyslog.c
+++ b/usr.sbin/newsyslog/newsyslog.c
@@ -167,6 +167,7 @@ int needroot = 1; /* Root privs are necessary */
int noaction = 0; /* Don't do anything, just show it */
int norotate = 0; /* Don't rotate */
int nosignal; /* Do not send any signals */
+int enforcepid = 0; /* If PID file does not exist or empty, do nothing */
int force = 0; /* Force the trim no matter what */
int rotatereq = 0; /* -R = Always rotate the file(s) as given */
/* on the command (this also requires */
@@ -580,7 +581,7 @@ parse_args(int argc, char **argv)
*p = '\0';
/* Parse command line options. */
- while ((ch = getopt(argc, argv, "a:d:f:nrsvCD:FNR:")) != -1)
+ while ((ch = getopt(argc, argv, "a:d:f:nrsvCD:FNPR:")) != -1)
switch (ch) {
case 'a':
archtodir++;
@@ -624,6 +625,9 @@ parse_args(int argc, char **argv)
case 'N':
norotate++;
break;
+ case 'P':
+ enforcepid++;
+ break;
case 'R':
rotatereq++;
requestor = strdup(optarg);
@@ -1779,7 +1783,18 @@ set_swpid(struct sigwork_entry *swork, const struct conf_entry *ent)
f = fopen(ent->pid_file, "r");
if (f == NULL) {
- warn("can't open pid file: %s", ent->pid_file);
+ if (errno == ENOENT && enforcepid == 0) {
+ /*
+ * Warn if the PID file doesn't exist, but do
+ * not consider it an error. Most likely it
+ * means the process has been terminated,
+ * so it should be safe to rotate any log
+ * files that the process would have been using.
+ */
+ swork->sw_pidok = 1;
+ warnx("pid file doesn't exist: %s", ent->pid_file);
+ } else
+ warn("can't open pid file: %s", ent->pid_file);
return;
}
@@ -1790,7 +1805,7 @@ set_swpid(struct sigwork_entry *swork, const struct conf_entry *ent)
* has terminated, so it should be safe to rotate any
* log files that the process would have been using.
*/
- if (feof(f)) {
+ if (feof(f) && enforcepid == 0) {
swork->sw_pidok = 1;
warnx("pid file is empty: %s", ent->pid_file);
} else
diff --git a/usr.sbin/nfsd/Makefile b/usr.sbin/nfsd/Makefile
index 3237ce3..2905067 100644
--- a/usr.sbin/nfsd/Makefile
+++ b/usr.sbin/nfsd/Makefile
@@ -4,6 +4,4 @@
PROG= nfsd
MAN= nfsd.8 nfsv4.4 stablerestart.5
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c
index a822eb3..d86309f 100644
--- a/usr.sbin/nfsd/nfsd.c
+++ b/usr.sbin/nfsd/nfsd.c
@@ -842,7 +842,7 @@ setbindhost(struct addrinfo **ai, const char *bindhost, struct addrinfo hints)
}
void
-usage()
+usage(void)
{
(void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
exit(1);
@@ -868,7 +868,7 @@ reapchild(__unused int signo)
}
void
-unregistration()
+unregistration(void)
{
if ((!rpcb_unset(NFS_PROGRAM, 2, NULL)) ||
(!rpcb_unset(NFS_PROGRAM, 3, NULL)))
@@ -876,7 +876,7 @@ unregistration()
}
void
-killchildren()
+killchildren(void)
{
int i;
diff --git a/usr.sbin/nfsd/nfsv4.4 b/usr.sbin/nfsd/nfsv4.4
index 70b145b..29e1609 100644
--- a/usr.sbin/nfsd/nfsv4.4
+++ b/usr.sbin/nfsd/nfsv4.4
@@ -24,22 +24,20 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 30, 2009
+.Dd December 3, 2009
.Dt NFSV4 4
.Os
.Sh NAME
-.Nm nfsv4
+.Nm NFSv4
.Nd NFS Version 4 Protocol
-.Sh SYNOPSIS
-experimental client and server with NFSv4 support
.Sh DESCRIPTION
-The experimental nfs client and server provides support for the
+The experimental NFS client and server provides support for the
.Tn NFSv4
specification; see
.%T "Network File System (NFS) Version 4 Protocol \\*(tNRFC\\*(sP 3530" .
The protocol is somewhat similar to NFS Version 3, but differs in significant
ways.
-It uses a single Compound RPC that concatenates operations to-gether.
+It uses a single compound RPC that concatenates operations to-gether.
Each of these operations are similar to the RPCs of NFS Version 3.
The operations in the compound are performed in order, until one of
them fails (returns an error) and then the RPC terminates at that point.
@@ -48,10 +46,10 @@ It has
integrated locking support, which implies that the server is no longer
stateless.
As such, the
-.Tn NFSv4
-server remains in recovery mode for a Grace period (always greater than the
+.Nm
+server remains in recovery mode for a grace period (always greater than the
lease duration the server uses) after a reboot.
-During this Grace period, clients may recover state but not perform other
+During this grace period, clients may recover state but not perform other
open/lock state changing operations.
To provide for correct recovery semantics, a small file described by
.Xr stablerestart 5
@@ -61,14 +59,14 @@ the server will not start.
If this file is lost, it should be recovered from backups, since creating
an empty
.Xr stablerestart 5
-file will result in the server starting without providing a Grace Period
+file will result in the server starting without providing a grace period
for recovery.
Note that recovery only occurs when the server
machine is rebooted, not when the
.Xr nfsd 8
are just restarted.
.Pp
-It provides several optional features not in NFS Version 3:
+It provides several optional features not present in NFS Version 3:
.sp
.Bd -literal -offset indent -compact
- NFS Version 4 ACLs
@@ -78,7 +76,7 @@ It provides several optional features not in NFS Version 3:
.Ed
.Pp
The
-.Tn NFSv4
+.Nm
protocol does not use a separate mount protocol and assumes that the
server provides a single file system tree structure, rooted at the point
in the local file system tree specified by one or more
@@ -131,7 +129,7 @@ by default.
However, this can normally be overridden by a command line
option or configuration file for the daemon used to do the name<->number
mapping.
-On FreeBSD, the mapping daemon is called
+Under FreeBSD, the mapping daemon is called
.Xr nfsuserd 8
and has a command line option that overrides the domain component of the
machine's hostname.
@@ -143,7 +141,7 @@ report a lot of ``nobody'' and ``nogroup'' ownerships.
.Pp
Although uid/gid numbers are no longer used in the
.Nm
-protocol, they will still be in the RPC authentication fields when running
+protocol, they will still be in the RPC authentication fields when
using AUTH_SYS (sec=sys), which is the default.
As such, in this case both the user/group name and number spaces must
be consistent between the client and server.
@@ -154,8 +152,8 @@ with RPCSEC_GSS (sec=krb5, krb5i, krb5p), only names and KerberosV tickets
will go on the wire.
.Sh SERVER SETUP
.Pp
-To set up the experimental nfs server that supports
-.Nm
+To set up the experimental NFS server that supports
+.Nm ,
you will need to either build a kernel with:
.sp
.Bd -literal -offset indent -compact
@@ -318,13 +316,13 @@ variables.
NFS V4 stable restart file
.El
.Sh SEE ALSO
-.Xr stablerestart 5
-.Xr mountd 8
-.Xr nfscbd 8
-.Xr nfsd 8
-.Xr nfsdumpstate 8
-.Xr nfsrevoke 8
-.Xr nfsuserd 8
+.Xr stablerestart 5 ,
+.Xr mountd 8 ,
+.Xr nfscbd 8 ,
+.Xr nfsd 8 ,
+.Xr nfsdumpstate 8 ,
+.Xr nfsrevoke 8 ,
+.Xr nfsuserd 8 ,
.Sh BUGS
At this time, there is no recall of delegations for local file system
operations.
diff --git a/usr.sbin/nfsd/stablerestart.5 b/usr.sbin/nfsd/stablerestart.5
index c469835..172dd4b 100644
--- a/usr.sbin/nfsd/stablerestart.5
+++ b/usr.sbin/nfsd/stablerestart.5
@@ -24,23 +24,23 @@
.\"
.\" $FreeBSD$
.\"
-.Dd Sept 7, 2007
+.Dd December 3, 2009
.Dt STABLERESTART 5
.Os
.Sh NAME
.Nm nfs-stablerestart
-.Nd handles restart edge conditions for the
-.Tn NFS
-V4 server
+.Nd restart information for the
+.Tn NFSv4
+server
.Sh SYNOPSIS
.Nm nfs-stablerestart
.Sh DESCRIPTION
The
.Nm
file holds information that allows the
-.Tn NFS
-V4 server to restart without always returning the NFSERR_NOGRACE error, as described in the
-.Tn NFS V4
+.Tn NFSv4
+server to restart without always returning the NFSERR_NOGRACE error, as described in the
+.Tn NFSv4
server specification; see
.%T "Network File System (NFS) Version 4 Protocol \\*(tNRFC\\*(sP 3530, Section 8.6.3" .
.Pp
@@ -49,11 +49,11 @@ The first record in the file, as defined by struct nfsf_rec in
last incarnation of the server and the number of boot times that follows.
Following this are the number of previous boot times listed in the
first record.
-The lease duration is used to set the Grace Period.
+The lease duration is used to set the grace period.
The boot times
are used to avoid the unlikely occurrence of a boot time being reused,
due to a TOD clock going backwards. This record and the previous boot times with this boot time added is re-written at the
-end of the Grace Period.
+end of the grace period.
.Pp
The rest of the file are appended records, as defined by
struct nfst_rec in /usr/include/fs/nfs/nfsrvstate.h and are used
@@ -77,14 +77,14 @@ a local disk drive that holds the file, or similar.
.Sh FILES
.Bl -tag -width /var/db/nfs-stablerestart -compact
.It Pa /var/db/nfs-stablerestart
-NFS V4 stable restart file
+NFSv4 stable restart file
.El
.Sh SEE ALSO
-.Xr nfsv4 4
+.Xr nfsv4 4 ,
.Xr nfsd 8
.Sh BUGS
-If the file is empty, the NFS V4 server has no choice but to return
-NFSERR_NOGRACE for all Reclaim requests. Although correct, this is
+If the file is empty, the NFSv4 server has no choice but to return
+NFSERR_NOGRACE for all reclaim requests. Although correct, this is
a highly undesirable occurrence, so the file should not be lost if
at all possible. Nfsd will not create the file if it does not
exist and will simply log a failure to start, in the hopes that the
diff --git a/usr.sbin/nghook/Makefile b/usr.sbin/nghook/Makefile
index 73f2df3..e427f26 100644
--- a/usr.sbin/nghook/Makefile
+++ b/usr.sbin/nghook/Makefile
@@ -4,7 +4,6 @@
PROG= nghook
MAN= nghook.8
SRCS= main.c
-WARNS?= 6
DPADD= ${LIBNETGRAPH}
LDADD= -lnetgraph
diff --git a/usr.sbin/nscd/nscd.conf.5 b/usr.sbin/nscd/nscd.conf.5
index f64ce27..727e3e6 100644
--- a/usr.sbin/nscd/nscd.conf.5
+++ b/usr.sbin/nscd/nscd.conf.5
@@ -106,7 +106,7 @@ The default policy is fifo.
This is the internal hash table size.
The value should be a prime number for optimum performance.
You should only change this value when the number of cached elements is
-significantly (in 5-10 times) greater then the default hash table size (255).
+significantly (5-10 times) greater than the default hash table size (257).
.It Va keep-hot-count Oo Ar cachename Oc Op Ar value
The size limit of the cache with the given
.Ar cachename .
diff --git a/usr.sbin/ntp/Makefile b/usr.sbin/ntp/Makefile
index 86e447d..31ee564 100644
--- a/usr.sbin/ntp/Makefile
+++ b/usr.sbin/ntp/Makefile
@@ -1,7 +1,7 @@
# Makefile for ntpd.
# $FreeBSD$
-SUBDIR= libopts libntp libparse ntpd ntpdc ntpq ntpdate ntptrace \
+SUBDIR= libopts libntp libparse ntpd ntpdc ntpq ntpdate \
ntptime ntp-keygen sntp
SUBDIR+= doc
diff --git a/usr.sbin/ntp/Makefile.inc b/usr.sbin/ntp/Makefile.inc
index f81905a..5095e89 100644
--- a/usr.sbin/ntp/Makefile.inc
+++ b/usr.sbin/ntp/Makefile.inc
@@ -18,4 +18,6 @@ LIBOPTS= ${.OBJDIR}/../libopts/libopts.a
LIBPARSE= ${.OBJDIR}/../libparse/libparse.a
LIBNTP= ${.OBJDIR}/../libntp/libntp.a
+WARNS?= 0
+
.include "../Makefile.inc"
diff --git a/usr.sbin/ntp/config.h b/usr.sbin/ntp/config.h
index 518cd8c..8359b30 100644
--- a/usr.sbin/ntp/config.h
+++ b/usr.sbin/ntp/config.h
@@ -947,7 +947,7 @@
/* #undef HAVE_UTMPX_H */
/* Define to 1 if you have the <utmp.h> header file. */
-#define HAVE_UTMP_H 1
+/* #undef HAVE_UTMP_H */
/* Define to 1 if you have the <values.h> header file. */
/* #undef HAVE_VALUES_H */
diff --git a/usr.sbin/ntp/doc/Makefile b/usr.sbin/ntp/doc/Makefile
index f1326fc..64e3571 100644
--- a/usr.sbin/ntp/doc/Makefile
+++ b/usr.sbin/ntp/doc/Makefile
@@ -24,7 +24,7 @@ FILES= accopt.html assoc.html audio.html authopt.html build.html \
.endif
MAN= ntp.conf.5 ntp.keys.5
-MAN+= ntp-keygen.8 ntpd.8 ntpdate.8 ntpdc.8 ntpq.8 ntptime.8 ntptrace.8
+MAN+= ntp-keygen.8 ntpd.8 ntpdate.8 ntpdc.8 ntpq.8 ntptime.8
.PATH: ${.CURDIR}/../../../contrib/ntp/html \
${.CURDIR}/../../../contrib/ntp/html/build \
diff --git a/usr.sbin/ntp/doc/ntpd.8 b/usr.sbin/ntp/doc/ntpd.8
index 5194b75..a55fe43 100644
--- a/usr.sbin/ntp/doc/ntpd.8
+++ b/usr.sbin/ntp/doc/ntpd.8
@@ -121,7 +121,7 @@ Normally,
.Nm
exits with a message to the system log if the offset exceeds
the panic threshold, which is 1000 s by default.
-This option allows thetime to be set to any value without restriction;
+This option allows the time to be set to any value without restriction;
however, this can happen only once.
If the threshold is exceeded after that,
.Nm
diff --git a/usr.sbin/ntp/ntptrace/Makefile b/usr.sbin/ntp/ntptrace/Makefile
deleted file mode 100644
index 8d7547c..0000000
--- a/usr.sbin/ntp/ntptrace/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../scripts
-
-SCRIPTS= ntptrace
-NO_MAN=
-NO_OBJ=
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/nvram/Makefile b/usr.sbin/nvram/Makefile
index 3cca037..2c6e43c 100644
--- a/usr.sbin/nvram/Makefile
+++ b/usr.sbin/nvram/Makefile
@@ -4,6 +4,4 @@ PROG= nvram
MAN= nvram.8
MANSUBDIR= /powerpc
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/ofwdump/Makefile b/usr.sbin/ofwdump/Makefile
index a20e94f..ca4f486 100644
--- a/usr.sbin/ofwdump/Makefile
+++ b/usr.sbin/ofwdump/Makefile
@@ -4,6 +4,4 @@ PROG= ofwdump
MAN= ofwdump.8
SRCS= ofwdump.c ofw_util.c
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/pciconf/Makefile b/usr.sbin/pciconf/Makefile
index e57e736..9fbec00 100644
--- a/usr.sbin/pciconf/Makefile
+++ b/usr.sbin/pciconf/Makefile
@@ -7,4 +7,6 @@ MAN= pciconf.8
CFLAGS+= -I${.CURDIR}/../../sys
+WARNS?= 3
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/pkg_install/add/main.c b/usr.sbin/pkg_install/add/main.c
index eaed0c0..d9b381b 100644
--- a/usr.sbin/pkg_install/add/main.c
+++ b/usr.sbin/pkg_install/add/main.c
@@ -344,7 +344,7 @@ getpackagesite(void)
}
static void
-usage()
+usage(void)
{
fprintf(stderr, "%s\n%s\n",
"usage: pkg_add [-viInfFrRMSK] [-t template] [-p prefix] [-P prefix] [-C chrootdir]",
diff --git a/usr.sbin/pkg_install/create/main.c b/usr.sbin/pkg_install/create/main.c
index b98b21e..d85392d 100644
--- a/usr.sbin/pkg_install/create/main.c
+++ b/usr.sbin/pkg_install/create/main.c
@@ -249,7 +249,7 @@ main(int argc, char **argv)
}
static void
-usage()
+usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
"usage: pkg_create [-YNOhjnvyz] [-C conflicts] [-P pkgs] [-p prefix]",
diff --git a/usr.sbin/pkg_install/delete/Makefile b/usr.sbin/pkg_install/delete/Makefile
index c346ea7..c9a0fde 100644
--- a/usr.sbin/pkg_install/delete/Makefile
+++ b/usr.sbin/pkg_install/delete/Makefile
@@ -5,7 +5,6 @@ SRCS= main.c perform.c
CFLAGS+= -I${.CURDIR}/../lib
-WARNS?= 6
WFORMAT?= 1
DPADD= ${LIBINSTALL} ${LIBMD}
diff --git a/usr.sbin/pkg_install/delete/main.c b/usr.sbin/pkg_install/delete/main.c
index 6075f72..f09a432 100644
--- a/usr.sbin/pkg_install/delete/main.c
+++ b/usr.sbin/pkg_install/delete/main.c
@@ -170,7 +170,7 @@ main(int argc, char **argv)
}
static void
-usage()
+usage(void)
{
fprintf(stderr, "%s\n%s\n",
"usage: pkg_delete [-dDfGinrvxX] [-p prefix] pkg-name ...",
diff --git a/usr.sbin/pkg_install/info/Makefile b/usr.sbin/pkg_install/info/Makefile
index 675f7ca..485cb22 100644
--- a/usr.sbin/pkg_install/info/Makefile
+++ b/usr.sbin/pkg_install/info/Makefile
@@ -5,7 +5,6 @@ SRCS= main.c perform.c show.c
CFLAGS+= -I${.CURDIR}/../lib
-WARNS?= 6
WFORMAT?= 1
DPADD= ${LIBINSTALL} ${LIBFETCH} ${LIBMD}
diff --git a/usr.sbin/pkg_install/info/main.c b/usr.sbin/pkg_install/info/main.c
index 08ab23b..2de638e 100644
--- a/usr.sbin/pkg_install/info/main.c
+++ b/usr.sbin/pkg_install/info/main.c
@@ -282,7 +282,7 @@ main(int argc, char **argv)
}
static void
-usage()
+usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
"usage: pkg_info [-bcdDEfgGiIjkKLmopPqQrRsvVxX] [-e package] [-l prefix]",
diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h
index a3d0413..4a6c625 100644
--- a/usr.sbin/pkg_install/lib/lib.h
+++ b/usr.sbin/pkg_install/lib/lib.h
@@ -105,7 +105,7 @@
* Version of the package tools - increase whenever you make a change
* in the code that is not cosmetic only.
*/
-#define PKG_INSTALL_VERSION 20090902
+#define PKG_INSTALL_VERSION 20100122
#define PKG_WRAPCONF_FNAME "/var/db/pkg_install.conf"
#define main(argc, argv) real_main(argc, argv)
diff --git a/usr.sbin/pkg_install/updating/Makefile b/usr.sbin/pkg_install/updating/Makefile
index cf8bfc8..b0d3689 100644
--- a/usr.sbin/pkg_install/updating/Makefile
+++ b/usr.sbin/pkg_install/updating/Makefile
@@ -5,7 +5,6 @@ SRCS= main.c
CFLAGS+= -I${.CURDIR}/../lib
-WARNS?= 6
WFORMAT?= 1
DPADD= ${LIBINSTALL} ${LIBFETCH} ${LIBMD}
diff --git a/usr.sbin/pkg_install/updating/main.c b/usr.sbin/pkg_install/updating/main.c
index e189c01..0ab2ec0 100644
--- a/usr.sbin/pkg_install/updating/main.c
+++ b/usr.sbin/pkg_install/updating/main.c
@@ -10,7 +10,11 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <stdio.h>
#include <errno.h>
+#include <fetch.h>
#include <limits.h>
#include <sysexits.h>
#include <getopt.h>
@@ -115,10 +119,10 @@ main(int argc, char *argv[])
if (argc != 0) {
pflag = 1;
while (*argv) {
- if((curr = (INSTALLEDPORT *)
+ if ((curr = (INSTALLEDPORT *)
malloc(sizeof(INSTALLEDPORT))) == NULL)
(void)exit(EXIT_FAILURE);
- strlcpy (curr->name, *argv, strlen(*argv) + 1);
+ strlcpy(curr->name, *argv, strlen(*argv) + 1);
curr->next = head;
head = curr;
(void)*argv++;
@@ -131,22 +135,22 @@ main(int argc, char *argv[])
*/
if (pflag == 0) {
/* Open /var/db/pkg and search for all installed ports. */
- if((dir = opendir(pkgdbpath)) != NULL) {
+ if ((dir = opendir(pkgdbpath)) != NULL) {
while ((pkgdbdir = readdir(dir)) != NULL) {
if (strcmp(pkgdbdir->d_name, ".") != 0 &&
- strcmp(pkgdbdir->d_name, "..") !=0) {
+ strcmp(pkgdbdir->d_name, "..") != 0) {
/* Create path to +CONTENTS file for each installed port */
n = strlcpy(tmp_file, pkgdbpath, strlen(pkgdbpath)+1);
n = strlcpy(tmp_file + n, "/", sizeof(tmp_file) - n);
n = strlcat(tmp_file + n, pkgdbdir->d_name,
sizeof(tmp_file) - n);
- if(stat(tmp_file, &attribute) == -1) {
+ if (stat(tmp_file, &attribute) == -1) {
fprintf(stderr, "can't open %s: %s\n",
tmp_file, strerror(errno));
return EXIT_FAILURE;
}
- if(attribute.st_mode & S_IFREG)
+ if (attribute.st_mode & S_IFREG)
continue;
(void)strlcat(tmp_file + n, "/",
sizeof(tmp_file) - n);
@@ -155,7 +159,7 @@ main(int argc, char *argv[])
/* Open +CONTENT file */
fd = fopen(tmp_file, "r");
- if(fd == NULL) {
+ if (fd == NULL) {
fprintf(stderr, "warning: can't open %s: %s\n",
tmp_file, strerror(errno));
continue;
@@ -165,14 +169,14 @@ main(int argc, char *argv[])
* Parses +CONTENT for ORIGIN line and
* put element into linked list.
*/
- while(fgets(originline, maxcharperline, fd) != NULL) {
+ while (fgets(originline, maxcharperline, fd) != NULL) {
tmpline1 = strstr(originline, origin);
- if( tmpline1 != NULL ) {
+ if (tmpline1 != NULL) {
/* Tmp variable to store port name. */
char *pname;
pname = strrchr(originline, (int)':');
pname++;
- if((curr = (INSTALLEDPORT *)
+ if ((curr = (INSTALLEDPORT *)
malloc(sizeof(INSTALLEDPORT))) == NULL)
(void)exit(EXIT_FAILURE);
if (pname[strlen(pname) - 1] == '\n')
@@ -183,7 +187,7 @@ main(int argc, char *argv[])
}
}
- if(ferror(fd)) {
+ if (ferror(fd)) {
fprintf(stderr, "error reading input\n");
exit(EX_IOERR);
}
@@ -195,32 +199,41 @@ main(int argc, char *argv[])
}
}
- /* Open UPDATING file */
- fd = fopen(updatingfile, "r");
- if(fd == NULL) {
+ /* Fetch UPDATING file if needed and open file */
+ if (isURL(updatingfile)) {
+ if ((fd = fetchGetURL(updatingfile, "")) == NULL) {
+ fprintf(stderr, "Error: Unable to get %s: %s\n",
+ updatingfile, fetchLastErrString);
+ exit(EX_UNAVAILABLE);
+ }
+ }
+ else {
+ fd = fopen(updatingfile, "r");
+ }
+ if (fd == NULL) {
fprintf(stderr, "can't open %s: %s\n",
- updatingfile, strerror(errno));
+ updatingfile, strerror(errno));
exit(EX_UNAVAILABLE);
}
/* Parse opened UPDATING file. */
- while(fgets(updatingline, maxcharperline, fd) != NULL) {
+ while (fgets(updatingline, maxcharperline, fd) != NULL) {
/* No entry is found so far */
if (found == 0) {
/* Search for AFFECTS line to parse the portname. */
tmpline1 = strstr(updatingline, affects);
- if( tmpline1 != NULL ) {
+ if (tmpline1 != NULL) {
curr = head;
- while(curr != NULL) {
+ while (curr != NULL) {
tmpline2 = strstr(updatingline, curr->name);
- if( tmpline2 != NULL )
+ if (tmpline2 != NULL)
break;
curr = curr->next;
}
- if( tmpline2 != NULL ) {
+ if (tmpline2 != NULL) {
/* If -d is set, check if entry is newer than the date. */
- if ( (dflag == 1) && (strncmp(dateline, date, 8) < 0))
+ if ((dflag == 1) && (strncmp(dateline, date, 8) < 0))
continue;
printf("%s", dateline);
printf("%s", updatingline);
@@ -231,7 +244,7 @@ main(int argc, char *argv[])
/* Search for the end of an entry, if not found print the line. */
else {
tmpline1 = strstr(updatingline, end);
- if( tmpline1 == NULL )
+ if (tmpline1 == NULL)
printf("%s", updatingline);
else {
linelength = strlen(updatingline);
@@ -245,7 +258,7 @@ main(int argc, char *argv[])
dateline = strdup(updatingline);
}
- if(ferror(fd)) {
+ if (ferror(fd)) {
fprintf(stderr, "error reading input\n");
exit(EX_IOERR);
}
diff --git a/usr.sbin/pkg_install/updating/pkg_updating.1 b/usr.sbin/pkg_install/updating/pkg_updating.1
index e3bcb54..0c35f9a 100644
--- a/usr.sbin/pkg_install/updating/pkg_updating.1
+++ b/usr.sbin/pkg_install/updating/pkg_updating.1
@@ -45,26 +45,31 @@ Print help message.
.El
.Sh EXAMPLES
.Bl -tag -width indent
-.Dl pkg_updating
+Shows all entries of all installed ports:
.Pp
-Shows all entries of all installed ports.
+.Dl % pkg_updating
.Pp
-.Dl pkg_updating -d 20070101
+Shows all entries of all installed ports since 2007-01-01:
.Pp
-Shows all entries of all installed ports since 2007-01-01.
+.Dl % pkg_updating -d 20070101
.Pp
-.Dl pkg_updating apache mysql
+Shows all entries for all apache and mysql ports:
.Pp
-Shows all entries for all apache and mysql ports.
+.Dl % pkg_updating apache mysql
.Pp
-.Dl pkg_updating -d 20060101 apache
+Shows all apache entries since 2006-01-01:
.Pp
-Shows all apache entries since 2006-01-01.
-.Pp
-.Dl pkg_updating -f /tmp/UPDATING
+.Dl % pkg_updating -d 20060101 apache
.Pp
Defines that the UPDATING file is in /tmp and shows all entries of all
-installed ports
+installed ports:
+.Pp
+.Dl % pkg_updating -f /tmp/UPDATING
+.Pp
+Fetch UPDATING file from ftp mirror and show all entries of all
+installed ports:
+.Pp
+.Dl % pkg_updating -f ftp://ftp.freebsd.org/pub/FreeBSD/ports/packages/UPDATING
.Pp
.El
.Sh ENVIRONMENT
diff --git a/usr.sbin/pkg_install/version/Makefile b/usr.sbin/pkg_install/version/Makefile
index 71168ee..3e1d7a5 100644
--- a/usr.sbin/pkg_install/version/Makefile
+++ b/usr.sbin/pkg_install/version/Makefile
@@ -5,7 +5,6 @@ SRCS= main.c perform.c
CFLAGS+= -I${.CURDIR}/../lib
-WARNS?= 6
WFORMAT?= 1
DPADD= ${LIBINSTALL} ${LIBFETCH} ${LIBMD}
diff --git a/usr.sbin/pkg_install/version/main.c b/usr.sbin/pkg_install/version/main.c
index f46d945..cad8583 100644
--- a/usr.sbin/pkg_install/version/main.c
+++ b/usr.sbin/pkg_install/version/main.c
@@ -127,7 +127,7 @@ main(int argc, char **argv)
}
static void
-usage()
+usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n",
"usage: pkg_version [-hIoqv] [-l limchar] [-L limchar] [[-X] -s string] [-O origin] [index]",
diff --git a/usr.sbin/pmcannotate/Makefile b/usr.sbin/pmcannotate/Makefile
index e087bb3..cff1efb 100644
--- a/usr.sbin/pmcannotate/Makefile
+++ b/usr.sbin/pmcannotate/Makefile
@@ -5,8 +5,6 @@
PROG= pmcannotate
MAN= pmcannotate.8
-WARNS?= 6
-
SRCS= pmcannotate.c
.include <bsd.prog.mk>
diff --git a/usr.sbin/pmcannotate/pmcannotate.c b/usr.sbin/pmcannotate/pmcannotate.c
index 1a5dec2..1f39f25 100644
--- a/usr.sbin/pmcannotate/pmcannotate.c
+++ b/usr.sbin/pmcannotate/pmcannotate.c
@@ -325,7 +325,7 @@ fqueue_compact(float th)
* Flush the first-level aggregates queue.
*/
static void
-fqueue_deleteall()
+fqueue_deleteall(void)
{
struct aggent *agg;
@@ -472,7 +472,7 @@ fqueue_insertgen(void)
* Flush the raw entries general queue.
*/
static void
-general_deleteall()
+general_deleteall(void)
{
struct entry *obj;
diff --git a/usr.sbin/pmccontrol/Makefile b/usr.sbin/pmccontrol/Makefile
index 9dafe1c..0f6dc76 100644
--- a/usr.sbin/pmccontrol/Makefile
+++ b/usr.sbin/pmccontrol/Makefile
@@ -8,8 +8,6 @@ MAN= pmccontrol.8
DPADD= ${LIBPMC}
LDADD= -lpmc
-WARNS?= 6
-
SRCS= pmccontrol.c
.include <bsd.prog.mk>
diff --git a/usr.sbin/pmcstat/Makefile b/usr.sbin/pmcstat/Makefile
index 6b11d8d..c27e56d 100644
--- a/usr.sbin/pmcstat/Makefile
+++ b/usr.sbin/pmcstat/Makefile
@@ -5,11 +5,10 @@
PROG= pmcstat
MAN= pmcstat.8
-DPADD= ${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM}
-LDADD= -lelf -lkvm -lpmc -lm
+DPADD= ${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM} ${LIBNCURSES}
+LDADD= -lelf -lkvm -lpmc -lm -lncurses
-WARNS?= 6
-
-SRCS= pmcstat.c pmcstat.h pmcstat_log.c
+SRCS= pmcstat.c pmcstat.h pmcstat_log.c \
+pmcpl_callgraph.c pmcpl_gprof.c pmcpl_annotate.c pmcpl_calltree.c
.include <bsd.prog.mk>
diff --git a/usr.sbin/pmcstat/pmcpl_annotate.c b/usr.sbin/pmcstat/pmcpl_annotate.c
new file mode 100644
index 0000000..802983c
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_annotate.c
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 2005-2007, Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE 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.
+ */
+
+/*
+ * Transform a hwpmc(4) log into human readable form, and into
+ * gprof(1) compatible profiles.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/gmon.h>
+#include <sys/imgact_aout.h>
+#include <sys/imgact_elf.h>
+#include <sys/mman.h>
+#include <sys/pmc.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libgen.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pmc.h>
+#include <pmclog.h>
+#include <sysexits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pmcstat.h"
+#include "pmcstat_log.h"
+#include "pmcpl_annotate.h"
+
+/*
+ * Record a callchain.
+ */
+
+void
+pmcpl_annotate_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
+{
+ struct pmcstat_pcmap *map;
+ struct pmcstat_symbol *sym;
+ uintfptr_t newpc;
+ struct pmcstat_image *image;
+
+ (void) pmcr; (void) nsamples; (void) usermode; (void) cpu;
+
+ map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[0]);
+ if (map == NULL) {
+ /* Unknown offset. */
+ pmcstat_stats.ps_samples_unknown_offset++;
+ return;
+ }
+
+ assert(cc[0] >= map->ppm_lowpc && cc[0] < map->ppm_highpc);
+
+ image = map->ppm_image;
+ newpc = cc[0] - (map->ppm_lowpc +
+ (image->pi_vaddr - image->pi_start));
+ sym = pmcstat_symbol_search(image, newpc);
+ if (sym == NULL)
+ return;
+
+ fprintf(args.pa_graphfile, "%p %s 0x%jx 0x%jx\n",
+ (void *)cc[0],
+ pmcstat_string_unintern(sym->ps_name),
+ (uintmax_t)(sym->ps_start +
+ image->pi_vaddr), (uintmax_t)(sym->ps_end +
+ image->pi_vaddr));
+}
diff --git a/usr.sbin/pmcstat/pmcpl_annotate.h b/usr.sbin/pmcstat/pmcpl_annotate.h
new file mode 100644
index 0000000..482bcd4
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_annotate.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2005-2007, Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PMCSTAT_PL_ANNOTATE_H_
+#define _PMCSTAT_PL_ANNOTATE_H_
+
+/* Function prototypes */
+void pmcpl_annotate_process(
+ struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
+
+#endif /* _PMCSTAT_PL_ANNOTATE_H_ */
diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.c b/usr.sbin/pmcstat/pmcpl_callgraph.c
new file mode 100644
index 0000000..d6f1a9d
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_callgraph.c
@@ -0,0 +1,682 @@
+/*-
+ * Copyright (c) 2005-2007, Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE 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.
+ */
+
+/*
+ * Transform a hwpmc(4) log into human readable form, and into
+ * gprof(1) compatible profiles.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/gmon.h>
+#include <sys/imgact_aout.h>
+#include <sys/imgact_elf.h>
+#include <sys/mman.h>
+#include <sys/pmc.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+
+#include <assert.h>
+#include <curses.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libgen.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pmc.h>
+#include <pmclog.h>
+#include <sysexits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pmcstat.h"
+#include "pmcstat_log.h"
+#include "pmcstat_top.h"
+#include "pmcpl_callgraph.h"
+
+/* Get the sample value in percent related to nsamples. */
+#define PMCPL_CG_COUNTP(a) \
+ ((a)->pcg_count * 100.0 / nsamples)
+
+/*
+ * The toplevel CG nodes (i.e., with rank == 0) are placed in a hash table.
+ */
+
+struct pmcstat_cgnode_hash_list pmcstat_cgnode_hash[PMCSTAT_NHASH];
+int pmcstat_cgnode_hash_count;
+
+static pmcstat_interned_string pmcstat_previous_filename_printed;
+
+static struct pmcstat_cgnode *
+pmcstat_cgnode_allocate(struct pmcstat_image *image, uintfptr_t pc)
+{
+ struct pmcstat_cgnode *cg;
+
+ if ((cg = malloc(sizeof(*cg))) == NULL)
+ err(EX_OSERR, "ERROR: Cannot allocate callgraph node");
+
+ cg->pcg_image = image;
+ cg->pcg_func = pc;
+
+ cg->pcg_count = 0;
+ cg->pcg_nchildren = 0;
+ LIST_INIT(&cg->pcg_children);
+
+ return (cg);
+}
+
+/*
+ * Free a node and its children.
+ */
+static void
+pmcstat_cgnode_free(struct pmcstat_cgnode *cg)
+{
+ struct pmcstat_cgnode *cgc, *cgtmp;
+
+ LIST_FOREACH_SAFE(cgc, &cg->pcg_children, pcg_sibling, cgtmp)
+ pmcstat_cgnode_free(cgc);
+ free(cg);
+}
+
+/*
+ * Look for a callgraph node associated with pmc `pmcid' in the global
+ * hash table that corresponds to the given `pc' value in the process
+ * `pp'.
+ */
+static struct pmcstat_cgnode *
+pmcstat_cgnode_hash_lookup_pc(struct pmcstat_process *pp, pmc_id_t pmcid,
+ uintfptr_t pc, int usermode)
+{
+ struct pmcstat_pcmap *ppm;
+ struct pmcstat_symbol *sym;
+ struct pmcstat_image *image;
+ struct pmcstat_cgnode *cg;
+ struct pmcstat_cgnode_hash *h;
+ uintfptr_t loadaddress;
+ unsigned int i, hash;
+
+ ppm = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, pc);
+ if (ppm == NULL)
+ return (NULL);
+
+ image = ppm->ppm_image;
+
+ loadaddress = ppm->ppm_lowpc + image->pi_vaddr - image->pi_start;
+ pc -= loadaddress; /* Convert to an offset in the image. */
+
+ /*
+ * Try determine the function at this offset. If we can't
+ * find a function round leave the `pc' value alone.
+ */
+ if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
+ pc = sym->ps_start;
+
+ for (hash = i = 0; i < sizeof(uintfptr_t); i++)
+ hash += (pc >> i) & 0xFF;
+
+ hash &= PMCSTAT_HASH_MASK;
+
+ cg = NULL;
+ LIST_FOREACH(h, &pmcstat_cgnode_hash[hash], pch_next)
+ {
+ if (h->pch_pmcid != pmcid)
+ continue;
+
+ cg = h->pch_cgnode;
+
+ assert(cg != NULL);
+
+ if (cg->pcg_image == image && cg->pcg_func == pc)
+ return (cg);
+ }
+
+ /*
+ * We haven't seen this (pmcid, pc) tuple yet, so allocate a
+ * new callgraph node and a new hash table entry for it.
+ */
+ cg = pmcstat_cgnode_allocate(image, pc);
+ if ((h = malloc(sizeof(*h))) == NULL)
+ err(EX_OSERR, "ERROR: Could not allocate callgraph node");
+
+ h->pch_pmcid = pmcid;
+ h->pch_cgnode = cg;
+ LIST_INSERT_HEAD(&pmcstat_cgnode_hash[hash], h, pch_next);
+
+ pmcstat_cgnode_hash_count++;
+
+ return (cg);
+}
+
+/*
+ * Compare two callgraph nodes for sorting.
+ */
+static int
+pmcstat_cgnode_compare(const void *a, const void *b)
+{
+ const struct pmcstat_cgnode *const *pcg1, *const *pcg2, *cg1, *cg2;
+
+ pcg1 = (const struct pmcstat_cgnode *const *) a;
+ cg1 = *pcg1;
+ pcg2 = (const struct pmcstat_cgnode *const *) b;
+ cg2 = *pcg2;
+
+ /* Sort in reverse order */
+ if (cg1->pcg_count < cg2->pcg_count)
+ return (1);
+ if (cg1->pcg_count > cg2->pcg_count)
+ return (-1);
+ return (0);
+}
+
+/*
+ * Find (allocating if a needed) a callgraph node in the given
+ * parent with the same (image, pcoffset) pair.
+ */
+
+static struct pmcstat_cgnode *
+pmcstat_cgnode_find(struct pmcstat_cgnode *parent, struct pmcstat_image *image,
+ uintfptr_t pcoffset)
+{
+ struct pmcstat_cgnode *child;
+
+ LIST_FOREACH(child, &parent->pcg_children, pcg_sibling) {
+ if (child->pcg_image == image &&
+ child->pcg_func == pcoffset)
+ return (child);
+ }
+
+ /*
+ * Allocate a new structure.
+ */
+
+ child = pmcstat_cgnode_allocate(image, pcoffset);
+
+ /*
+ * Link it into the parent.
+ */
+ LIST_INSERT_HEAD(&parent->pcg_children, child, pcg_sibling);
+ parent->pcg_nchildren++;
+
+ return (child);
+}
+
+/*
+ * Print one callgraph node. The output format is:
+ *
+ * indentation %(parent's samples) #nsamples function@object
+ */
+static void
+pmcstat_cgnode_print(struct pmcstat_cgnode *cg, int depth, uint32_t total)
+{
+ uint32_t n;
+ const char *space;
+ struct pmcstat_symbol *sym;
+ struct pmcstat_cgnode **sortbuffer, **cgn, *pcg;
+
+ space = " ";
+
+ if (depth > 0)
+ (void) fprintf(args.pa_graphfile, "%*s", depth, space);
+
+ if (cg->pcg_count == total)
+ (void) fprintf(args.pa_graphfile, "100.0%% ");
+ else
+ (void) fprintf(args.pa_graphfile, "%05.2f%% ",
+ 100.0 * cg->pcg_count / total);
+
+ n = fprintf(args.pa_graphfile, " [%u] ", cg->pcg_count);
+
+ /* #samples is a 12 character wide field. */
+ if (n < 12)
+ (void) fprintf(args.pa_graphfile, "%*s", 12 - n, space);
+
+ if (depth > 0)
+ (void) fprintf(args.pa_graphfile, "%*s", depth, space);
+
+ sym = pmcstat_symbol_search(cg->pcg_image, cg->pcg_func);
+ if (sym)
+ (void) fprintf(args.pa_graphfile, "%s",
+ pmcstat_string_unintern(sym->ps_name));
+ else
+ (void) fprintf(args.pa_graphfile, "%p",
+ (void *) (cg->pcg_image->pi_vaddr + cg->pcg_func));
+
+ if (pmcstat_previous_filename_printed !=
+ cg->pcg_image->pi_fullpath) {
+ pmcstat_previous_filename_printed = cg->pcg_image->pi_fullpath;
+ (void) fprintf(args.pa_graphfile, " @ %s\n",
+ pmcstat_string_unintern(
+ pmcstat_previous_filename_printed));
+ } else
+ (void) fprintf(args.pa_graphfile, "\n");
+
+ if (cg->pcg_nchildren == 0)
+ return;
+
+ if ((sortbuffer = (struct pmcstat_cgnode **)
+ malloc(sizeof(struct pmcstat_cgnode *) *
+ cg->pcg_nchildren)) == NULL)
+ err(EX_OSERR, "ERROR: Cannot print callgraph");
+ cgn = sortbuffer;
+
+ LIST_FOREACH(pcg, &cg->pcg_children, pcg_sibling)
+ *cgn++ = pcg;
+
+ assert(cgn - sortbuffer == (int) cg->pcg_nchildren);
+
+ qsort(sortbuffer, cg->pcg_nchildren, sizeof(struct pmcstat_cgnode *),
+ pmcstat_cgnode_compare);
+
+ for (cgn = sortbuffer, n = 0; n < cg->pcg_nchildren; n++, cgn++)
+ pmcstat_cgnode_print(*cgn, depth+1, cg->pcg_count);
+
+ free(sortbuffer);
+}
+
+/*
+ * Record a callchain.
+ */
+
+void
+pmcpl_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
+{
+ uintfptr_t pc, loadaddress;
+ uint32_t n;
+ struct pmcstat_image *image;
+ struct pmcstat_pcmap *ppm;
+ struct pmcstat_symbol *sym;
+ struct pmcstat_cgnode *parent, *child;
+ struct pmcstat_process *km;
+ pmc_id_t pmcid;
+
+ (void) cpu;
+
+ /*
+ * Find the callgraph node recorded in the global hash table
+ * for this (pmcid, pc).
+ */
+
+ pc = cc[0];
+ pmcid = pmcr->pr_pmcid;
+ parent = pmcstat_cgnode_hash_lookup_pc(pp, pmcid, pc, usermode);
+ if (parent == NULL) {
+ pmcstat_stats.ps_callchain_dubious_frames++;
+ return;
+ }
+
+ parent->pcg_count++;
+
+ /*
+ * For each return address in the call chain record, subject
+ * to the maximum depth desired.
+ * - Find the image associated with the sample. Stop if there
+ * there is no valid image at that address.
+ * - Find the function that overlaps the return address.
+ * - If found: use the start address of the function.
+ * If not found (say an object's symbol table is not present or
+ * is incomplete), round down to th gprof bucket granularity.
+ * - Convert return virtual address to an offset in the image.
+ * - Look for a child with the same {offset,image} tuple,
+ * inserting one if needed.
+ * - Increment the count of occurrences of the child.
+ */
+ km = pmcstat_kernproc;
+
+ for (n = 1; n < (uint32_t) args.pa_graphdepth && n < nsamples; n++,
+ parent = child) {
+ pc = cc[n];
+
+ ppm = pmcstat_process_find_map(usermode ? pp : km, pc);
+ if (ppm == NULL) {
+ /* Detect full frame capture (kernel + user). */
+ if (!usermode) {
+ ppm = pmcstat_process_find_map(pp, pc);
+ if (ppm != NULL)
+ km = pp;
+ }
+ }
+ if (ppm == NULL)
+ return;
+
+ image = ppm->ppm_image;
+ loadaddress = ppm->ppm_lowpc + image->pi_vaddr -
+ image->pi_start;
+ pc -= loadaddress;
+
+ if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
+ pc = sym->ps_start;
+
+ child = pmcstat_cgnode_find(parent, image, pc);
+ child->pcg_count++;
+ }
+}
+
+/*
+ * Printing a callgraph for a PMC.
+ */
+static void
+pmcstat_callgraph_print_for_pmcid(struct pmcstat_pmcrecord *pmcr)
+{
+ int n, nentries;
+ uint32_t nsamples;
+ pmc_id_t pmcid;
+ struct pmcstat_cgnode **sortbuffer, **cgn;
+ struct pmcstat_cgnode_hash *pch;
+
+ /*
+ * We pull out all callgraph nodes in the top-level hash table
+ * with a matching PMC id. We then sort these based on the
+ * frequency of occurrence. Each callgraph node is then
+ * printed.
+ */
+
+ nsamples = 0;
+ pmcid = pmcr->pr_pmcid;
+ if ((sortbuffer = (struct pmcstat_cgnode **)
+ malloc(sizeof(struct pmcstat_cgnode *) *
+ pmcstat_cgnode_hash_count)) == NULL)
+ err(EX_OSERR, "ERROR: Cannot sort callgraph");
+ cgn = sortbuffer;
+
+ for (n = 0; n < PMCSTAT_NHASH; n++)
+ LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
+ if (pch->pch_pmcid == pmcid) {
+ nsamples += pch->pch_cgnode->pcg_count;
+ *cgn++ = pch->pch_cgnode;
+ }
+
+ nentries = cgn - sortbuffer;
+ assert(nentries <= pmcstat_cgnode_hash_count);
+
+ if (nentries == 0) {
+ free(sortbuffer);
+ return;
+ }
+
+ qsort(sortbuffer, nentries, sizeof(struct pmcstat_cgnode *),
+ pmcstat_cgnode_compare);
+
+ (void) fprintf(args.pa_graphfile,
+ "@ %s [%u samples]\n\n",
+ pmcstat_string_unintern(pmcr->pr_pmcname),
+ nsamples);
+
+ for (cgn = sortbuffer, n = 0; n < nentries; n++, cgn++) {
+ pmcstat_previous_filename_printed = NULL;
+ pmcstat_cgnode_print(*cgn, 0, nsamples);
+ (void) fprintf(args.pa_graphfile, "\n");
+ }
+
+ free(sortbuffer);
+}
+
+/*
+ * Print out callgraphs.
+ */
+
+static void
+pmcstat_callgraph_print(void)
+{
+ struct pmcstat_pmcrecord *pmcr;
+
+ LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
+ pmcstat_callgraph_print_for_pmcid(pmcr);
+}
+
+static void
+pmcstat_cgnode_topprint(struct pmcstat_cgnode *cg,
+ int depth, uint32_t nsamples)
+{
+ int v_attrs, vs_len, ns_len, width, len, n, nchildren;
+ float v;
+ char ns[30], vs[10];
+ struct pmcstat_symbol *sym;
+ struct pmcstat_cgnode **sortbuffer, **cgn, *pcg;
+
+ (void) depth;
+
+ /* Format value. */
+ v = PMCPL_CG_COUNTP(cg);
+ snprintf(vs, sizeof(vs), "%.1f", v);
+ v_attrs = PMCSTAT_ATTRPERCENT(v);
+
+ /* Format name. */
+ sym = pmcstat_symbol_search(cg->pcg_image, cg->pcg_func);
+ if (sym != NULL) {
+ snprintf(ns, sizeof(ns), "%s",
+ pmcstat_string_unintern(sym->ps_name));
+ } else
+ snprintf(ns, sizeof(ns), "%p",
+ (void *)cg->pcg_func);
+
+ PMCSTAT_ATTRON(v_attrs);
+ PMCSTAT_PRINTW("%5.5s", vs);
+ PMCSTAT_ATTROFF(v_attrs);
+ PMCSTAT_PRINTW(" %-10.10s %-20.20s",
+ pmcstat_string_unintern(cg->pcg_image->pi_name),
+ ns);
+
+ nchildren = cg->pcg_nchildren;
+ if (nchildren == 0) {
+ PMCSTAT_PRINTW("\n");
+ return;
+ }
+
+ width = pmcstat_displaywidth - 40;
+
+ if ((sortbuffer = (struct pmcstat_cgnode **)
+ malloc(sizeof(struct pmcstat_cgnode *) *
+ nchildren)) == NULL)
+ err(EX_OSERR, "ERROR: Cannot print callgraph");
+ cgn = sortbuffer;
+
+ LIST_FOREACH(pcg, &cg->pcg_children, pcg_sibling)
+ *cgn++ = pcg;
+
+ assert(cgn - sortbuffer == (int)nchildren);
+
+ qsort(sortbuffer, nchildren, sizeof(struct pmcstat_cgnode *),
+ pmcstat_cgnode_compare);
+
+ /* Count how many callers. */
+ for (cgn = sortbuffer, n = 0; n < nchildren; n++, cgn++) {
+ pcg = *cgn;
+
+ v = PMCPL_CG_COUNTP(pcg);
+ if (v < pmcstat_threshold)
+ break;
+ }
+ nchildren = n;
+
+ for (cgn = sortbuffer, n = 0; n < nchildren; n++, cgn++) {
+ pcg = *cgn;
+
+ /* Format value. */
+ if (nchildren > 1) {
+ v = PMCPL_CG_COUNTP(pcg);
+ vs_len = snprintf(vs, sizeof(vs), ":%.1f", v);
+ v_attrs = PMCSTAT_ATTRPERCENT(v);
+ } else
+ vs_len = 0;
+
+ /* Format name. */
+ sym = pmcstat_symbol_search(pcg->pcg_image, pcg->pcg_func);
+ if (sym != NULL) {
+ ns_len = snprintf(ns, sizeof(ns), "%s",
+ pmcstat_string_unintern(sym->ps_name));
+ } else
+ ns_len = snprintf(ns, sizeof(ns), "%p",
+ (void *)pcg->pcg_func);
+
+ len = ns_len + vs_len + 1;
+ if (width - len < 0) {
+ PMCSTAT_PRINTW("...");
+ break;
+ }
+ width -= len;
+
+ PMCSTAT_PRINTW(" %s", ns);
+ if (nchildren > 1) {
+ PMCSTAT_ATTRON(v_attrs);
+ PMCSTAT_PRINTW("%s", vs);
+ PMCSTAT_ATTROFF(v_attrs);
+ }
+ }
+ PMCSTAT_PRINTW("\n");
+ free(sortbuffer);
+}
+
+/*
+ * Top mode display.
+ */
+
+void
+pmcpl_cg_topdisplay(void)
+{
+ int n, nentries;
+ uint32_t nsamples;
+ struct pmcstat_cgnode **sortbuffer, **cgn;
+ struct pmcstat_cgnode_hash *pch;
+ struct pmcstat_pmcrecord *pmcr;
+
+ pmcr = pmcstat_pmcindex_to_pmcr(pmcstat_pmcinfilter);
+
+ /*
+ * We pull out all callgraph nodes in the top-level hash table
+ * with a matching PMC index. We then sort these based on the
+ * frequency of occurrence. Each callgraph node is then
+ * printed.
+ */
+
+ nsamples = 0;
+
+ if ((sortbuffer = (struct pmcstat_cgnode **)
+ malloc(sizeof(struct pmcstat_cgnode *) *
+ pmcstat_cgnode_hash_count)) == NULL)
+ err(EX_OSERR, "ERROR: Cannot sort callgraph");
+ cgn = sortbuffer;
+
+ for (n = 0; n < PMCSTAT_NHASH; n++)
+ LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
+ if (pmcr == NULL || pch->pch_pmcid == pmcr->pr_pmcid) {
+ nsamples += pch->pch_cgnode->pcg_count;
+ *cgn++ = pch->pch_cgnode;
+ }
+
+ nentries = cgn - sortbuffer;
+ assert(nentries <= pmcstat_cgnode_hash_count);
+
+ if (nentries == 0) {
+ free(sortbuffer);
+ return;
+ }
+
+ qsort(sortbuffer, nentries, sizeof(struct pmcstat_cgnode *),
+ pmcstat_cgnode_compare);
+
+ PMCSTAT_PRINTW("%5.5s %-10.10s %-20.20s %s\n",
+ "%SAMP", "IMAGE", "FUNCTION", "CALLERS");
+
+ nentries = min(pmcstat_displayheight - 2, nentries);
+
+ for (cgn = sortbuffer, n = 0; n < nentries; n++, cgn++) {
+ if (PMCPL_CG_COUNTP(*cgn) < pmcstat_threshold)
+ break;
+ pmcstat_cgnode_topprint(*cgn, 0, nsamples);
+ }
+
+ free(sortbuffer);
+}
+
+/*
+ * Handle top mode keypress.
+ */
+
+int
+pmcpl_cg_topkeypress(int c, WINDOW *w)
+{
+
+ (void) c; (void) w;
+
+ return 0;
+}
+
+int
+pmcpl_cg_init(void)
+{
+ int i;
+
+ pmcstat_cgnode_hash_count = 0;
+ pmcstat_previous_filename_printed = NULL;
+
+ for (i = 0; i < PMCSTAT_NHASH; i++) {
+ LIST_INIT(&pmcstat_cgnode_hash[i]);
+ }
+
+ return (0);
+}
+
+void
+pmcpl_cg_shutdown(FILE *mf)
+{
+ int i;
+ struct pmcstat_cgnode_hash *pch, *pchtmp;
+
+ (void) mf;
+
+ if (args.pa_flags & FLAG_DO_CALLGRAPHS)
+ pmcstat_callgraph_print();
+
+ /*
+ * Free memory.
+ */
+ for (i = 0; i < PMCSTAT_NHASH; i++) {
+ LIST_FOREACH_SAFE(pch, &pmcstat_cgnode_hash[i], pch_next,
+ pchtmp) {
+ pmcstat_cgnode_free(pch->pch_cgnode);
+ LIST_REMOVE(pch, pch_next);
+ free(pch);
+ }
+ }
+}
+
diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.h b/usr.sbin/pmcstat/pmcpl_callgraph.h
new file mode 100644
index 0000000..aaf0e1b
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_callgraph.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2005-2007, Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PMCSTAT_PL_CALLGRAPH_H_
+#define _PMCSTAT_PL_CALLGRAPH_H_
+
+/*
+ * Each call graph node is tracked by a pmcstat_cgnode struct.
+ */
+
+struct pmcstat_cgnode {
+ struct pmcstat_image *pcg_image;
+ uintfptr_t pcg_func;
+ uint32_t pcg_count;
+ uint32_t pcg_nchildren;
+ LIST_ENTRY(pmcstat_cgnode) pcg_sibling;
+ LIST_HEAD(,pmcstat_cgnode) pcg_children;
+};
+
+struct pmcstat_cgnode_hash {
+ struct pmcstat_cgnode *pch_cgnode;
+ pmc_id_t pch_pmcid;
+ LIST_ENTRY(pmcstat_cgnode_hash) pch_next;
+};
+extern LIST_HEAD(pmcstat_cgnode_hash_list, pmcstat_cgnode_hash) pmcstat_cgnode_hash[PMCSTAT_NHASH];
+extern int pmcstat_cgnode_hash_count;
+
+/* Function prototypes */
+int pmcpl_cg_init(void);
+void pmcpl_cg_shutdown(FILE *mf);
+void pmcpl_cg_process(
+ struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
+int pmcpl_cg_topkeypress(int c, WINDOW *w);
+void pmcpl_cg_topdisplay(void);
+void pmcpl_cg_configure(char *opt);
+
+#endif /* _PMCSTAT_PL_CALLGRAPH_H_ */
diff --git a/usr.sbin/pmcstat/pmcpl_calltree.c b/usr.sbin/pmcstat/pmcpl_calltree.c
new file mode 100644
index 0000000..498092d
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_calltree.c
@@ -0,0 +1,1000 @@
+/*-
+ * Copyright (c) 2009, Fabien Thomas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+/*
+ * Process hwpmc(4) samples as calltree.
+ *
+ * Output file format compatible with Kcachegrind (kdesdk).
+ * Handle top mode with a sorted tree display.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/queue.h>
+
+#include <assert.h>
+#include <curses.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pmc.h>
+#include <pmclog.h>
+#include <sysexits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sysexits.h>
+
+#include "pmcstat.h"
+#include "pmcstat_log.h"
+#include "pmcstat_top.h"
+#include "pmcpl_calltree.h"
+
+#define PMCPL_CT_GROWSIZE 4
+
+static pmcstat_interned_string pmcpl_ct_prevfn;
+
+static int pmcstat_skiplink = 0;
+
+struct pmcpl_ct_node;
+
+/* Get the sample value for PMC a. */
+#define PMCPL_CT_SAMPLE(a, b) \
+ ((a) < (b)->npmcs ? (b)->sb[a] : 0)
+
+/* Get the sample value in percent related to rsamples. */
+#define PMCPL_CT_SAMPLEP(a, b) \
+ (PMCPL_CT_SAMPLE(a, b) * 100.0 / rsamples->sb[a])
+
+struct pmcpl_ct_sample {
+ int npmcs; /* Max pmc index available. */
+ unsigned *sb; /* Sample buffer for 0..npmcs. */
+};
+
+struct pmcpl_ct_arc {
+ struct pmcpl_ct_sample pcta_samples;
+ struct pmcpl_ct_sample pcta_callid;
+ unsigned pcta_call;
+ struct pmcpl_ct_node *pcta_child;
+};
+
+struct pmcpl_ct_instr {
+ uintfptr_t pctf_func;
+ struct pmcpl_ct_sample pctf_samples;
+};
+
+/*
+ * Each calltree node is tracked by a pmcpl_ct_node struct.
+ */
+struct pmcpl_ct_node {
+#define PMCPL_PCT_TAG 0x00000001 /* Loop detection. */
+ uint32_t pct_flags;
+ struct pmcstat_image *pct_image;
+ uintfptr_t pct_func;
+ struct pmcpl_ct_sample pct_samples;
+
+ int pct_narc;
+ int pct_arc_c;
+ struct pmcpl_ct_arc *pct_arc;
+
+ /* TODO: optimize for large number of items. */
+ int pct_ninstr;
+ int pct_instr_c;
+ struct pmcpl_ct_instr *pct_instr;
+};
+
+struct pmcpl_ct_node_hash {
+ struct pmcpl_ct_node *pch_ctnode;
+ LIST_ENTRY(pmcpl_ct_node_hash) pch_next;
+};
+
+struct pmcpl_ct_sample pmcpl_ct_callid;
+
+#define PMCPL_CT_MAXCOL PMC_CALLCHAIN_DEPTH_MAX
+#define PMCPL_CT_MAXLINE 256
+struct pmcpl_ct_node *pmcpl_ct_topscreen[PMCPL_CT_MAXCOL][PMCPL_CT_MAXLINE];
+
+/*
+ * All nodes indexed by function/image name are placed in a hash table.
+ */
+static LIST_HEAD(,pmcpl_ct_node_hash) pmcpl_ct_node_hash[PMCSTAT_NHASH];
+
+/*
+ * Root node for the graph.
+ */
+static struct pmcpl_ct_node *pmcpl_ct_root;
+
+/*
+ * Prototypes
+ */
+
+/*
+ * Initialize a samples.
+ */
+
+static void
+pmcpl_ct_samples_init(struct pmcpl_ct_sample *samples)
+{
+
+ samples->npmcs = 0;
+ samples->sb = NULL;
+}
+
+/*
+ * Free a samples.
+ */
+
+static void
+pmcpl_ct_samples_free(struct pmcpl_ct_sample *samples)
+{
+
+ samples->npmcs = 0;
+ free(samples->sb);
+ samples->sb = NULL;
+}
+
+/*
+ * Grow a sample block to store pmcstat_npmcs PMCs.
+ */
+
+static void
+pmcpl_ct_samples_grow(struct pmcpl_ct_sample *samples)
+{
+ int npmcs;
+
+ /* Enough storage. */
+ if (pmcstat_npmcs <= samples->npmcs)
+ return;
+
+ npmcs = samples->npmcs +
+ max(pmcstat_npmcs - samples->npmcs, PMCPL_CT_GROWSIZE);
+ samples->sb = realloc(samples->sb, npmcs * sizeof(unsigned));
+ if (samples->sb == NULL)
+ errx(EX_SOFTWARE, "ERROR: out of memory");
+ bzero((char *)samples->sb + samples->npmcs * sizeof(unsigned),
+ (npmcs - samples->npmcs) * sizeof(unsigned));
+ samples->npmcs = npmcs;
+}
+
+/*
+ * Compute the sum of all root arcs.
+ */
+
+static void
+pmcpl_ct_samples_root(struct pmcpl_ct_sample *samples)
+{
+ int i, pmcin;
+
+ pmcpl_ct_samples_init(samples);
+ pmcpl_ct_samples_grow(samples);
+
+ for (i = 0; i < pmcpl_ct_root->pct_narc; i++)
+ for (pmcin = 0; pmcin < pmcstat_npmcs; pmcin++)
+ samples->sb[pmcin] += PMCPL_CT_SAMPLE(pmcin,
+ &pmcpl_ct_root->pct_arc[i].pcta_samples);
+}
+
+/*
+ * Grow the arc table.
+ */
+
+static void
+pmcpl_ct_arc_grow(int cursize, int *maxsize, struct pmcpl_ct_arc **items)
+{
+ int nmaxsize;
+
+ if (cursize < *maxsize)
+ return;
+
+ nmaxsize = *maxsize + max(cursize + 1 - *maxsize, PMCPL_CT_GROWSIZE);
+ *items = realloc(*items, nmaxsize * sizeof(struct pmcpl_ct_arc));
+ if (*items == NULL)
+ errx(EX_SOFTWARE, "ERROR: out of memory");
+ bzero((char *)*items + *maxsize * sizeof(struct pmcpl_ct_arc),
+ (nmaxsize - *maxsize) * sizeof(struct pmcpl_ct_arc));
+ *maxsize = nmaxsize;
+}
+
+/*
+ * Compare two arc by samples value.
+ */
+static int
+pmcpl_ct_arc_compare(void *thunk, const void *a, const void *b)
+{
+ const struct pmcpl_ct_arc *ct1, *ct2;
+ int pmcin = *(int *)thunk;
+
+ ct1 = (const struct pmcpl_ct_arc *) a;
+ ct2 = (const struct pmcpl_ct_arc *) b;
+
+ /* Sort in reverse order */
+ if (PMCPL_CT_SAMPLE(pmcin, &ct1->pcta_samples) <
+ PMCPL_CT_SAMPLE(pmcin, &ct2->pcta_samples))
+ return (1);
+ if (PMCPL_CT_SAMPLE(pmcin, &ct1->pcta_samples) >
+ PMCPL_CT_SAMPLE(pmcin, &ct2->pcta_samples))
+ return (-1);
+ return (0);
+}
+
+/*
+ * Grow the instr table.
+ */
+
+static void
+pmcpl_ct_instr_grow(int cursize, int *maxsize, struct pmcpl_ct_instr **items)
+{
+ int nmaxsize;
+
+ if (cursize < *maxsize)
+ return;
+
+ nmaxsize = *maxsize + max(cursize + 1 - *maxsize, PMCPL_CT_GROWSIZE);
+ *items = realloc(*items, nmaxsize * sizeof(struct pmcpl_ct_instr));
+ if (*items == NULL)
+ errx(EX_SOFTWARE, "ERROR: out of memory");
+ bzero((char *)*items + *maxsize * sizeof(struct pmcpl_ct_instr),
+ (nmaxsize - *maxsize) * sizeof(struct pmcpl_ct_instr));
+ *maxsize = nmaxsize;
+}
+
+/*
+ * Add a new instruction sample to given node.
+ */
+
+static void
+pmcpl_ct_instr_add(struct pmcpl_ct_node *ct, int pmcin, uintfptr_t pc)
+{
+ int i;
+ struct pmcpl_ct_instr *in;
+
+ for (i = 0; i<ct->pct_ninstr; i++) {
+ if (ct->pct_instr[i].pctf_func == pc) {
+ in = &ct->pct_instr[i];
+ pmcpl_ct_samples_grow(&in->pctf_samples);
+ in->pctf_samples.sb[pmcin]++;
+ return;
+ }
+ }
+
+ pmcpl_ct_instr_grow(ct->pct_ninstr, &ct->pct_instr_c, &ct->pct_instr);
+ in = &ct->pct_instr[ct->pct_ninstr];
+ in->pctf_func = pc;
+ pmcpl_ct_samples_init(&in->pctf_samples);
+ pmcpl_ct_samples_grow(&in->pctf_samples);
+ in->pctf_samples.sb[pmcin] = 1;
+ ct->pct_ninstr++;
+}
+
+/*
+ * Allocate a new node.
+ */
+
+static struct pmcpl_ct_node *
+pmcpl_ct_node_allocate(struct pmcstat_image *image, uintfptr_t pc)
+{
+ struct pmcpl_ct_node *ct;
+
+ if ((ct = malloc(sizeof(*ct))) == NULL)
+ err(EX_OSERR, "ERROR: Cannot allocate callgraph node");
+
+ ct->pct_flags = 0;
+ ct->pct_image = image;
+ ct->pct_func = pc;
+
+ pmcpl_ct_samples_init(&ct->pct_samples);
+
+ ct->pct_narc = 0;
+ ct->pct_arc_c = 0;
+ ct->pct_arc = NULL;
+
+ ct->pct_ninstr = 0;
+ ct->pct_instr_c = 0;
+ ct->pct_instr = NULL;
+
+ return (ct);
+}
+
+/*
+ * Free a node.
+ */
+
+static void
+pmcpl_ct_node_free(struct pmcpl_ct_node *ct)
+{
+ int i;
+
+ for (i = 0; i < ct->pct_narc; i++) {
+ pmcpl_ct_samples_free(&ct->pct_arc[i].pcta_samples);
+ pmcpl_ct_samples_free(&ct->pct_arc[i].pcta_callid);
+ }
+
+ pmcpl_ct_samples_free(&ct->pct_samples);
+ free(ct->pct_arc);
+ free(ct->pct_instr);
+ free(ct);
+}
+
+/*
+ * Clear the graph tag on each node.
+ */
+static void
+pmcpl_ct_node_cleartag(void)
+{
+ int i;
+ struct pmcpl_ct_node_hash *pch;
+
+ for (i = 0; i < PMCSTAT_NHASH; i++)
+ LIST_FOREACH(pch, &pmcpl_ct_node_hash[i], pch_next)
+ pch->pch_ctnode->pct_flags &= ~PMCPL_PCT_TAG;
+
+ pmcpl_ct_root->pct_flags &= ~PMCPL_PCT_TAG;
+}
+
+/*
+ * Print the callchain line by line with maximum cost at top.
+ */
+
+static int
+pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct,
+ struct pmcpl_ct_sample *rsamples, int x, int *y)
+{
+ int i;
+
+ if (ct->pct_flags & PMCPL_PCT_TAG)
+ return 0;
+
+ ct->pct_flags |= PMCPL_PCT_TAG;
+
+ if (x >= PMCPL_CT_MAXCOL) {
+ pmcpl_ct_topscreen[x][*y] = NULL;
+ return 1;
+ }
+ pmcpl_ct_topscreen[x][*y] = ct;
+
+ /*
+ * This is a terminal node
+ */
+ if (ct->pct_narc == 0) {
+ pmcpl_ct_topscreen[x+1][*y] = NULL;
+ if (*y >= PMCPL_CT_MAXLINE ||
+ *y >= pmcstat_displaywidth)
+ return 1;
+ *y = *y + 1;
+ for (i=0; i < x; i++)
+ pmcpl_ct_topscreen[i][*y] =
+ pmcpl_ct_topscreen[i][*y - 1];
+ return 0;
+ }
+
+ /*
+ * Quicksort the arcs.
+ */
+ qsort_r(ct->pct_arc, ct->pct_narc, sizeof(struct pmcpl_ct_arc),
+ &pmcin, pmcpl_ct_arc_compare);
+
+ for (i = 0; i < ct->pct_narc; i++) {
+ if (PMCPL_CT_SAMPLEP(pmcin,
+ &ct->pct_arc[i].pcta_samples) > pmcstat_threshold) {
+ if (pmcpl_ct_node_dumptop(pmcin,
+ ct->pct_arc[i].pcta_child,
+ rsamples, x+1, y))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Format and display given PMC index.
+ */
+
+static void
+pmcpl_ct_node_printtop(struct pmcpl_ct_sample *rsamples, int pmcin, int maxy)
+{
+ int v_attrs, ns_len, vs_len, is_len, width, indentwidth, x, y;
+ float v;
+ char ns[30], vs[10], is[20];
+ struct pmcpl_ct_node *ct;
+ struct pmcstat_symbol *sym;
+ const char *space = " ";
+
+ for (y = 0; y < maxy; y++) {
+ /* Output image. */
+ ct = pmcpl_ct_topscreen[0][y];
+ snprintf(is, sizeof(is), "%-10.10s",
+ pmcstat_string_unintern(ct->pct_image->pi_name));
+ PMCSTAT_PRINTW("%s ", is);
+ width = indentwidth = 11;
+
+ for (x = 0; pmcpl_ct_topscreen[x][y] !=NULL; x++) {
+
+ ct = pmcpl_ct_topscreen[x][y];
+
+ ns[0] = '\0'; ns_len = 0;
+ vs[0] = '\0'; vs_len = 0;
+ is[0] = '\0'; is_len = 0;
+
+ /* Format value. */
+ v = PMCPL_CT_SAMPLEP(pmcin, &ct->pct_samples);
+ if (v > pmcstat_threshold)
+ vs_len = snprintf(vs, sizeof(vs), "(%.1f%%)", v);
+ v_attrs = PMCSTAT_ATTRPERCENT(v);
+
+ if (pmcstat_skiplink && v <= pmcstat_threshold) {
+ PMCSTAT_PRINTW(". ");
+ width += 2;
+ continue;
+ }
+ sym = pmcstat_symbol_search(ct->pct_image, ct->pct_func);
+ if (sym != NULL) {
+ ns_len = snprintf(ns, sizeof(ns), "%s",
+ pmcstat_string_unintern(sym->ps_name));
+ } else
+ ns_len = snprintf(ns, sizeof(ns), "%p",
+ (void *)ct->pct_func);
+
+ /* Format image. */
+ if (x > 0 && pmcpl_ct_topscreen[x-1][y]->pct_image != ct->pct_image)
+ is_len = snprintf(is, sizeof(is), "@%s",
+ pmcstat_string_unintern(ct->pct_image->pi_name));
+
+ /* Check for line wrap. */
+ width += ns_len + is_len + vs_len + 1;
+ if (width >= pmcstat_displaywidth) {
+ PMCSTAT_PRINTW("\n%*s", indentwidth, space);
+ width = indentwidth + ns_len + is_len + vs_len;
+ }
+
+ PMCSTAT_ATTRON(v_attrs);
+ PMCSTAT_PRINTW("%s%s%s ", ns, is, vs);
+ PMCSTAT_ATTROFF(v_attrs);
+ }
+ PMCSTAT_PRINTW("\n");
+ }
+}
+
+/*
+ * Output top mode snapshot.
+ */
+
+void
+pmcpl_ct_topdisplay(void)
+{
+ int i, x, y, pmcin;
+ struct pmcpl_ct_sample rsamples;
+
+ pmcpl_ct_samples_root(&rsamples);
+
+ PMCSTAT_PRINTW("%-10.10s %s\n", "IMAGE", "CALLTREE");
+
+ for (pmcin = 0; pmcin < pmcstat_npmcs; pmcin++) {
+ /* Filter PMCs. */
+ if (pmcstat_pmcinfilter != pmcin)
+ continue;
+
+ pmcpl_ct_node_cleartag();
+
+ /* Quicksort the arcs. */
+ qsort_r(pmcpl_ct_root->pct_arc,
+ pmcpl_ct_root->pct_narc,
+ sizeof(struct pmcpl_ct_arc),
+ &pmcin, pmcpl_ct_arc_compare);
+
+ x = y = 0;
+ for (i = 0; i < pmcpl_ct_root->pct_narc; i++) {
+ if (pmcpl_ct_node_dumptop(pmcin,
+ pmcpl_ct_root->pct_arc[i].pcta_child,
+ &rsamples, x, &y)) {
+ break;
+ }
+ }
+
+ pmcpl_ct_node_printtop(&rsamples, pmcin, y);
+ }
+ pmcpl_ct_samples_free(&rsamples);
+}
+
+/*
+ * Handle top mode keypress.
+ */
+
+int
+pmcpl_ct_topkeypress(int c, WINDOW *w)
+{
+
+ switch (c) {
+ case 'f':
+ pmcstat_skiplink = !pmcstat_skiplink;
+ wprintw(w, "skip empty link %s", pmcstat_skiplink ? "on" : "off");
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Look for a callgraph node associated with pmc `pmcid' in the global
+ * hash table that corresponds to the given `pc' value in the process map
+ * `ppm'.
+ */
+
+static struct pmcpl_ct_node *
+pmcpl_ct_node_hash_lookup_pc(struct pmcpl_ct_node *parent,
+ struct pmcstat_pcmap *ppm, uintfptr_t pc, int pmcin)
+{
+ struct pmcstat_symbol *sym;
+ struct pmcstat_image *image;
+ struct pmcpl_ct_node *ct;
+ struct pmcpl_ct_node_hash *h;
+ struct pmcpl_ct_arc *arc;
+ uintfptr_t loadaddress;
+ int i;
+ unsigned int hash;
+
+ assert(parent != NULL);
+
+ image = ppm->ppm_image;
+
+ loadaddress = ppm->ppm_lowpc + image->pi_vaddr - image->pi_start;
+ pc -= loadaddress; /* Convert to an offset in the image. */
+
+ /*
+ * Try determine the function at this offset. If we can't
+ * find a function round leave the `pc' value alone.
+ */
+ if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
+ pc = sym->ps_start;
+
+ for (hash = i = 0; i < (int)sizeof(uintfptr_t); i++)
+ hash += (pc >> i) & 0xFF;
+
+ hash &= PMCSTAT_HASH_MASK;
+
+ ct = NULL;
+ LIST_FOREACH(h, &pmcpl_ct_node_hash[hash], pch_next) {
+ ct = h->pch_ctnode;
+
+ assert(ct != NULL);
+
+ if (ct->pct_image == image && ct->pct_func == pc) {
+ /*
+ * Find related arc in parent node and
+ * increment the sample count.
+ */
+ for (i = 0; i < parent->pct_narc; i++) {
+ if (parent->pct_arc[i].pcta_child == ct) {
+ arc = &parent->pct_arc[i];
+ pmcpl_ct_samples_grow(&arc->pcta_samples);
+ arc->pcta_samples.sb[pmcin]++;
+ /* Estimate call count. */
+ pmcpl_ct_samples_grow(&arc->pcta_callid);
+ if (pmcpl_ct_callid.sb[pmcin] -
+ arc->pcta_callid.sb[pmcin] > 1)
+ arc->pcta_call++;
+ arc->pcta_callid.sb[pmcin] =
+ pmcpl_ct_callid.sb[pmcin];
+ return (ct);
+ }
+ }
+
+ /*
+ * No arc found for us, add ourself to the parent.
+ */
+ pmcpl_ct_arc_grow(parent->pct_narc,
+ &parent->pct_arc_c, &parent->pct_arc);
+ arc = &parent->pct_arc[parent->pct_narc];
+ pmcpl_ct_samples_grow(&arc->pcta_samples);
+ arc->pcta_samples.sb[pmcin] = 1;
+ arc->pcta_call = 1;
+ pmcpl_ct_samples_grow(&arc->pcta_callid);
+ arc->pcta_callid.sb[pmcin] = pmcpl_ct_callid.sb[pmcin];
+ arc->pcta_child = ct;
+ parent->pct_narc++;
+ return (ct);
+ }
+ }
+
+ /*
+ * We haven't seen this (pmcid, pc) tuple yet, so allocate a
+ * new callgraph node and a new hash table entry for it.
+ */
+ ct = pmcpl_ct_node_allocate(image, pc);
+ if ((h = malloc(sizeof(*h))) == NULL)
+ err(EX_OSERR, "ERROR: Could not allocate callgraph node");
+
+ h->pch_ctnode = ct;
+ LIST_INSERT_HEAD(&pmcpl_ct_node_hash[hash], h, pch_next);
+
+ pmcpl_ct_arc_grow(parent->pct_narc,
+ &parent->pct_arc_c, &parent->pct_arc);
+ arc = &parent->pct_arc[parent->pct_narc];
+ pmcpl_ct_samples_grow(&arc->pcta_samples);
+ arc->pcta_samples.sb[pmcin] = 1;
+ arc->pcta_call = 1;
+ pmcpl_ct_samples_grow(&arc->pcta_callid);
+ arc->pcta_callid.sb[pmcin] = pmcpl_ct_callid.sb[pmcin];
+ arc->pcta_child = ct;
+ parent->pct_narc++;
+ return (ct);
+}
+
+/*
+ * Record a callchain.
+ */
+
+void
+pmcpl_ct_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
+{
+ int n, pmcin;
+ struct pmcstat_pcmap *ppm[PMC_CALLCHAIN_DEPTH_MAX];
+ struct pmcstat_process *km;
+ struct pmcpl_ct_node *parent, *child;
+
+ (void) cpu;
+
+ assert(nsamples>0 && nsamples<=PMC_CALLCHAIN_DEPTH_MAX);
+
+ /* Get the PMC index. */
+ pmcin = pmcr->pr_pmcin;
+
+ /*
+ * Validate mapping for the callchain.
+ * Go from bottom to first invalid entry.
+ */
+ km = pmcstat_kernproc;
+ for (n = 0; n < (int)nsamples; n++) {
+ ppm[n] = pmcstat_process_find_map(usermode ?
+ pp : km, cc[n]);
+ if (ppm[n] == NULL) {
+ /* Detect full frame capture (kernel + user). */
+ if (!usermode) {
+ ppm[n] = pmcstat_process_find_map(pp, cc[n]);
+ if (ppm[n] != NULL)
+ km = pp;
+ }
+ }
+ if (ppm[n] == NULL)
+ break;
+ }
+ if (n-- == 0) {
+ pmcstat_stats.ps_callchain_dubious_frames++;
+ return;
+ }
+
+ /* Increase the call generation counter. */
+ pmcpl_ct_samples_grow(&pmcpl_ct_callid);
+ pmcpl_ct_callid.sb[pmcin]++;
+
+ /*
+ * Iterate remaining addresses.
+ */
+ for (parent = pmcpl_ct_root, child = NULL; n >= 0; n--) {
+ child = pmcpl_ct_node_hash_lookup_pc(parent, ppm[n], cc[n],
+ pmcin);
+ if (child == NULL) {
+ pmcstat_stats.ps_callchain_dubious_frames++;
+ continue;
+ }
+ parent = child;
+ }
+
+ /*
+ * Increment the sample count for this PMC.
+ */
+ if (child != NULL) {
+ pmcpl_ct_samples_grow(&child->pct_samples);
+ child->pct_samples.sb[pmcin]++;
+
+ /* Update per instruction sample if required. */
+ if (args.pa_ctdumpinstr)
+ pmcpl_ct_instr_add(child, pmcin, cc[0] -
+ (ppm[0]->ppm_lowpc + ppm[0]->ppm_image->pi_vaddr -
+ ppm[0]->ppm_image->pi_start));
+ }
+}
+
+/*
+ * Print node self cost.
+ */
+
+static void
+pmcpl_ct_node_printself(struct pmcpl_ct_node *ct)
+{
+ int i, j, line;
+ uintptr_t addr;
+ struct pmcstat_symbol *sym;
+ char sourcefile[PATH_MAX];
+ char funcname[PATH_MAX];
+
+ /*
+ * Object binary.
+ */
+#ifdef PMCPL_CT_OPTIMIZEFN
+ if (pmcpl_ct_prevfn != ct->pct_image->pi_fullpath) {
+#endif
+ pmcpl_ct_prevfn = ct->pct_image->pi_fullpath;
+ fprintf(args.pa_graphfile, "ob=%s\n",
+ pmcstat_string_unintern(pmcpl_ct_prevfn));
+#ifdef PMCPL_CT_OPTIMIZEFN
+ }
+#endif
+
+ /*
+ * Function name.
+ */
+ if (pmcstat_image_addr2line(ct->pct_image, ct->pct_func,
+ sourcefile, sizeof(sourcefile), &line,
+ funcname, sizeof(funcname))) {
+ fprintf(args.pa_graphfile, "fn=%s\n",
+ funcname);
+ } else {
+ sym = pmcstat_symbol_search(ct->pct_image, ct->pct_func);
+ if (sym != NULL)
+ fprintf(args.pa_graphfile, "fn=%s\n",
+ pmcstat_string_unintern(sym->ps_name));
+ else
+ fprintf(args.pa_graphfile, "fn=%p\n",
+ (void *)(ct->pct_image->pi_vaddr + ct->pct_func));
+ }
+
+ /*
+ * Self cost.
+ */
+ if (ct->pct_ninstr > 0) {
+ for (i = 0; i < ct->pct_ninstr; i++) {
+ addr = ct->pct_image->pi_vaddr +
+ ct->pct_instr[i].pctf_func;
+ line = 0;
+ if (pmcstat_image_addr2line(ct->pct_image, addr,
+ sourcefile, sizeof(sourcefile), &line,
+ funcname, sizeof(funcname)))
+ fprintf(args.pa_graphfile, "fl=%s\n", sourcefile);
+ fprintf(args.pa_graphfile, "%p %u", (void *)addr, line);
+ for (j = 0; j<pmcstat_npmcs; j++)
+ fprintf(args.pa_graphfile, " %u",
+ PMCPL_CT_SAMPLE(j,
+ &ct->pct_instr[i].pctf_samples));
+ fprintf(args.pa_graphfile, "\n");
+ }
+ } else {
+ addr = ct->pct_image->pi_vaddr + ct->pct_func;
+ line = 0;
+ if (pmcstat_image_addr2line(ct->pct_image, addr,
+ sourcefile, sizeof(sourcefile), &line,
+ funcname, sizeof(funcname)))
+ fprintf(args.pa_graphfile, "fl=%s\n", sourcefile);
+ fprintf(args.pa_graphfile, "* *");
+ for (i = 0; i<pmcstat_npmcs ; i++)
+ fprintf(args.pa_graphfile, " %u",
+ PMCPL_CT_SAMPLE(i, &ct->pct_samples));
+ fprintf(args.pa_graphfile, "\n");
+ }
+}
+
+/*
+ * Print node child cost.
+ */
+
+static void
+pmcpl_ct_node_printchild(struct pmcpl_ct_node *ct)
+{
+ int i, j, line;
+ uintptr_t addr;
+ struct pmcstat_symbol *sym;
+ struct pmcpl_ct_node *child;
+ char sourcefile[PATH_MAX];
+ char funcname[PATH_MAX];
+
+ /*
+ * Child cost.
+ * TODO: attach child cost to the real position in the funtion.
+ * TODO: cfn=<fn> / call <ncall> addr(<fn>) / addr(call <fn>) <arccost>
+ */
+ for (i=0 ; i<ct->pct_narc; i++) {
+ child = ct->pct_arc[i].pcta_child;
+
+ /* Object binary. */
+#ifdef PMCPL_CT_OPTIMIZEFN
+ if (pmcpl_ct_prevfn != child->pct_image->pi_fullpath) {
+#endif
+ pmcpl_ct_prevfn = child->pct_image->pi_fullpath;
+ fprintf(args.pa_graphfile, "cob=%s\n",
+ pmcstat_string_unintern(pmcpl_ct_prevfn));
+#if PMCPL_CT_OPTIMIZEFN
+ }
+#endif
+ /* Child function name. */
+ addr = child->pct_image->pi_vaddr + child->pct_func;
+ /* Child function source file. */
+ if (pmcstat_image_addr2line(child->pct_image, addr,
+ sourcefile, sizeof(sourcefile), &line,
+ funcname, sizeof(funcname))) {
+ fprintf(args.pa_graphfile, "cfn=%s\n", funcname);
+ fprintf(args.pa_graphfile, "cfl=%s\n", sourcefile);
+ } else {
+ sym = pmcstat_symbol_search(child->pct_image,
+ child->pct_func);
+ if (sym != NULL)
+ fprintf(args.pa_graphfile, "cfn=%s\n",
+ pmcstat_string_unintern(sym->ps_name));
+ else
+ fprintf(args.pa_graphfile, "cfn=%p\n", (void *)addr);
+ }
+
+ /* Child function address, line and call count. */
+ fprintf(args.pa_graphfile, "calls=%u %p %u\n",
+ ct->pct_arc[i].pcta_call, (void *)addr, line);
+
+ if (ct->pct_image != NULL) {
+ /* Call address, line, sample. */
+ addr = ct->pct_image->pi_vaddr + ct->pct_func;
+ line = 0;
+ pmcstat_image_addr2line(ct->pct_image, addr, sourcefile,
+ sizeof(sourcefile), &line,
+ funcname, sizeof(funcname));
+ fprintf(args.pa_graphfile, "%p %u", (void *)addr, line);
+ }
+ else
+ fprintf(args.pa_graphfile, "* *");
+ for (j = 0; j<pmcstat_npmcs; j++)
+ fprintf(args.pa_graphfile, " %u",
+ PMCPL_CT_SAMPLE(j, &ct->pct_arc[i].pcta_samples));
+ fprintf(args.pa_graphfile, "\n");
+ }
+}
+
+/*
+ * Clean the PMC name for Kcachegrind formula
+ */
+
+static void
+pmcpl_ct_fixup_pmcname(char *s)
+{
+ char *p;
+
+ for (p = s; *p; p++)
+ if (!isalnum(*p))
+ *p = '_';
+}
+
+/*
+ * Print a calltree (KCachegrind) for all PMCs.
+ */
+
+static void
+pmcpl_ct_print(void)
+{
+ int n, i;
+ struct pmcpl_ct_node_hash *pch;
+ struct pmcpl_ct_sample rsamples;
+ char name[40];
+
+ pmcpl_ct_samples_root(&rsamples);
+ pmcpl_ct_prevfn = NULL;
+
+ fprintf(args.pa_graphfile,
+ "version: 1\n"
+ "creator: pmcstat\n"
+ "positions: instr line\n"
+ "events:");
+ for (i=0; i<pmcstat_npmcs; i++) {
+ snprintf(name, sizeof(name), "%s_%d",
+ pmcstat_pmcindex_to_name(i), i);
+ pmcpl_ct_fixup_pmcname(name);
+ fprintf(args.pa_graphfile, " %s", name);
+ }
+ fprintf(args.pa_graphfile, "\nsummary:");
+ for (i=0; i<pmcstat_npmcs ; i++)
+ fprintf(args.pa_graphfile, " %u",
+ PMCPL_CT_SAMPLE(i, &rsamples));
+ fprintf(args.pa_graphfile, "\n\n");
+
+ /*
+ * Fake root node
+ */
+ fprintf(args.pa_graphfile, "ob=FreeBSD\n");
+ fprintf(args.pa_graphfile, "fn=ROOT\n");
+ fprintf(args.pa_graphfile, "* *");
+ for (i = 0; i<pmcstat_npmcs ; i++)
+ fprintf(args.pa_graphfile, " 0");
+ fprintf(args.pa_graphfile, "\n");
+ pmcpl_ct_node_printchild(pmcpl_ct_root);
+
+ for (n = 0; n < PMCSTAT_NHASH; n++)
+ LIST_FOREACH(pch, &pmcpl_ct_node_hash[n], pch_next) {
+ pmcpl_ct_node_printself(pch->pch_ctnode);
+ pmcpl_ct_node_printchild(pch->pch_ctnode);
+ }
+
+ pmcpl_ct_samples_free(&rsamples);
+}
+
+int
+pmcpl_ct_configure(char *opt)
+{
+
+ if (strncmp(opt, "skiplink=", 9) == 0) {
+ pmcstat_skiplink = atoi(opt+9);
+ } else
+ return (0);
+
+ return (1);
+}
+
+int
+pmcpl_ct_init(void)
+{
+ int i;
+
+ pmcpl_ct_prevfn = NULL;
+ pmcpl_ct_root = pmcpl_ct_node_allocate(NULL, 0);
+
+ for (i = 0; i < PMCSTAT_NHASH; i++)
+ LIST_INIT(&pmcpl_ct_node_hash[i]);
+
+ pmcpl_ct_samples_init(&pmcpl_ct_callid);
+
+ return (0);
+}
+
+void
+pmcpl_ct_shutdown(FILE *mf)
+{
+ int i;
+ struct pmcpl_ct_node_hash *pch, *pchtmp;
+
+ (void) mf;
+
+ if (args.pa_flags & FLAG_DO_CALLGRAPHS)
+ pmcpl_ct_print();
+
+ /*
+ * Free memory.
+ */
+
+ for (i = 0; i < PMCSTAT_NHASH; i++) {
+ LIST_FOREACH_SAFE(pch, &pmcpl_ct_node_hash[i], pch_next,
+ pchtmp) {
+ pmcpl_ct_node_free(pch->pch_ctnode);
+ free(pch);
+ }
+ }
+
+ pmcpl_ct_node_free(pmcpl_ct_root);
+ pmcpl_ct_root = NULL;
+
+ pmcpl_ct_samples_free(&pmcpl_ct_callid);
+}
+
diff --git a/usr.sbin/pmcstat/pmcpl_calltree.h b/usr.sbin/pmcstat/pmcpl_calltree.h
new file mode 100644
index 0000000..f54957f
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_calltree.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2009, Fabien Thomas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PMCSTAT_PL_CALLTREE_H_
+#define _PMCSTAT_PL_CALLTREE_H_
+
+/* Function prototypes */
+int pmcpl_ct_init(void);
+void pmcpl_ct_shutdown(FILE *mf);
+void pmcpl_ct_process(
+ struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
+int pmcpl_ct_topkeypress(int c, WINDOW *w);
+void pmcpl_ct_topdisplay(void);
+int pmcpl_ct_configure(char *opt);
+
+#endif /* _PMCSTAT_PL_CALLTREE_H_ */
diff --git a/usr.sbin/pmcstat/pmcpl_gprof.c b/usr.sbin/pmcstat/pmcpl_gprof.c
new file mode 100644
index 0000000..9327eb9
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_gprof.c
@@ -0,0 +1,533 @@
+/*-
+ * Copyright (c) 2005-2007, Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
+ * Copyright (c) 2009, Fabien Thomas
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE 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.
+ */
+
+/*
+ * Transform a hwpmc(4) log into human readable form, and into
+ * gprof(1) compatible profiles.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/gmon.h>
+#include <sys/imgact_aout.h>
+#include <sys/imgact_elf.h>
+#include <sys/mman.h>
+#include <sys/pmc.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+
+#include <assert.h>
+#include <curses.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libgen.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pmc.h>
+#include <pmclog.h>
+#include <sysexits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pmcstat.h"
+#include "pmcstat_log.h"
+#include "pmcpl_callgraph.h"
+#include "pmcpl_gprof.h"
+
+/*
+ * struct pmcstat_gmonfile tracks a given 'gmon.out' file. These
+ * files are mmap()'ed in as needed.
+ */
+
+struct pmcstat_gmonfile {
+ LIST_ENTRY(pmcstat_gmonfile) pgf_next; /* list of entries */
+ int pgf_overflow; /* whether a count overflowed */
+ pmc_id_t pgf_pmcid; /* id of the associated pmc */
+ size_t pgf_nbuckets; /* #buckets in this gmon.out */
+ unsigned int pgf_nsamples; /* #samples in this gmon.out */
+ pmcstat_interned_string pgf_name; /* pathname of gmon.out file */
+ size_t pgf_ndatabytes; /* number of bytes mapped */
+ void *pgf_gmondata; /* pointer to mmap'ed data */
+ FILE *pgf_file; /* used when writing gmon arcs */
+};
+
+/*
+ * Prototypes
+ */
+
+static void pmcstat_gmon_create_file(struct pmcstat_gmonfile *_pgf,
+ struct pmcstat_image *_image);
+static pmcstat_interned_string pmcstat_gmon_create_name(const char *_sd,
+ struct pmcstat_image *_img, pmc_id_t _pmcid);
+static void pmcstat_gmon_map_file(struct pmcstat_gmonfile *_pgf);
+static void pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *_pgf);
+
+static struct pmcstat_gmonfile *pmcstat_image_find_gmonfile(struct
+ pmcstat_image *_i, pmc_id_t _id);
+
+/*
+ * Create a gmon.out file and size it.
+ */
+
+static void
+pmcstat_gmon_create_file(struct pmcstat_gmonfile *pgf,
+ struct pmcstat_image *image)
+{
+ int fd;
+ size_t count;
+ struct gmonhdr gm;
+ const char *pathname;
+ char buffer[DEFAULT_BUFFER_SIZE];
+
+ pathname = pmcstat_string_unintern(pgf->pgf_name);
+ if ((fd = open(pathname, O_RDWR|O_NOFOLLOW|O_CREAT,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
+ err(EX_OSERR, "ERROR: Cannot open \"%s\"", pathname);
+
+ gm.lpc = image->pi_start;
+ gm.hpc = image->pi_end;
+ gm.ncnt = (pgf->pgf_nbuckets * sizeof(HISTCOUNTER)) +
+ sizeof(struct gmonhdr);
+ gm.version = GMONVERSION;
+ gm.profrate = 0; /* use ticks */
+ gm.histcounter_type = 0; /* compatibility with moncontrol() */
+ gm.spare[0] = gm.spare[1] = 0;
+
+ /* Write out the gmon header */
+ if (write(fd, &gm, sizeof(gm)) < 0)
+ goto error;
+
+ /* Zero fill the samples[] array */
+ (void) memset(buffer, 0, sizeof(buffer));
+
+ count = pgf->pgf_ndatabytes - sizeof(struct gmonhdr);
+ while (count > sizeof(buffer)) {
+ if (write(fd, &buffer, sizeof(buffer)) < 0)
+ goto error;
+ count -= sizeof(buffer);
+ }
+
+ if (write(fd, &buffer, count) < 0)
+ goto error;
+
+ (void) close(fd);
+
+ return;
+
+ error:
+ err(EX_OSERR, "ERROR: Cannot write \"%s\"", pathname);
+}
+
+/*
+ * Determine the full pathname of a gmon.out file for a given
+ * (image,pmcid) combination. Return the interned string.
+ */
+
+pmcstat_interned_string
+pmcstat_gmon_create_name(const char *samplesdir, struct pmcstat_image *image,
+ pmc_id_t pmcid)
+{
+ const char *pmcname;
+ char fullpath[PATH_MAX];
+
+ pmcname = pmcstat_pmcid_to_name(pmcid);
+
+ (void) snprintf(fullpath, sizeof(fullpath),
+ "%s/%s/%s", samplesdir, pmcname,
+ pmcstat_string_unintern(image->pi_samplename));
+
+ return (pmcstat_string_intern(fullpath));
+}
+
+
+/*
+ * Mmap in a gmon.out file for processing.
+ */
+
+static void
+pmcstat_gmon_map_file(struct pmcstat_gmonfile *pgf)
+{
+ int fd;
+ const char *pathname;
+
+ pathname = pmcstat_string_unintern(pgf->pgf_name);
+
+ /* the gmon.out file must already exist */
+ if ((fd = open(pathname, O_RDWR | O_NOFOLLOW, 0)) < 0)
+ err(EX_OSERR, "ERROR: cannot open \"%s\"", pathname);
+
+ pgf->pgf_gmondata = mmap(NULL, pgf->pgf_ndatabytes,
+ PROT_READ|PROT_WRITE, MAP_NOSYNC|MAP_SHARED, fd, 0);
+
+ if (pgf->pgf_gmondata == MAP_FAILED)
+ err(EX_OSERR, "ERROR: cannot map \"%s\"", pathname);
+
+ (void) close(fd);
+}
+
+/*
+ * Unmap a gmon.out file after sync'ing its data to disk.
+ */
+
+static void
+pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *pgf)
+{
+ (void) msync(pgf->pgf_gmondata, pgf->pgf_ndatabytes,
+ MS_SYNC);
+ (void) munmap(pgf->pgf_gmondata, pgf->pgf_ndatabytes);
+ pgf->pgf_gmondata = NULL;
+}
+
+static void
+pmcstat_gmon_append_arc(struct pmcstat_image *image, pmc_id_t pmcid,
+ uintptr_t rawfrom, uintptr_t rawto, uint32_t count)
+{
+ struct rawarc arc; /* from <sys/gmon.h> */
+ const char *pathname;
+ struct pmcstat_gmonfile *pgf;
+
+ if ((pgf = pmcstat_image_find_gmonfile(image, pmcid)) == NULL)
+ return;
+
+ if (pgf->pgf_file == NULL) {
+ pathname = pmcstat_string_unintern(pgf->pgf_name);
+ if ((pgf->pgf_file = fopen(pathname, "a")) == NULL)
+ return;
+ }
+
+ arc.raw_frompc = rawfrom + image->pi_vaddr;
+ arc.raw_selfpc = rawto + image->pi_vaddr;
+ arc.raw_count = count;
+
+ (void) fwrite(&arc, sizeof(arc), 1, pgf->pgf_file);
+
+}
+
+static struct pmcstat_gmonfile *
+pmcstat_image_find_gmonfile(struct pmcstat_image *image, pmc_id_t pmcid)
+{
+ struct pmcstat_gmonfile *pgf;
+ LIST_FOREACH(pgf, &image->pi_gmlist, pgf_next)
+ if (pgf->pgf_pmcid == pmcid)
+ return (pgf);
+ return (NULL);
+}
+
+static void
+pmcstat_cgnode_do_gmon_arcs(struct pmcstat_cgnode *cg, pmc_id_t pmcid)
+{
+ struct pmcstat_cgnode *cgc;
+
+ /*
+ * Look for child nodes that belong to the same image.
+ */
+
+ LIST_FOREACH(cgc, &cg->pcg_children, pcg_sibling) {
+ if (cgc->pcg_image == cg->pcg_image)
+ pmcstat_gmon_append_arc(cg->pcg_image, pmcid,
+ cgc->pcg_func, cg->pcg_func, cgc->pcg_count);
+ if (cgc->pcg_nchildren > 0)
+ pmcstat_cgnode_do_gmon_arcs(cgc, pmcid);
+ }
+}
+
+static void
+pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmc_id_t pmcid)
+{
+ int n;
+ struct pmcstat_cgnode_hash *pch;
+
+ for (n = 0; n < PMCSTAT_NHASH; n++)
+ LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
+ if (pch->pch_pmcid == pmcid &&
+ pch->pch_cgnode->pcg_nchildren > 1)
+ pmcstat_cgnode_do_gmon_arcs(pch->pch_cgnode,
+ pmcid);
+}
+
+
+static void
+pmcstat_callgraph_do_gmon_arcs(void)
+{
+ struct pmcstat_pmcrecord *pmcr;
+
+ LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
+ pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmcr->pr_pmcid);
+}
+
+void
+pmcpl_gmon_initimage(struct pmcstat_image *pi)
+{
+ int count, nlen;
+ char *sn;
+ char name[NAME_MAX];
+
+ /*
+ * Look for a suitable name for the sample files associated
+ * with this image: if `basename(path)`+".gmon" is available,
+ * we use that, otherwise we try iterating through
+ * `basename(path)`+ "~" + NNN + ".gmon" till we get a free
+ * entry.
+ */
+ if ((sn = basename(pmcstat_string_unintern(pi->pi_execpath))) == NULL)
+ err(EX_OSERR, "ERROR: Cannot process \"%s\"",
+ pmcstat_string_unintern(pi->pi_execpath));
+
+ nlen = strlen(sn);
+ nlen = min(nlen, (int) (sizeof(name) - sizeof(".gmon")));
+
+ snprintf(name, sizeof(name), "%.*s.gmon", nlen, sn);
+
+ /* try use the unabridged name first */
+ if (pmcstat_string_lookup(name) == NULL)
+ pi->pi_samplename = pmcstat_string_intern(name);
+ else {
+ /*
+ * Otherwise use a prefix from the original name and
+ * upto 3 digits.
+ */
+ nlen = strlen(sn);
+ nlen = min(nlen, (int) (sizeof(name)-sizeof("~NNN.gmon")));
+ count = 0;
+ do {
+ if (++count > 999)
+ errx(EX_CANTCREAT, "ERROR: cannot create a "
+ "gmon file for \"%s\"", name);
+ snprintf(name, sizeof(name), "%.*s~%3.3d.gmon",
+ nlen, sn, count);
+ if (pmcstat_string_lookup(name) == NULL) {
+ pi->pi_samplename =
+ pmcstat_string_intern(name);
+ count = 0;
+ }
+ } while (count > 0);
+ }
+
+ LIST_INIT(&pi->pi_gmlist);
+}
+
+void
+pmcpl_gmon_shutdownimage(struct pmcstat_image *pi)
+{
+ struct pmcstat_gmonfile *pgf, *pgftmp;
+
+ LIST_FOREACH_SAFE(pgf, &pi->pi_gmlist, pgf_next, pgftmp) {
+ if (pgf->pgf_file)
+ (void) fclose(pgf->pgf_file);
+ LIST_REMOVE(pgf, pgf_next);
+ free(pgf);
+ }
+}
+
+void
+pmcpl_gmon_newpmc(pmcstat_interned_string ps, struct pmcstat_pmcrecord *pr)
+{
+ struct stat st;
+ char fullpath[PATH_MAX];
+
+ (void) pr;
+
+ /*
+ * Create the appropriate directory to hold gmon.out files.
+ */
+
+ (void) snprintf(fullpath, sizeof(fullpath), "%s/%s", args.pa_samplesdir,
+ pmcstat_string_unintern(ps));
+
+ /* If the path name exists, it should be a directory */
+ if (stat(fullpath, &st) == 0 && S_ISDIR(st.st_mode))
+ return;
+
+ if (mkdir(fullpath, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) < 0)
+ err(EX_OSERR, "ERROR: Cannot create directory \"%s\"",
+ fullpath);
+}
+
+/*
+ * Increment the bucket in the gmon.out file corresponding to 'pmcid'
+ * and 'pc'.
+ */
+
+void
+pmcpl_gmon_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
+{
+ struct pmcstat_pcmap *map;
+ struct pmcstat_image *image;
+ struct pmcstat_gmonfile *pgf;
+ uintfptr_t bucket;
+ HISTCOUNTER *hc;
+ pmc_id_t pmcid;
+
+ (void) nsamples; (void) usermode; (void) cpu;
+
+ map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[0]);
+ if (map == NULL) {
+ /* Unknown offset. */
+ pmcstat_stats.ps_samples_unknown_offset++;
+ return;
+ }
+
+ assert(cc[0] >= map->ppm_lowpc && cc[0] < map->ppm_highpc);
+
+ image = map->ppm_image;
+ pmcid = pmcr->pr_pmcid;
+
+ /*
+ * If this is the first time we are seeing a sample for
+ * this executable image, try determine its parameters.
+ */
+ if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
+ pmcstat_image_determine_type(image);
+
+ assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN);
+
+ /* Ignore samples in images that we know nothing about. */
+ if (image->pi_type == PMCSTAT_IMAGE_INDETERMINABLE) {
+ pmcstat_stats.ps_samples_indeterminable++;
+ return;
+ }
+
+ /*
+ * Find the gmon file corresponding to 'pmcid', creating it if
+ * needed.
+ */
+ pgf = pmcstat_image_find_gmonfile(image, pmcid);
+ if (pgf == NULL) {
+ if ((pgf = calloc(1, sizeof(*pgf))) == NULL)
+ err(EX_OSERR, "ERROR:");
+
+ pgf->pgf_gmondata = NULL; /* mark as unmapped */
+ pgf->pgf_name = pmcstat_gmon_create_name(args.pa_samplesdir,
+ image, pmcid);
+ pgf->pgf_pmcid = pmcid;
+ assert(image->pi_end > image->pi_start);
+ pgf->pgf_nbuckets = (image->pi_end - image->pi_start) /
+ FUNCTION_ALIGNMENT; /* see <machine/profile.h> */
+ pgf->pgf_ndatabytes = sizeof(struct gmonhdr) +
+ pgf->pgf_nbuckets * sizeof(HISTCOUNTER);
+ pgf->pgf_nsamples = 0;
+ pgf->pgf_file = NULL;
+
+ pmcstat_gmon_create_file(pgf, image);
+
+ LIST_INSERT_HEAD(&image->pi_gmlist, pgf, pgf_next);
+ }
+
+ /*
+ * Map the gmon file in if needed. It may have been mapped
+ * out under memory pressure.
+ */
+ if (pgf->pgf_gmondata == NULL)
+ pmcstat_gmon_map_file(pgf);
+
+ assert(pgf->pgf_gmondata != NULL);
+
+ /*
+ *
+ */
+
+ bucket = (cc[0] - map->ppm_lowpc) / FUNCTION_ALIGNMENT;
+
+ assert(bucket < pgf->pgf_nbuckets);
+
+ hc = (HISTCOUNTER *) ((uintptr_t) pgf->pgf_gmondata +
+ sizeof(struct gmonhdr));
+
+ /* saturating add */
+ if (hc[bucket] < 0xFFFFU) /* XXX tie this to sizeof(HISTCOUNTER) */
+ hc[bucket]++;
+ else /* mark that an overflow occurred */
+ pgf->pgf_overflow = 1;
+
+ pgf->pgf_nsamples++;
+}
+
+/*
+ * Shutdown module.
+ */
+
+void
+pmcpl_gmon_shutdown(FILE *mf)
+{
+ int i;
+ struct pmcstat_gmonfile *pgf;
+ struct pmcstat_image *pi;
+
+ /*
+ * Sync back all gprof flat profile data.
+ */
+ for (i = 0; i < PMCSTAT_NHASH; i++) {
+ LIST_FOREACH(pi, &pmcstat_image_hash[i], pi_next) {
+ if (mf)
+ (void) fprintf(mf, " \"%s\" => \"%s\"",
+ pmcstat_string_unintern(pi->pi_execpath),
+ pmcstat_string_unintern(
+ pi->pi_samplename));
+
+ /* flush gmon.out data to disk */
+ LIST_FOREACH(pgf, &pi->pi_gmlist, pgf_next) {
+ pmcstat_gmon_unmap_file(pgf);
+ if (mf)
+ (void) fprintf(mf, " %s/%d",
+ pmcstat_pmcid_to_name(
+ pgf->pgf_pmcid),
+ pgf->pgf_nsamples);
+ if (pgf->pgf_overflow && args.pa_verbosity >= 1)
+ warnx("WARNING: profile \"%s\" "
+ "overflowed.",
+ pmcstat_string_unintern(
+ pgf->pgf_name));
+ }
+
+ if (mf)
+ (void) fprintf(mf, "\n");
+ }
+ }
+
+ /*
+ * Compute arcs and add these to the gprof files.
+ */
+ if (args.pa_flags & FLAG_DO_GPROF && args.pa_graphdepth > 1)
+ pmcstat_callgraph_do_gmon_arcs();
+}
diff --git a/usr.sbin/pmcstat/pmcpl_gprof.h b/usr.sbin/pmcstat/pmcpl_gprof.h
new file mode 100644
index 0000000..069082f
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_gprof.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2005-2007, Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
+ * Copyright (c) 2009, Fabien Thomas
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PMCSTAT_PL_GPROF_H_
+#define _PMCSTAT_PL_GPROF_H_
+
+/* Function prototypes */
+void pmcpl_gmon_shutdown(FILE *mf);
+void pmcpl_gmon_process(
+ struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
+void pmcpl_gmon_initimage(struct pmcstat_image *pi);
+void pmcpl_gmon_shutdownimage(struct pmcstat_image *pi);
+void pmcpl_gmon_newpmc(pmcstat_interned_string ps,
+ struct pmcstat_pmcrecord *pr);
+
+#endif /* _PMCSTAT_PL_GPROF_H_ */
diff --git a/usr.sbin/pmcstat/pmcstat.8 b/usr.sbin/pmcstat/pmcstat.8
index a4e6f1f..309eb3e 100644
--- a/usr.sbin/pmcstat/pmcstat.8
+++ b/usr.sbin/pmcstat/pmcstat.8
@@ -36,6 +36,7 @@
.Op Fl C
.Op Fl D Ar pathname
.Op Fl E
+.Op Fl F Ar pathname
.Op Fl G Ar pathname
.Op Fl M Ar mapfilename
.Op Fl N
@@ -43,9 +44,11 @@
.Op Fl P Ar event-spec
.Op Fl R Ar logfilename
.Op Fl S Ar event-spec
+.Op Fl T
.Op Fl W
.Op Fl c Ar cpu-spec
.Op Fl d
+.Op Fl f Ar pluginopt
.Op Fl g
.Op Fl k Ar kerneldir
.Op Fl m Ar pathname
@@ -129,6 +132,16 @@ complex pipeline of processes when used in conjunction with the
.Fl d
option.
The default is to not to enable per-process tracking.
+.It Fl F Ar pathname
+Print calltree (Kcachegrind) information to file
+.Ar pathname .
+If argument
+.Ar pathname
+is a
+.Dq Li -
+this information is sent to the output file specified by the
+.Fl o
+option.
.It Fl G Ar pathname
Print callchain information to file
.Ar pathname .
@@ -195,6 +208,12 @@ Perform offline analysis using sampling data in file
Allocate a system mode sampling PMC measuring hardware events
specified in
.Ar event-spec .
+.It Fl T
+Use a top like mode for sampling PMCs. The following hotkeys
+can be used: 'c+a' switch to accumulative mode, 'c+d' switch
+to delta mode, 'm' merge PMCs, 'n' change view, 'p' show next
+PMC, ' ' pause, 'q' quit. calltree only: 'f' cost under threshold
+is seen as a dot.
.It Fl W
Toggle logging the incremental counts seen by the threads of a
tracked process each time they are scheduled on a CPU.
@@ -218,6 +237,12 @@ Toggle between process mode PMCs measuring events for the target
process' current and future children or only measuring events for
the target process.
The default is to measure events for the target process alone.
+.It Fl f Ar pluginopt
+Pass option string to the active plugin.
+.br
+threshold=<float> do not display cost under specified value (Top).
+.br
+skiplink=0|1 replace node with cost under threshold by a dot (Top).
.It Fl g
Produce profiles in a format compatible with
.Xr gprof 1 .
@@ -286,7 +311,8 @@ regular expression for selecting processes based on their command names.
.It Fl v
Increase verbosity.
.It Fl w Ar secs
-Print the values of all counting mode PMCs every
+Print the values of all counting mode PMCs or sampling mode PMCs
+for top mode every
.Ar secs
seconds.
The argument
diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c
index 6496ddb..a73d293 100644
--- a/usr.sbin/pmcstat/pmcstat.c
+++ b/usr.sbin/pmcstat/pmcstat.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/wait.h>
#include <assert.h>
+#include <curses.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -106,13 +107,15 @@ __FBSDID("$FreeBSD$");
int pmcstat_interrupt = 0;
int pmcstat_displayheight = DEFAULT_DISPLAY_HEIGHT;
+int pmcstat_displaywidth = DEFAULT_DISPLAY_WIDTH;
int pmcstat_sockpair[NSOCKPAIRFD];
int pmcstat_kq;
kvm_t *pmcstat_kvm;
struct kinfo_proc *pmcstat_plist;
+struct pmcstat_args args;
void
-pmcstat_attach_pmcs(struct pmcstat_args *a)
+pmcstat_attach_pmcs(void)
{
struct pmcstat_ev *ev;
struct pmcstat_target *pt;
@@ -120,10 +123,10 @@ pmcstat_attach_pmcs(struct pmcstat_args *a)
/* Attach all process PMCs to target processes. */
count = 0;
- STAILQ_FOREACH(ev, &a->pa_events, ev_next) {
+ STAILQ_FOREACH(ev, &args.pa_events, ev_next) {
if (PMC_IS_SYSTEM_MODE(ev->ev_mode))
continue;
- SLIST_FOREACH(pt, &a->pa_targets, pt_next)
+ SLIST_FOREACH(pt, &args.pa_targets, pt_next)
if (pmc_attach(ev->ev_pmcid, pt->pt_pid) == 0)
count++;
else if (errno != ESRCH)
@@ -138,12 +141,12 @@ pmcstat_attach_pmcs(struct pmcstat_args *a)
void
-pmcstat_cleanup(struct pmcstat_args *a)
+pmcstat_cleanup(void)
{
struct pmcstat_ev *ev, *tmp;
/* release allocated PMCs. */
- STAILQ_FOREACH_SAFE(ev, &a->pa_events, ev_next, tmp)
+ STAILQ_FOREACH_SAFE(ev, &args.pa_events, ev_next, tmp)
if (ev->ev_pmcid != PMC_ID_INVALID) {
if (pmc_stop(ev->ev_pmcid) < 0)
err(EX_OSERR, "ERROR: cannot stop pmc 0x%x "
@@ -153,25 +156,25 @@ pmcstat_cleanup(struct pmcstat_args *a)
"0x%x \"%s\"", ev->ev_pmcid, ev->ev_name);
free(ev->ev_name);
free(ev->ev_spec);
- STAILQ_REMOVE(&a->pa_events, ev, pmcstat_ev, ev_next);
+ STAILQ_REMOVE(&args.pa_events, ev, pmcstat_ev, ev_next);
free(ev);
}
/* de-configure the log file if present. */
- if (a->pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE))
+ if (args.pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE))
(void) pmc_configure_logfile(-1);
- if (a->pa_logparser) {
- pmclog_close(a->pa_logparser);
- a->pa_logparser = NULL;
+ if (args.pa_logparser) {
+ pmclog_close(args.pa_logparser);
+ args.pa_logparser = NULL;
}
- if (a->pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE))
- pmcstat_shutdown_logging(a);
+ if (args.pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE))
+ pmcstat_shutdown_logging();
}
void
-pmcstat_clone_event_descriptor(struct pmcstat_args *a, struct pmcstat_ev *ev,
+pmcstat_clone_event_descriptor(struct pmcstat_ev *ev,
uint32_t cpumask)
{
int cpu;
@@ -194,14 +197,14 @@ pmcstat_clone_event_descriptor(struct pmcstat_args *a, struct pmcstat_ev *ev,
ev_clone->ev_saved = ev->ev_saved;
ev_clone->ev_spec = strdup(ev->ev_spec);
- STAILQ_INSERT_TAIL(&a->pa_events, ev_clone, ev_next);
+ STAILQ_INSERT_TAIL(&args.pa_events, ev_clone, ev_next);
cpumask &= ~(1 << cpu);
}
}
void
-pmcstat_create_process(struct pmcstat_args *a)
+pmcstat_create_process(void)
{
char token;
pid_t pid;
@@ -229,10 +232,10 @@ pmcstat_create_process(struct pmcstat_args *a)
(void) close(pmcstat_sockpair[CHILDSOCKET]);
/* exec() the program requested */
- execvp(*a->pa_argv, a->pa_argv);
+ execvp(*args.pa_argv, args.pa_argv);
/* and if that fails, notify the parent */
kill(getppid(), SIGCHLD);
- err(EX_OSERR, "ERROR: execvp \"%s\" failed", *a->pa_argv);
+ err(EX_OSERR, "ERROR: execvp \"%s\" failed", *args.pa_argv);
/*NOTREACHED*/
default: /* parent */
@@ -250,7 +253,7 @@ pmcstat_create_process(struct pmcstat_args *a)
errx(EX_SOFTWARE, "ERROR: Out of memory.");
pt->pt_pid = pid;
- SLIST_INSERT_HEAD(&a->pa_targets, pt, pt_next);
+ SLIST_INSERT_HEAD(&args.pa_targets, pt, pt_next);
/* Wait for the child to signal that its ready to go. */
if (read(pmcstat_sockpair[PARENTSOCKET], &token, 1) < 0)
@@ -260,7 +263,7 @@ pmcstat_create_process(struct pmcstat_args *a)
}
void
-pmcstat_find_targets(struct pmcstat_args *a, const char *spec)
+pmcstat_find_targets(const char *spec)
{
int n, nproc, pid, rv;
struct pmcstat_target *pt;
@@ -275,7 +278,7 @@ pmcstat_find_targets(struct pmcstat_args *a, const char *spec)
if ((pt = malloc(sizeof(*pt))) == NULL)
goto outofmemory;
pt->pt_pid = pid;
- SLIST_INSERT_HEAD(&a->pa_targets, pt, pt_next);
+ SLIST_INSERT_HEAD(&args.pa_targets, pt, pt_next);
return;
}
@@ -302,7 +305,7 @@ pmcstat_find_targets(struct pmcstat_args *a, const char *spec)
if ((pt = malloc(sizeof(*pt))) == NULL)
goto outofmemory;
pt->pt_pid = kp->ki_pid;
- SLIST_INSERT_HEAD(&a->pa_targets, pt, pt_next);
+ SLIST_INSERT_HEAD(&args.pa_targets, pt, pt_next);
} else if (rv != REG_NOMATCH) {
regerror(rv, &reg, errbuf, sizeof(errbuf));
errx(EX_SOFTWARE, "ERROR: Regex evalation failed: %s",
@@ -343,17 +346,17 @@ pmcstat_get_cpumask(const char *cpuspec)
}
void
-pmcstat_kill_process(struct pmcstat_args *a)
+pmcstat_kill_process(void)
{
struct pmcstat_target *pt;
- assert(a->pa_flags & FLAG_HAS_COMMANDLINE);
+ assert(args.pa_flags & FLAG_HAS_COMMANDLINE);
/*
* If a command line was specified, it would be the very first
* in the list, before any other processes specified by -t.
*/
- pt = SLIST_FIRST(&a->pa_targets);
+ pt = SLIST_FIRST(&args.pa_targets);
assert(pt != NULL);
if (kill(pt->pt_pid, SIGINT) != 0)
@@ -361,7 +364,7 @@ pmcstat_kill_process(struct pmcstat_args *a)
}
void
-pmcstat_start_pmcs(struct pmcstat_args *a)
+pmcstat_start_pmcs(void)
{
struct pmcstat_ev *ev;
@@ -372,7 +375,7 @@ pmcstat_start_pmcs(struct pmcstat_args *a)
if (pmc_start(ev->ev_pmcid) < 0) {
warn("ERROR: Cannot start pmc 0x%x \"%s\"",
ev->ev_pmcid, ev->ev_name);
- pmcstat_cleanup(a);
+ pmcstat_cleanup();
exit(EX_OSERR);
}
}
@@ -380,37 +383,37 @@ pmcstat_start_pmcs(struct pmcstat_args *a)
}
void
-pmcstat_print_headers(struct pmcstat_args *a)
+pmcstat_print_headers(void)
{
struct pmcstat_ev *ev;
int c, w;
- (void) fprintf(a->pa_printfile, PRINT_HEADER_PREFIX);
+ (void) fprintf(args.pa_printfile, PRINT_HEADER_PREFIX);
- STAILQ_FOREACH(ev, &a->pa_events, ev_next) {
+ STAILQ_FOREACH(ev, &args.pa_events, ev_next) {
if (PMC_IS_SAMPLING_MODE(ev->ev_mode))
continue;
c = PMC_IS_SYSTEM_MODE(ev->ev_mode) ? 's' : 'p';
if (ev->ev_fieldskip != 0)
- (void) fprintf(a->pa_printfile, "%*s",
+ (void) fprintf(args.pa_printfile, "%*s",
ev->ev_fieldskip, "");
w = ev->ev_fieldwidth - ev->ev_fieldskip - 2;
if (c == 's')
- (void) fprintf(a->pa_printfile, "s/%02d/%-*s ",
+ (void) fprintf(args.pa_printfile, "s/%02d/%-*s ",
ev->ev_cpu, w-3, ev->ev_name);
else
- (void) fprintf(a->pa_printfile, "p/%*s ", w,
+ (void) fprintf(args.pa_printfile, "p/%*s ", w,
ev->ev_name);
}
- (void) fflush(a->pa_printfile);
+ (void) fflush(args.pa_printfile);
}
void
-pmcstat_print_counters(struct pmcstat_args *a)
+pmcstat_print_counters(void)
{
int extra_width;
struct pmcstat_ev *ev;
@@ -418,7 +421,7 @@ pmcstat_print_counters(struct pmcstat_args *a)
extra_width = sizeof(PRINT_HEADER_PREFIX) - 1;
- STAILQ_FOREACH(ev, &a->pa_events, ev_next) {
+ STAILQ_FOREACH(ev, &args.pa_events, ev_next) {
/* skip sampling mode counters */
if (PMC_IS_SAMPLING_MODE(ev->ev_mode))
@@ -428,7 +431,7 @@ pmcstat_print_counters(struct pmcstat_args *a)
err(EX_OSERR, "ERROR: Cannot read pmc "
"\"%s\"", ev->ev_name);
- (void) fprintf(a->pa_printfile, "%*ju ",
+ (void) fprintf(args.pa_printfile, "%*ju ",
ev->ev_fieldwidth + extra_width,
(uintmax_t) ev->ev_cumulative ? value :
(value - ev->ev_saved));
@@ -438,7 +441,7 @@ pmcstat_print_counters(struct pmcstat_args *a)
extra_width = 0;
}
- (void) fflush(a->pa_printfile);
+ (void) fflush(args.pa_printfile);
}
/*
@@ -446,20 +449,20 @@ pmcstat_print_counters(struct pmcstat_args *a)
*/
void
-pmcstat_print_pmcs(struct pmcstat_args *a)
+pmcstat_print_pmcs(void)
{
static int linecount = 0;
/* check if we need to print a header line */
if (++linecount > pmcstat_displayheight) {
- (void) fprintf(a->pa_printfile, "\n");
+ (void) fprintf(args.pa_printfile, "\n");
linecount = 1;
}
if (linecount == 1)
- pmcstat_print_headers(a);
- (void) fprintf(a->pa_printfile, "\n");
+ pmcstat_print_headers();
+ (void) fprintf(args.pa_printfile, "\n");
- pmcstat_print_counters(a);
+ pmcstat_print_counters();
return;
}
@@ -493,6 +496,8 @@ pmcstat_show_usage(void)
"\t -C\t\t (toggle) show cumulative counts\n"
"\t -D path\t create profiles in directory \"path\"\n"
"\t -E\t\t (toggle) show counts at process exit\n"
+ "\t -F file\t write a system-wide callgraph (Kcachegrind format)"
+ " to \"file\"\n"
"\t -G file\t write a system-wide callgraph to \"file\"\n"
"\t -M file\t print executable/gmon file map to \"file\"\n"
"\t -N\t\t (toggle) capture callchains\n"
@@ -500,9 +505,11 @@ pmcstat_show_usage(void)
"\t -P spec\t allocate a process-private sampling PMC\n"
"\t -R file\t read events from \"file\"\n"
"\t -S spec\t allocate a system-wide sampling PMC\n"
+ "\t -T\t\t start in top mode\n"
"\t -W\t\t (toggle) show counts per context switch\n"
"\t -c cpu-list\t set cpus for subsequent system-wide PMCs\n"
"\t -d\t\t (toggle) track descendants\n"
+ "\t -f spec\t pass \"spec\" to as plugin option\n"
"\t -g\t\t produce gprof(1) compatible profiles\n"
"\t -k dir\t\t set the path to the kernel\n"
"\t -n rate\t set sampling rate\n"
@@ -520,6 +527,24 @@ pmcstat_show_usage(void)
}
/*
+ * At exit handler for top mode
+ */
+
+void
+pmcstat_topexit(void)
+{
+ if (!args.pa_toptty)
+ return;
+
+ /*
+ * Shutdown ncurses.
+ */
+ clrtoeol();
+ refresh();
+ endwin();
+}
+
+/*
* Main
*/
@@ -535,6 +560,7 @@ main(int argc, char **argv)
int graphdepth;
int pipefd[2];
int use_cumulative_counts;
+ short cf, cb;
uint32_t cpumask;
char *end, *tmp;
const char *errmsg, *graphfilename;
@@ -570,6 +596,13 @@ main(int argc, char **argv)
args.pa_mapfilename = NULL;
args.pa_inputpath = NULL;
args.pa_outputpath = NULL;
+ args.pa_pplugin = PMCSTAT_PL_NONE;
+ args.pa_plugin = PMCSTAT_PL_NONE;
+ args.pa_ctdumpinstr = 1;
+ args.pa_topmode = PMCSTAT_TOP_DELTA;
+ args.pa_toptty = 0;
+ args.pa_topcolor = 0;
+ args.pa_mergepmc = 0;
STAILQ_INIT(&args.pa_events);
SLIST_INIT(&args.pa_targets);
bzero(&ds_start, sizeof(ds_start));
@@ -594,7 +627,7 @@ main(int argc, char **argv)
}
while ((option = getopt(argc, argv,
- "CD:EG:M:NO:P:R:S:Wc:dgk:m:n:o:p:qr:s:t:vw:z:")) != -1)
+ "CD:EF:G:M:NO:P:R:S:TWc:df:gk:m:n:o:p:qr:s:t:vw:z:")) != -1)
switch (option) {
case 'C': /* cumulative values */
use_cumulative_counts = !use_cumulative_counts;
@@ -628,13 +661,28 @@ main(int argc, char **argv)
args.pa_required |= FLAG_HAS_PROCESS_PMCS;
break;
+ case 'F': /* produce a system-wide calltree */
+ args.pa_flags |= FLAG_DO_CALLGRAPHS;
+ args.pa_plugin = PMCSTAT_PL_CALLTREE;
+ graphfilename = optarg;
+ break;
+
+ case 'f': /* plugins options */
+ if (args.pa_plugin == PMCSTAT_PL_NONE)
+ err(EX_USAGE, "ERROR: Need -g/-G/-m/-T.");
+ pmcstat_pluginconfigure_log(optarg);
+ break;
+
case 'G': /* produce a system-wide callgraph */
args.pa_flags |= FLAG_DO_CALLGRAPHS;
+ args.pa_plugin = PMCSTAT_PL_CALLGRAPH;
graphfilename = optarg;
break;
case 'g': /* produce gprof compatible profiles */
args.pa_flags |= FLAG_DO_GPROF;
+ args.pa_pplugin = PMCSTAT_PL_CALLGRAPH;
+ args.pa_plugin = PMCSTAT_PL_GPROF;
break;
case 'k': /* pathname to the kernel */
@@ -645,8 +693,9 @@ main(int argc, char **argv)
break;
case 'm':
- args.pa_flags |= FLAG_WANTS_MAPPINGS;
- graphfilename = optarg;
+ args.pa_flags |= FLAG_DO_ANNOTATE;
+ args.pa_plugin = PMCSTAT_PL_ANNOTATE;
+ graphfilename = optarg;
break;
case 'E': /* log process exit */
@@ -732,7 +781,7 @@ main(int argc, char **argv)
STAILQ_INSERT_TAIL(&args.pa_events, ev, ev_next);
if (option == 's' || option == 'S')
- pmcstat_clone_event_descriptor(&args, ev,
+ pmcstat_clone_event_descriptor(ev,
cpumask & ~(1 << ev->ev_cpu));
break;
@@ -782,12 +831,21 @@ main(int argc, char **argv)
break;
case 't': /* target pid or process name */
- pmcstat_find_targets(&args, optarg);
+ pmcstat_find_targets(optarg);
args.pa_flags |= FLAG_HAS_TARGET;
args.pa_required |= FLAG_HAS_PROCESS_PMCS;
break;
+ case 'T': /* top mode */
+ args.pa_flags |= FLAG_DO_TOP;
+ args.pa_plugin = PMCSTAT_PL_CALLGRAPH;
+ args.pa_ctdumpinstr = 0;
+ args.pa_mergepmc = 1;
+ if (args.pa_printfile == stderr)
+ args.pa_printfile = stdout;
+ break;
+
case 'v': /* verbose */
args.pa_verbosity++;
break;
@@ -798,7 +856,6 @@ main(int argc, char **argv)
errx(EX_USAGE, "ERROR: Illegal wait interval "
"value \"%s\".", optarg);
args.pa_flags |= FLAG_HAS_WAIT_INTERVAL;
- args.pa_required |= FLAG_HAS_COUNTING_PMCS;
args.pa_interval = interval;
break;
@@ -833,7 +890,7 @@ main(int argc, char **argv)
args.pa_flags |= FLAG_HAS_COMMANDLINE;
if (args.pa_flags & (FLAG_DO_GPROF | FLAG_DO_CALLGRAPHS |
- FLAG_WANTS_MAPPINGS))
+ FLAG_DO_ANNOTATE | FLAG_DO_TOP))
args.pa_flags |= FLAG_DO_ANALYSIS;
/*
@@ -846,11 +903,11 @@ main(int argc, char **argv)
"exclusive.");
/* -m option is allowed with -R only. */
- if (args.pa_flags & FLAG_WANTS_MAPPINGS && args.pa_inputpath == NULL)
+ if (args.pa_flags & FLAG_DO_ANNOTATE && args.pa_inputpath == NULL)
errx(EX_USAGE, "ERROR: option -m requires an input file");
/* -m option is not allowed combined with -g or -G. */
- if (args.pa_flags & FLAG_WANTS_MAPPINGS &&
+ if (args.pa_flags & FLAG_DO_ANNOTATE &&
args.pa_flags & (FLAG_DO_GPROF | FLAG_DO_CALLGRAPHS))
errx(EX_USAGE, "ERROR: option -m and -g | -G are mutually "
"exclusive");
@@ -904,7 +961,7 @@ main(int argc, char **argv)
/* check for counting mode options without a counting PMC */
if ((args.pa_required & FLAG_HAS_COUNTING_PMCS) &&
(args.pa_flags & FLAG_HAS_COUNTING_PMCS) == 0)
- errx(EX_USAGE, "ERROR: options -C, -W, -o and -w require at "
+ errx(EX_USAGE, "ERROR: options -C, -W and -o require at "
"least one counting mode PMC to be specified.");
/* check for sampling mode options without a sampling PMC spec */
@@ -913,10 +970,10 @@ main(int argc, char **argv)
errx(EX_USAGE, "ERROR: options -N, -n and -O require at "
"least one sampling mode PMC to be specified.");
- /* check if -g/-G are being used correctly */
+ /* check if -g/-G/-m/-T are being used correctly */
if ((args.pa_flags & FLAG_DO_ANALYSIS) &&
!(args.pa_flags & (FLAG_HAS_SAMPLING_PMCS|FLAG_READ_LOGFILE)))
- errx(EX_USAGE, "ERROR: options -g/-G require sampling PMCs "
+ errx(EX_USAGE, "ERROR: options -g/-G/-m/-T require sampling PMCs "
"or -R to be specified.");
/* check if -O was spuriously specified */
@@ -926,11 +983,11 @@ main(int argc, char **argv)
"ERROR: option -O is used only with options "
"-E, -P, -S and -W.");
- /* -k kernel path require -g/-G or -R */
+ /* -k kernel path require -g/-G/-m/-T or -R */
if ((args.pa_flags & FLAG_HAS_KERNELPATH) &&
(args.pa_flags & FLAG_DO_ANALYSIS) == 0 &&
(args.pa_flags & FLAG_READ_LOGFILE) == 0)
- errx(EX_USAGE, "ERROR: option -k is only used with -g/-R.");
+ errx(EX_USAGE, "ERROR: option -k is only used with -g/-R/-m/-T.");
/* -D only applies to gprof output mode (-g) */
if ((args.pa_flags & FLAG_HAS_SAMPLESDIR) &&
@@ -943,6 +1000,11 @@ main(int argc, char **argv)
(args.pa_flags & FLAG_READ_LOGFILE) == 0)
errx(EX_USAGE, "ERROR: option -M is only used with -g/-R.");
+ /* -T is incompatible with -R (replay logfile is a TODO) */
+ if ((args.pa_flags & FLAG_DO_TOP) &&
+ (args.pa_flags & FLAG_READ_LOGFILE))
+ errx(EX_USAGE, "ERROR: option -T is incompatible with -R.");
+
/*
* Disallow textual output of sampling PMCs if counting PMCs
* have also been asked for, mostly because the combined output
@@ -996,7 +1058,7 @@ main(int argc, char **argv)
"for writing", graphfilename);
}
}
- if (args.pa_flags & FLAG_WANTS_MAPPINGS) {
+ if (args.pa_flags & FLAG_DO_ANNOTATE) {
args.pa_graphfile = fopen(graphfilename, "w");
if (args.pa_graphfile == NULL)
err(EX_OSERR, "ERROR: cannot open \"%s\" for writing",
@@ -1012,13 +1074,13 @@ main(int argc, char **argv)
if ((args.pa_flags & FLAG_DO_ANALYSIS) == 0)
args.pa_flags |= FLAG_DO_PRINT;
- pmcstat_initialize_logging(&args);
+ pmcstat_initialize_logging();
args.pa_logfd = pmcstat_open_log(args.pa_inputpath,
PMCSTAT_OPEN_FOR_READ);
if ((args.pa_logparser = pmclog_open(args.pa_logfd)) == NULL)
err(EX_OSERR, "ERROR: Cannot create parser");
- pmcstat_process_log(&args);
- pmcstat_shutdown_logging(&args);
+ pmcstat_process_log();
+ pmcstat_shutdown_logging();
exit(EX_OK);
}
@@ -1062,7 +1124,9 @@ main(int argc, char **argv)
args.pa_logfd = pipefd[WRITEPIPEFD];
- args.pa_flags |= (FLAG_HAS_PIPE | FLAG_DO_PRINT);
+ args.pa_flags |= FLAG_HAS_PIPE;
+ if ((args.pa_flags & FLAG_DO_TOP) == 0)
+ args.pa_flags |= FLAG_DO_PRINT;
args.pa_logparser = pmclog_open(pipefd[READPIPEFD]);
}
@@ -1126,12 +1190,24 @@ main(int argc, char **argv)
err(EX_OSERR, "ERROR: Cannot determine window size");
pmcstat_displayheight = ws.ws_row - 1;
+ pmcstat_displaywidth = ws.ws_col - 1;
EV_SET(&kev, SIGWINCH, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
if (kevent(pmcstat_kq, &kev, 1, NULL, 0, NULL) < 0)
err(EX_OSERR, "ERROR: Cannot register kevent for "
"SIGWINCH");
+
+ args.pa_toptty = 1;
+ }
+
+ /*
+ * Listen to key input in top mode.
+ */
+ if (args.pa_flags & FLAG_DO_TOP) {
+ EV_SET(&kev, fileno(stdin), EVFILT_READ, EV_ADD, 0, 0, NULL);
+ if (kevent(pmcstat_kq, &kev, 1, NULL, 0, NULL) < 0)
+ err(EX_OSERR, "ERROR: Cannot register kevent");
}
EV_SET(&kev, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
@@ -1152,9 +1228,13 @@ main(int argc, char **argv)
if (kevent(pmcstat_kq, &kev, 1, NULL, 0, NULL) < 0)
err(EX_OSERR, "ERROR: Cannot register kevent for SIGCHLD");
- /* setup a timer if we have counting mode PMCs needing to be printed */
- if ((args.pa_flags & FLAG_HAS_COUNTING_PMCS) &&
- (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) {
+ /*
+ * Setup a timer if we have counting mode PMCs needing to be printed or
+ * top mode plugin is active.
+ */
+ if (((args.pa_flags & FLAG_HAS_COUNTING_PMCS) &&
+ (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) ||
+ (args.pa_flags & FLAG_DO_TOP)) {
EV_SET(&kev, 0, EVFILT_TIMER, EV_ADD, 0,
args.pa_interval * 1000, NULL);
@@ -1165,7 +1245,7 @@ main(int argc, char **argv)
/* attach PMCs to the target process, starting it if specified */
if (args.pa_flags & FLAG_HAS_COMMANDLINE)
- pmcstat_create_process(&args);
+ pmcstat_create_process();
if (check_driver_stats && pmc_get_driver_stats(&ds_start) < 0)
err(EX_OSERR, "ERROR: Cannot retrieve driver statistics");
@@ -1176,7 +1256,7 @@ main(int argc, char **argv)
errx(EX_DATAERR, "ERROR: No matching target "
"processes.");
if (args.pa_flags & FLAG_HAS_PROCESS_PMCS)
- pmcstat_attach_pmcs(&args);
+ pmcstat_attach_pmcs();
if (pmcstat_kvm) {
kvm_close(pmcstat_kvm);
@@ -1185,16 +1265,16 @@ main(int argc, char **argv)
}
/* start the pmcs */
- pmcstat_start_pmcs(&args);
+ pmcstat_start_pmcs();
/* start the (commandline) process if needed */
if (args.pa_flags & FLAG_HAS_COMMANDLINE)
pmcstat_start_process();
/* initialize logging if printing the configured log */
- if ((args.pa_flags & FLAG_DO_PRINT) &&
+ if ((args.pa_flags & (FLAG_DO_PRINT | FLAG_DO_TOP)) &&
(args.pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE)))
- pmcstat_initialize_logging(&args);
+ pmcstat_initialize_logging();
/* Handle SIGINT using the kqueue loop */
sa.sa_handler = SIG_IGN;
@@ -1205,6 +1285,37 @@ main(int argc, char **argv)
err(EX_OSERR, "ERROR: Cannot install signal handler");
/*
+ * Setup the top mode display.
+ */
+ if (args.pa_flags & FLAG_DO_TOP) {
+ args.pa_flags &= ~FLAG_DO_PRINT;
+
+ if (args.pa_toptty) {
+ /*
+ * Init ncurses.
+ */
+ initscr();
+ if(has_colors() == TRUE) {
+ args.pa_topcolor = 1;
+ start_color();
+ use_default_colors();
+ pair_content(0, &cf, &cb);
+ init_pair(1, COLOR_RED, cb);
+ init_pair(2, COLOR_YELLOW, cb);
+ init_pair(3, COLOR_GREEN, cb);
+ }
+ cbreak();
+ noecho();
+ nonl();
+ nodelay(stdscr, 1);
+ intrflush(stdscr, FALSE);
+ keypad(stdscr, TRUE);
+ clear();
+ atexit(pmcstat_topexit);
+ }
+ }
+
+ /*
* loop till either the target process (if any) exits, or we
* are killed by a SIGINT.
*/
@@ -1225,14 +1336,18 @@ main(int argc, char **argv)
case EVFILT_PROC: /* target has exited */
if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE |
FLAG_HAS_PIPE))
- runstate = pmcstat_close_log(&args);
+ runstate = pmcstat_close_log();
else
runstate = PMCSTAT_FINISHED;
do_print = 1;
break;
case EVFILT_READ: /* log file data is present */
- runstate = pmcstat_process_log(&args);
+ if (kev.ident == (unsigned)fileno(stdin)) {
+ if (pmcstat_keypress_log())
+ runstate = pmcstat_close_log();
+ } else
+ runstate = pmcstat_process_log();
break;
case EVFILT_SIGNAL:
@@ -1253,17 +1368,17 @@ main(int argc, char **argv)
*/
if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE |
FLAG_HAS_PIPE)) {
- runstate = pmcstat_close_log(&args);
+ runstate = pmcstat_close_log();
if (args.pa_flags &
(FLAG_DO_PRINT|FLAG_DO_ANALYSIS))
- pmcstat_process_log(&args);
+ pmcstat_process_log();
}
do_print = 1; /* print PMCs at exit */
runstate = PMCSTAT_FINISHED;
} else if (kev.ident == SIGINT) {
/* Kill the child process if we started it */
if (args.pa_flags & FLAG_HAS_COMMANDLINE)
- pmcstat_kill_process(&args);
+ pmcstat_kill_process();
/* Close the pipe to self, if present. */
if (args.pa_flags & FLAG_HAS_PIPE)
(void) close(pipefd[READPIPEFD]);
@@ -1274,6 +1389,7 @@ main(int argc, char **argv)
err(EX_OSERR, "ERROR: Cannot determine "
"window size");
pmcstat_displayheight = ws.ws_row - 1;
+ pmcstat_displaywidth = ws.ws_col - 1;
} else
assert(0);
@@ -1285,22 +1401,30 @@ main(int argc, char **argv)
}
- if (do_print &&
- (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) {
- pmcstat_print_pmcs(&args);
- if (runstate == PMCSTAT_FINISHED && /* final newline */
- (args.pa_flags & FLAG_DO_PRINT) == 0)
- (void) fprintf(args.pa_printfile, "\n");
+ if (do_print) {
+ if ((args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) {
+ pmcstat_print_pmcs();
+ if (runstate == PMCSTAT_FINISHED && /* final newline */
+ (args.pa_flags & FLAG_DO_PRINT) == 0)
+ (void) fprintf(args.pa_printfile, "\n");
+ }
+ if (args.pa_flags & FLAG_DO_TOP)
+ pmcstat_display_log();
do_print = 0;
}
} while (runstate != PMCSTAT_FINISHED);
+ if ((args.pa_flags & FLAG_DO_TOP) && args.pa_toptty) {
+ pmcstat_topexit();
+ args.pa_toptty = 0;
+ }
+
/* flush any pending log entries */
if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE))
pmc_flush_logfile();
- pmcstat_cleanup(&args);
+ pmcstat_cleanup();
free(args.pa_kernel);
diff --git a/usr.sbin/pmcstat/pmcstat.h b/usr.sbin/pmcstat/pmcstat.h
index 5d6f5f2..1bb7862 100644
--- a/usr.sbin/pmcstat/pmcstat.h
+++ b/usr.sbin/pmcstat/pmcstat.h
@@ -47,13 +47,15 @@
#define FLAG_HAS_SAMPLESDIR 0x00000800 /* -D dir */
#define FLAG_HAS_KERNELPATH 0x00001000 /* -k kernel */
#define FLAG_DO_PRINT 0x00002000 /* -o */
-#define FLAG_DO_CALLGRAPHS 0x00004000 /* -G */
-#define FLAG_DO_ANALYSIS 0x00008000 /* -g or -G */
-#define FLAG_WANTS_MAPPINGS 0x00010000 /* -m */
+#define FLAG_DO_CALLGRAPHS 0x00004000 /* -G or -F */
+#define FLAG_DO_ANNOTATE 0x00008000 /* -m */
+#define FLAG_DO_TOP 0x00010000 /* -T */
+#define FLAG_DO_ANALYSIS 0x00020000 /* -g or -G or -m or -T */
#define DEFAULT_SAMPLE_COUNT 65536
#define DEFAULT_WAIT_INTERVAL 5.0
-#define DEFAULT_DISPLAY_HEIGHT 23
+#define DEFAULT_DISPLAY_HEIGHT 256 /* file virtual height */
+#define DEFAULT_DISPLAY_WIDTH 1024 /* file virtual width */
#define DEFAULT_BUFFER_SIZE 4096
#define DEFAULT_CALLGRAPH_DEPTH 4
@@ -75,12 +77,24 @@
#define PMCSTAT_LDD_COMMAND "/usr/bin/ldd"
-#define PMCSTAT_PRINT_ENTRY(A,T,...) do { \
- (void) fprintf((A)->pa_printfile, "%-9s", T); \
- (void) fprintf((A)->pa_printfile, " " __VA_ARGS__); \
- (void) fprintf((A)->pa_printfile, "\n"); \
+#define PMCSTAT_PRINT_ENTRY(T,...) do { \
+ (void) fprintf(args.pa_printfile, "%-9s", T); \
+ (void) fprintf(args.pa_printfile, " " __VA_ARGS__); \
+ (void) fprintf(args.pa_printfile, "\n"); \
} while (0)
+#define PMCSTAT_PL_NONE 0
+#define PMCSTAT_PL_CALLGRAPH 1
+#define PMCSTAT_PL_GPROF 2
+#define PMCSTAT_PL_ANNOTATE 3
+#define PMCSTAT_PL_CALLTREE 4
+
+#define PMCSTAT_TOP_DELTA 0
+#define PMCSTAT_TOP_ACCUM 1
+
+#define min(A,B) ((A) < (B) ? (A) : (B))
+#define max(A,B) ((A) > (B) ? (A) : (B))
+
enum pmcstat_state {
PMCSTAT_FINISHED = 0,
PMCSTAT_EXITING = 1,
@@ -110,6 +124,8 @@ struct pmcstat_target {
struct pmcstat_args {
int pa_flags; /* argument flags */
int pa_required; /* required features */
+ int pa_pplugin; /* pre-processing plugin */
+ int pa_plugin; /* analysis plugin */
int pa_verbosity; /* verbosity level */
FILE *pa_printfile; /* where to send printed output */
int pa_logfd; /* output log file */
@@ -124,31 +140,44 @@ struct pmcstat_args {
int pa_graphdepth; /* print depth for callgraphs */
double pa_interval; /* printing interval in seconds */
uint32_t pa_cpumask; /* filter for CPUs analysed */
+ int pa_ctdumpinstr; /* dump instructions with calltree */
+ int pa_topmode; /* delta or accumulative */
+ int pa_toptty; /* output to tty or file */
+ int pa_topcolor; /* terminal support color */
+ int pa_mergepmc; /* merge PMC with same name */
int pa_argc;
char **pa_argv;
STAILQ_HEAD(, pmcstat_ev) pa_events;
SLIST_HEAD(, pmcstat_target) pa_targets;
-} args;
+};
+
+extern int pmcstat_displayheight; /* current terminal height */
+extern int pmcstat_displaywidth; /* current terminal width */
+extern struct pmcstat_args args; /* command line args */
/* Function prototypes */
-void pmcstat_attach_pmcs(struct pmcstat_args *_a);
-void pmcstat_cleanup(struct pmcstat_args *_a);
-void pmcstat_clone_event_descriptor(struct pmcstat_args *_a,
+void pmcstat_attach_pmcs(void);
+void pmcstat_cleanup(void);
+void pmcstat_clone_event_descriptor(
struct pmcstat_ev *_ev, uint32_t _cpumask);
-int pmcstat_close_log(struct pmcstat_args *_a);
-void pmcstat_create_process(struct pmcstat_args *_a);
-void pmcstat_find_targets(struct pmcstat_args *_a, const char *_arg);
-void pmcstat_initialize_logging(struct pmcstat_args *_a);
-void pmcstat_kill_process(struct pmcstat_args *_a);
+int pmcstat_close_log(void);
+void pmcstat_create_process(void);
+void pmcstat_find_targets(const char *_arg);
+void pmcstat_initialize_logging(void);
+void pmcstat_kill_process(void);
int pmcstat_open_log(const char *_p, int _mode);
-void pmcstat_print_counters(struct pmcstat_args *_a);
-void pmcstat_print_headers(struct pmcstat_args *_a);
-void pmcstat_print_pmcs(struct pmcstat_args *_a);
+void pmcstat_print_counters(void);
+void pmcstat_print_headers(void);
+void pmcstat_print_pmcs(void);
void pmcstat_show_usage(void);
-void pmcstat_shutdown_logging(struct pmcstat_args *_a);
-void pmcstat_start_pmcs(struct pmcstat_args *_a);
+void pmcstat_shutdown_logging(void);
+void pmcstat_start_pmcs(void);
void pmcstat_start_process(void);
-int pmcstat_process_log(struct pmcstat_args *_a);
+int pmcstat_process_log(void);
+int pmcstat_keypress_log(void);
+void pmcstat_display_log(void);
+void pmcstat_pluginconfigure_log(char *_opt);
uint32_t pmcstat_get_cpumask(const char *_a);
+void pmcstat_topexit(void);
#endif /* _PMCSTAT_H_ */
diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c
index 9814126..5811af3 100644
--- a/usr.sbin/pmcstat/pmcstat_log.c
+++ b/usr.sbin/pmcstat/pmcstat_log.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <assert.h>
+#include <curses.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -68,9 +69,8 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include "pmcstat.h"
-
-#define min(A,B) ((A) < (B) ? (A) : (B))
-#define max(A,B) ((A) > (B) ? (A) : (B))
+#include "pmcstat_log.h"
+#include "pmcstat_top.h"
#define PMCSTAT_ALLOCATE 1
@@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$");
* pmcstat_shutdown_logging() orderly shutdown, called last
* pmcstat_open_log() open an eventlog for processing
* pmcstat_process_log() print/convert an event log
+ * pmcstat_display_log() top mode display for the log
* pmcstat_close_log() finish processing an event log
*
* IMPLEMENTATION NOTES
@@ -127,236 +128,125 @@ __FBSDID("$FreeBSD$");
* also given a 'rank' that reflects its depth in the call stack.
*/
-typedef const void *pmcstat_interned_string;
-
-/*
- * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable
- * names.
- */
-
-struct pmcstat_pmcrecord {
- LIST_ENTRY(pmcstat_pmcrecord) pr_next;
- pmc_id_t pr_pmcid;
- pmcstat_interned_string pr_pmcname;
-};
-
-static LIST_HEAD(,pmcstat_pmcrecord) pmcstat_pmcs =
- LIST_HEAD_INITIALIZER(&pmcstat_pmcs);
-
-
-/*
- * struct pmcstat_gmonfile tracks a given 'gmon.out' file. These
- * files are mmap()'ed in as needed.
- */
-
-struct pmcstat_gmonfile {
- LIST_ENTRY(pmcstat_gmonfile) pgf_next; /* list of entries */
- int pgf_overflow; /* whether a count overflowed */
- pmc_id_t pgf_pmcid; /* id of the associated pmc */
- size_t pgf_nbuckets; /* #buckets in this gmon.out */
- unsigned int pgf_nsamples; /* #samples in this gmon.out */
- pmcstat_interned_string pgf_name; /* pathname of gmon.out file */
- size_t pgf_ndatabytes; /* number of bytes mapped */
- void *pgf_gmondata; /* pointer to mmap'ed data */
- FILE *pgf_file; /* used when writing gmon arcs */
-};
-
-/*
- * A 'pmcstat_image' structure describes an executable program on
- * disk. 'pi_execpath' is a cookie representing the pathname of
- * the executable. 'pi_start' and 'pi_end' are the least and greatest
- * virtual addresses for the text segments in the executable.
- * 'pi_gmonlist' contains a linked list of gmon.out files associated
- * with this image.
- */
-
-enum pmcstat_image_type {
- PMCSTAT_IMAGE_UNKNOWN = 0, /* never looked at the image */
- PMCSTAT_IMAGE_INDETERMINABLE, /* can't tell what the image is */
- PMCSTAT_IMAGE_ELF32, /* ELF 32 bit object */
- PMCSTAT_IMAGE_ELF64, /* ELF 64 bit object */
- PMCSTAT_IMAGE_AOUT /* AOUT object */
-};
-
-struct pmcstat_image {
- LIST_ENTRY(pmcstat_image) pi_next; /* hash link */
- TAILQ_ENTRY(pmcstat_image) pi_lru; /* LRU list */
- pmcstat_interned_string pi_execpath; /* cookie */
- pmcstat_interned_string pi_samplename; /* sample path name */
- pmcstat_interned_string pi_fullpath; /* path to FS object */
-
- enum pmcstat_image_type pi_type; /* executable type */
-
- /*
- * Executables have pi_start and pi_end; these are zero
- * for shared libraries.
- */
- uintfptr_t pi_start; /* start address (inclusive) */
- uintfptr_t pi_end; /* end address (exclusive) */
- uintfptr_t pi_entry; /* entry address */
- uintfptr_t pi_vaddr; /* virtual address where loaded */
- int pi_isdynamic; /* whether a dynamic object */
- int pi_iskernelmodule;
- pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */
-
- /* All symbols associated with this object. */
- struct pmcstat_symbol *pi_symbols;
- size_t pi_symcount;
-
- /*
- * An image can be associated with one or more gmon.out files;
- * one per PMC.
- */
- LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
-};
+struct pmcstat_pmcs pmcstat_pmcs = LIST_HEAD_INITIALIZER(pmcstat_pmcs);
/*
* All image descriptors are kept in a hash table.
*/
-static LIST_HEAD(,pmcstat_image) pmcstat_image_hash[PMCSTAT_NHASH];
-
-/*
- * A 'pmcstat_pcmap' structure maps a virtual address range to an
- * underlying 'pmcstat_image' descriptor.
- */
-struct pmcstat_pcmap {
- TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
- uintfptr_t ppm_lowpc;
- uintfptr_t ppm_highpc;
- struct pmcstat_image *ppm_image;
-};
+struct pmcstat_image_hash_list pmcstat_image_hash[PMCSTAT_NHASH];
/*
- * A 'pmcstat_process' structure models processes. Each process is
- * associated with a set of pmcstat_pcmap structures that map
- * addresses inside it to executable objects. This set is implemented
- * as a list, kept sorted in ascending order of mapped addresses.
- *
- * 'pp_pid' holds the pid of the process. When a process exits, the
- * 'pp_isactive' field is set to zero, but the process structure is
- * not immediately reclaimed because there may still be samples in the
- * log for this process.
+ * All process descriptors are kept in a hash table.
*/
+struct pmcstat_process_hash_list pmcstat_process_hash[PMCSTAT_NHASH];
-struct pmcstat_process {
- LIST_ENTRY(pmcstat_process) pp_next; /* hash-next */
- pid_t pp_pid; /* associated pid */
- int pp_isactive; /* whether active */
- uintfptr_t pp_entryaddr; /* entry address */
- TAILQ_HEAD(,pmcstat_pcmap) pp_map; /* address range map */
-};
+struct pmcstat_stats pmcstat_stats; /* statistics */
-/*
- * All process descriptors are kept in a hash table.
- */
-static LIST_HEAD(,pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH];
+struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
-static struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
+#include "pmcpl_gprof.h"
+#include "pmcpl_callgraph.h"
+#include "pmcpl_annotate.h"
+#include "pmcpl_calltree.h"
-/*
- * Each function symbol tracked by pmcstat(8).
- */
+struct pmc_plugins {
+ const char *pl_name; /* name */
-struct pmcstat_symbol {
- pmcstat_interned_string ps_name;
- uint64_t ps_start;
- uint64_t ps_end;
-};
+ /* configure */
+ int (*pl_configure)(char *opt);
-/*
- * Each call graph node is tracked by a pmcstat_cgnode struct.
- */
+ /* init and shutdown */
+ int (*pl_init)(void);
+ void (*pl_shutdown)(FILE *mf);
-struct pmcstat_cgnode {
- struct pmcstat_image *pcg_image;
- uintfptr_t pcg_func;
- uint32_t pcg_count;
- uint32_t pcg_nchildren;
- LIST_ENTRY(pmcstat_cgnode) pcg_sibling;
- LIST_HEAD(,pmcstat_cgnode) pcg_children;
-};
+ /* sample processing */
+ void (*pl_process)(struct pmcstat_process *pp,
+ struct pmcstat_pmcrecord *pmcr, uint32_t nsamples,
+ uintfptr_t *cc, int usermode, uint32_t cpu);
-struct pmcstat_cgnode_hash {
- struct pmcstat_cgnode *pch_cgnode;
- uint32_t pch_pmcid;
- LIST_ENTRY(pmcstat_cgnode_hash) pch_next;
-};
+ /* image */
+ void (*pl_initimage)(struct pmcstat_image *pi);
+ void (*pl_shutdownimage)(struct pmcstat_image *pi);
-static int pmcstat_cgnode_hash_count;
-static pmcstat_interned_string pmcstat_previous_filename_printed;
+ /* pmc */
+ void (*pl_newpmc)(pmcstat_interned_string ps,
+ struct pmcstat_pmcrecord *pr);
+
+ /* top display */
+ void (*pl_topdisplay)(void);
-/*
- * The toplevel CG nodes (i.e., with rank == 0) are placed in a hash table.
- */
+ /* top keypress */
+ int (*pl_topkeypress)(int c, WINDOW *w);
-static LIST_HEAD(,pmcstat_cgnode_hash) pmcstat_cgnode_hash[PMCSTAT_NHASH];
+} plugins[] = {
+ {
+ .pl_name = "none",
+ },
+ {
+ .pl_name = "callgraph",
+ .pl_init = pmcpl_cg_init,
+ .pl_shutdown = pmcpl_cg_shutdown,
+ .pl_process = pmcpl_cg_process,
+ .pl_topkeypress = pmcpl_cg_topkeypress,
+ .pl_topdisplay = pmcpl_cg_topdisplay
+ },
+ {
+ .pl_name = "gprof",
+ .pl_shutdown = pmcpl_gmon_shutdown,
+ .pl_process = pmcpl_gmon_process,
+ .pl_initimage = pmcpl_gmon_initimage,
+ .pl_shutdownimage = pmcpl_gmon_shutdownimage,
+ .pl_newpmc = pmcpl_gmon_newpmc
+ },
+ {
+ .pl_name = "annotate",
+ .pl_process = pmcpl_annotate_process
+ },
+ {
+ .pl_name = "calltree",
+ .pl_configure = pmcpl_ct_configure,
+ .pl_init = pmcpl_ct_init,
+ .pl_shutdown = pmcpl_ct_shutdown,
+ .pl_process = pmcpl_ct_process,
+ .pl_topkeypress = pmcpl_ct_topkeypress,
+ .pl_topdisplay = pmcpl_ct_topdisplay
+ },
+ {
+ .pl_name = NULL
+ }
+};
-/* Misc. statistics */
-static struct pmcstat_stats {
- int ps_exec_aout; /* # a.out executables seen */
- int ps_exec_elf; /* # elf executables seen */
- int ps_exec_errors; /* # errors processing executables */
- int ps_exec_indeterminable; /* # unknown executables seen */
- int ps_samples_total; /* total number of samples processed */
- int ps_samples_skipped; /* #samples filtered out for any reason */
- int ps_samples_unknown_offset; /* #samples of rank 0 not in a map */
- int ps_samples_indeterminable; /* #samples in indeterminable images */
- int ps_callchain_dubious_frames;/* #dubious frame pointers seen */
-} pmcstat_stats;
+int pmcstat_mergepmc;
+int pmcstat_pmcinfilter = 0; /* PMC filter for top mode. */
+float pmcstat_threshold = 0.5; /* Cost filter for top mode. */
/*
* Prototypes
*/
-static void pmcstat_gmon_create_file(struct pmcstat_gmonfile *_pgf,
- struct pmcstat_image *_image);
-static pmcstat_interned_string pmcstat_gmon_create_name(const char *_sd,
- struct pmcstat_image *_img, pmc_id_t _pmcid);
-static void pmcstat_gmon_map_file(struct pmcstat_gmonfile *_pgf);
-static void pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *_pgf);
-
-static void pmcstat_image_determine_type(struct pmcstat_image *_image,
- struct pmcstat_args *_a);
-static struct pmcstat_gmonfile *pmcstat_image_find_gmonfile(struct
- pmcstat_image *_i, pmc_id_t _id);
static struct pmcstat_image *pmcstat_image_from_path(pmcstat_interned_string
_path, int _iskernelmodule);
-static void pmcstat_image_get_aout_params(struct pmcstat_image *_image,
- struct pmcstat_args *_a);
-static void pmcstat_image_get_elf_params(struct pmcstat_image *_image,
- struct pmcstat_args *_a);
-static void pmcstat_image_increment_bucket(struct pmcstat_pcmap *_pcm,
- uintfptr_t _pc, pmc_id_t _pmcid, struct pmcstat_args *_a);
+static void pmcstat_image_get_aout_params(struct pmcstat_image *_image);
+static void pmcstat_image_get_elf_params(struct pmcstat_image *_image);
static void pmcstat_image_link(struct pmcstat_process *_pp,
struct pmcstat_image *_i, uintfptr_t _lpc);
static void pmcstat_pmcid_add(pmc_id_t _pmcid,
- pmcstat_interned_string _name, struct pmcstat_args *_a);
-static const char *pmcstat_pmcid_to_name(pmc_id_t _pmcid);
+ pmcstat_interned_string _name);
static void pmcstat_process_aout_exec(struct pmcstat_process *_pp,
- struct pmcstat_image *_image, uintfptr_t _entryaddr,
- struct pmcstat_args *_a);
+ struct pmcstat_image *_image, uintfptr_t _entryaddr);
static void pmcstat_process_elf_exec(struct pmcstat_process *_pp,
- struct pmcstat_image *_image, uintfptr_t _entryaddr,
- struct pmcstat_args *_a);
+ struct pmcstat_image *_image, uintfptr_t _entryaddr);
static void pmcstat_process_exec(struct pmcstat_process *_pp,
- pmcstat_interned_string _path, uintfptr_t _entryaddr,
- struct pmcstat_args *_ao);
+ pmcstat_interned_string _path, uintfptr_t _entryaddr);
static struct pmcstat_process *pmcstat_process_lookup(pid_t _pid,
int _allocate);
-static struct pmcstat_pcmap *pmcstat_process_find_map(
- struct pmcstat_process *_p, uintfptr_t _pc);
-
static int pmcstat_string_compute_hash(const char *_string);
static void pmcstat_string_initialize(void);
-static pmcstat_interned_string pmcstat_string_intern(const char *_s);
-static pmcstat_interned_string pmcstat_string_lookup(const char *_s);
static int pmcstat_string_lookup_hash(pmcstat_interned_string _is);
static void pmcstat_string_shutdown(void);
-static const char *pmcstat_string_unintern(pmcstat_interned_string _is);
-
/*
* A simple implementation of interned strings. Each interned string
@@ -375,6 +265,16 @@ struct pmcstat_string {
static LIST_HEAD(,pmcstat_string) pmcstat_string_hash[PMCSTAT_NHASH];
/*
+ * PMC count.
+ */
+int pmcstat_npmcs;
+
+/*
+ * PMC Top mode pause state.
+ */
+int pmcstat_pause;
+
+/*
* Compute a 'hash' value for a string.
*/
@@ -394,7 +294,7 @@ pmcstat_string_compute_hash(const char *s)
* interned structure.
*/
-static pmcstat_interned_string
+pmcstat_interned_string
pmcstat_string_intern(const char *s)
{
struct pmcstat_string *ps;
@@ -416,7 +316,7 @@ pmcstat_string_intern(const char *s)
return ((pmcstat_interned_string) ps);
}
-static const char *
+const char *
pmcstat_string_unintern(pmcstat_interned_string str)
{
const char *s;
@@ -425,7 +325,7 @@ pmcstat_string_unintern(pmcstat_interned_string str)
return (s);
}
-static pmcstat_interned_string
+pmcstat_interned_string
pmcstat_string_lookup(const char *s)
{
struct pmcstat_string *ps;
@@ -483,163 +383,13 @@ pmcstat_string_shutdown(void)
}
/*
- * Create a gmon.out file and size it.
- */
-
-static void
-pmcstat_gmon_create_file(struct pmcstat_gmonfile *pgf,
- struct pmcstat_image *image)
-{
- int fd;
- size_t count;
- struct gmonhdr gm;
- const char *pathname;
- char buffer[DEFAULT_BUFFER_SIZE];
-
- pathname = pmcstat_string_unintern(pgf->pgf_name);
- if ((fd = open(pathname, O_RDWR|O_NOFOLLOW|O_CREAT,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
- err(EX_OSERR, "ERROR: Cannot open \"%s\"", pathname);
-
- gm.lpc = image->pi_start;
- gm.hpc = image->pi_end;
- gm.ncnt = (pgf->pgf_nbuckets * sizeof(HISTCOUNTER)) +
- sizeof(struct gmonhdr);
- gm.version = GMONVERSION;
- gm.profrate = 0; /* use ticks */
- gm.histcounter_type = 0; /* compatibility with moncontrol() */
- gm.spare[0] = gm.spare[1] = 0;
-
- /* Write out the gmon header */
- if (write(fd, &gm, sizeof(gm)) < 0)
- goto error;
-
- /* Zero fill the samples[] array */
- (void) memset(buffer, 0, sizeof(buffer));
-
- count = pgf->pgf_ndatabytes - sizeof(struct gmonhdr);
- while (count > sizeof(buffer)) {
- if (write(fd, &buffer, sizeof(buffer)) < 0)
- goto error;
- count -= sizeof(buffer);
- }
-
- if (write(fd, &buffer, count) < 0)
- goto error;
-
- (void) close(fd);
-
- return;
-
- error:
- err(EX_OSERR, "ERROR: Cannot write \"%s\"", pathname);
-}
-
-/*
- * Determine the full pathname of a gmon.out file for a given
- * (image,pmcid) combination. Return the interned string.
- */
-
-pmcstat_interned_string
-pmcstat_gmon_create_name(const char *samplesdir, struct pmcstat_image *image,
- pmc_id_t pmcid)
-{
- const char *pmcname;
- char fullpath[PATH_MAX];
-
- pmcname = pmcstat_pmcid_to_name(pmcid);
-
- (void) snprintf(fullpath, sizeof(fullpath),
- "%s/%s/%s", samplesdir, pmcname,
- pmcstat_string_unintern(image->pi_samplename));
-
- return (pmcstat_string_intern(fullpath));
-}
-
-
-/*
- * Mmap in a gmon.out file for processing.
- */
-
-static void
-pmcstat_gmon_map_file(struct pmcstat_gmonfile *pgf)
-{
- int fd;
- const char *pathname;
-
- pathname = pmcstat_string_unintern(pgf->pgf_name);
-
- /* the gmon.out file must already exist */
- if ((fd = open(pathname, O_RDWR | O_NOFOLLOW, 0)) < 0)
- err(EX_OSERR, "ERROR: cannot open \"%s\"", pathname);
-
- pgf->pgf_gmondata = mmap(NULL, pgf->pgf_ndatabytes,
- PROT_READ|PROT_WRITE, MAP_NOSYNC|MAP_SHARED, fd, 0);
-
- if (pgf->pgf_gmondata == MAP_FAILED)
- err(EX_OSERR, "ERROR: cannot map \"%s\"", pathname);
-
- (void) close(fd);
-}
-
-/*
- * Unmap a gmon.out file after sync'ing its data to disk.
- */
-
-static void
-pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *pgf)
-{
- (void) msync(pgf->pgf_gmondata, pgf->pgf_ndatabytes,
- MS_SYNC);
- (void) munmap(pgf->pgf_gmondata, pgf->pgf_ndatabytes);
- pgf->pgf_gmondata = NULL;
-}
-
-static void
-pmcstat_gmon_append_arc(struct pmcstat_image *image, pmc_id_t pmcid,
- uintptr_t rawfrom, uintptr_t rawto, uint32_t count)
-{
- struct rawarc arc; /* from <sys/gmon.h> */
- const char *pathname;
- struct pmcstat_gmonfile *pgf;
-
- if ((pgf = pmcstat_image_find_gmonfile(image, pmcid)) == NULL)
- return;
-
- if (pgf->pgf_file == NULL) {
- pathname = pmcstat_string_unintern(pgf->pgf_name);
- if ((pgf->pgf_file = fopen(pathname, "a")) == NULL)
- return;
- }
-
- arc.raw_frompc = rawfrom + image->pi_vaddr;
- arc.raw_selfpc = rawto + image->pi_vaddr;
- arc.raw_count = count;
-
- (void) fwrite(&arc, sizeof(arc), 1, pgf->pgf_file);
-
-}
-
-static struct pmcstat_gmonfile *
-pmcstat_image_find_gmonfile(struct pmcstat_image *image, pmc_id_t pmcid)
-{
- struct pmcstat_gmonfile *pgf;
- LIST_FOREACH(pgf, &image->pi_gmlist, pgf_next)
- if (pgf->pgf_pmcid == pmcid)
- return (pgf);
- return (NULL);
-}
-
-
-/*
* Determine whether a given executable image is an A.OUT object, and
* if so, fill in its parameters from the text file.
* Sets image->pi_type.
*/
static void
-pmcstat_image_get_aout_params(struct pmcstat_image *image,
- struct pmcstat_args *a)
+pmcstat_image_get_aout_params(struct pmcstat_image *image)
{
int fd;
ssize_t nbytes;
@@ -655,7 +405,7 @@ pmcstat_image_get_aout_params(struct pmcstat_image *image,
"unsupported \"%s\"", path);
(void) snprintf(buffer, sizeof(buffer), "%s%s",
- a->pa_fsroot, path);
+ args.pa_fsroot, path);
if ((fd = open(buffer, O_RDONLY, 0)) < 0 ||
(nbytes = read(fd, &ex, sizeof(ex))) < 0) {
@@ -702,7 +452,7 @@ pmcstat_symbol_compare(const void *a, const void *b)
* Map an address to a symbol in an image.
*/
-static struct pmcstat_symbol *
+struct pmcstat_symbol *
pmcstat_symbol_search(struct pmcstat_image *image, uintfptr_t addr)
{
struct pmcstat_symbol sym;
@@ -825,12 +575,12 @@ pmcstat_image_add_symbols(struct pmcstat_image *image, Elf *e,
*/
static void
-pmcstat_image_get_elf_params(struct pmcstat_image *image,
- struct pmcstat_args *a)
+pmcstat_image_get_elf_params(struct pmcstat_image *image)
{
int fd;
size_t i, nph, nsh;
const char *path, *elfbase;
+ char *p, *endp;
uintfptr_t minva, maxva;
Elf *e;
Elf_Scn *scn;
@@ -858,10 +608,10 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image,
*/
if (image->pi_iskernelmodule)
(void) snprintf(buffer, sizeof(buffer), "%s%s/%s",
- a->pa_fsroot, a->pa_kernel, path);
+ args.pa_fsroot, args.pa_kernel, path);
else
(void) snprintf(buffer, sizeof(buffer), "%s%s",
- a->pa_fsroot, path);
+ args.pa_fsroot, path);
e = NULL;
if ((fd = open(buffer, O_RDONLY, 0)) < 0 ||
@@ -960,6 +710,14 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image,
image->pi_type = image_type;
image->pi_fullpath = pmcstat_string_intern(buffer);
+ /* Build display name
+ */
+ endp = buffer;
+ for (p = buffer; *p; p++)
+ if (*p == '/')
+ endp = p+1;
+ image->pi_name = pmcstat_string_intern(endp);
+
done:
(void) elf_end(e);
if (fd >= 0)
@@ -972,17 +730,16 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image,
* If no handler claims the image, set its type to 'INDETERMINABLE'.
*/
-static void
-pmcstat_image_determine_type(struct pmcstat_image *image,
- struct pmcstat_args *a)
+void
+pmcstat_image_determine_type(struct pmcstat_image *image)
{
assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN);
/* Try each kind of handler in turn */
if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
- pmcstat_image_get_elf_params(image, a);
+ pmcstat_image_get_elf_params(image);
if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
- pmcstat_image_get_aout_params(image, a);
+ pmcstat_image_get_aout_params(image);
/*
* Otherwise, remember that we tried to determine
@@ -1006,10 +763,8 @@ static struct pmcstat_image *
pmcstat_image_from_path(pmcstat_interned_string internedpath,
int iskernelmodule)
{
- int count, hash, nlen;
+ int hash;
struct pmcstat_image *pi;
- char *sn;
- char name[NAME_MAX];
hash = pmcstat_string_lookup_hash(internedpath);
@@ -1038,50 +793,12 @@ pmcstat_image_from_path(pmcstat_interned_string internedpath,
pi->pi_dynlinkerpath = NULL;
pi->pi_symbols = NULL;
pi->pi_symcount = 0;
+ pi->pi_addr2line = NULL;
- /*
- * Look for a suitable name for the sample files associated
- * with this image: if `basename(path)`+".gmon" is available,
- * we use that, otherwise we try iterating through
- * `basename(path)`+ "~" + NNN + ".gmon" till we get a free
- * entry.
- */
- if ((sn = basename(pmcstat_string_unintern(internedpath))) == NULL)
- err(EX_OSERR, "ERROR: Cannot process \"%s\"",
- pmcstat_string_unintern(internedpath));
-
- nlen = strlen(sn);
- nlen = min(nlen, (int) (sizeof(name) - sizeof(".gmon")));
-
- snprintf(name, sizeof(name), "%.*s.gmon", nlen, sn);
-
- /* try use the unabridged name first */
- if (pmcstat_string_lookup(name) == NULL)
- pi->pi_samplename = pmcstat_string_intern(name);
- else {
- /*
- * Otherwise use a prefix from the original name and
- * upto 3 digits.
- */
- nlen = strlen(sn);
- nlen = min(nlen, (int) (sizeof(name)-sizeof("~NNN.gmon")));
- count = 0;
- do {
- if (++count > 999)
- errx(EX_CANTCREAT, "ERROR: cannot create a "
- "gmon file for \"%s\"", name);
- snprintf(name, sizeof(name), "%.*s~%3.3d.gmon",
- nlen, sn, count);
- if (pmcstat_string_lookup(name) == NULL) {
- pi->pi_samplename =
- pmcstat_string_intern(name);
- count = 0;
- }
- } while (count > 0);
- }
-
-
- LIST_INIT(&pi->pi_gmlist);
+ if (plugins[args.pa_pplugin].pl_initimage != NULL)
+ plugins[args.pa_pplugin].pl_initimage(pi);
+ if (plugins[args.pa_plugin].pl_initimage != NULL)
+ plugins[args.pa_plugin].pl_initimage(pi);
LIST_INSERT_HEAD(&pmcstat_image_hash[hash], pi, pi_next);
@@ -1089,94 +806,6 @@ pmcstat_image_from_path(pmcstat_interned_string internedpath,
}
/*
- * Increment the bucket in the gmon.out file corresponding to 'pmcid'
- * and 'pc'.
- */
-
-static void
-pmcstat_image_increment_bucket(struct pmcstat_pcmap *map, uintfptr_t pc,
- pmc_id_t pmcid, struct pmcstat_args *a)
-{
- struct pmcstat_image *image;
- struct pmcstat_gmonfile *pgf;
- uintfptr_t bucket;
- HISTCOUNTER *hc;
-
- assert(pc >= map->ppm_lowpc && pc < map->ppm_highpc);
-
- image = map->ppm_image;
-
- /*
- * If this is the first time we are seeing a sample for
- * this executable image, try determine its parameters.
- */
- if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
- pmcstat_image_determine_type(image, a);
-
- assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN);
-
- /* Ignore samples in images that we know nothing about. */
- if (image->pi_type == PMCSTAT_IMAGE_INDETERMINABLE) {
- pmcstat_stats.ps_samples_indeterminable++;
- return;
- }
-
- /*
- * Find the gmon file corresponding to 'pmcid', creating it if
- * needed.
- */
- pgf = pmcstat_image_find_gmonfile(image, pmcid);
- if (pgf == NULL) {
- if ((pgf = calloc(1, sizeof(*pgf))) == NULL)
- err(EX_OSERR, "ERROR:");
-
- pgf->pgf_gmondata = NULL; /* mark as unmapped */
- pgf->pgf_name = pmcstat_gmon_create_name(a->pa_samplesdir,
- image, pmcid);
- pgf->pgf_pmcid = pmcid;
- assert(image->pi_end > image->pi_start);
- pgf->pgf_nbuckets = (image->pi_end - image->pi_start) /
- FUNCTION_ALIGNMENT; /* see <machine/profile.h> */
- pgf->pgf_ndatabytes = sizeof(struct gmonhdr) +
- pgf->pgf_nbuckets * sizeof(HISTCOUNTER);
- pgf->pgf_nsamples = 0;
- pgf->pgf_file = NULL;
-
- pmcstat_gmon_create_file(pgf, image);
-
- LIST_INSERT_HEAD(&image->pi_gmlist, pgf, pgf_next);
- }
-
- /*
- * Map the gmon file in if needed. It may have been mapped
- * out under memory pressure.
- */
- if (pgf->pgf_gmondata == NULL)
- pmcstat_gmon_map_file(pgf);
-
- assert(pgf->pgf_gmondata != NULL);
-
- /*
- *
- */
-
- bucket = (pc - map->ppm_lowpc) / FUNCTION_ALIGNMENT;
-
- assert(bucket < pgf->pgf_nbuckets);
-
- hc = (HISTCOUNTER *) ((uintptr_t) pgf->pgf_gmondata +
- sizeof(struct gmonhdr));
-
- /* saturating add */
- if (hc[bucket] < 0xFFFFU) /* XXX tie this to sizeof(HISTCOUNTER) */
- hc[bucket]++;
- else /* mark that an overflow occurred */
- pgf->pgf_overflow = 1;
-
- pgf->pgf_nsamples++;
-}
-
-/*
* Record the fact that PC values from 'start' to 'end' come from
* image 'image'.
*/
@@ -1284,72 +913,181 @@ pmcstat_image_unmap(struct pmcstat_process *pp, uintfptr_t start,
}
/*
+ * Resolve file name and line number for the given address.
+ */
+int
+pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr,
+ char *sourcefile, size_t sourcefile_len, unsigned *sourceline,
+ char *funcname, size_t funcname_len)
+{
+ static int addr2line_warn = 0;
+
+ char *sep, cmdline[PATH_MAX], imagepath[PATH_MAX];
+ int fd;
+
+ if (image->pi_addr2line == NULL) {
+ snprintf(imagepath, sizeof(imagepath), "%s.symbols",
+ pmcstat_string_unintern(image->pi_fullpath));
+ fd = open(imagepath, O_RDONLY);
+ if (fd < 0) {
+ snprintf(imagepath, sizeof(imagepath), "%s",
+ pmcstat_string_unintern(image->pi_fullpath));
+ } else
+ close(fd);
+ snprintf(cmdline, sizeof(cmdline), "addr2line -Cfe \"%s\"",
+ imagepath);
+ image->pi_addr2line = popen(cmdline, "r+");
+ if (image->pi_addr2line == NULL) {
+ if (!addr2line_warn) {
+ addr2line_warn = 1;
+ warnx("WARNING: addr2line is needed"
+ "for source code information.");
+ }
+ return (0);
+ }
+ }
+
+ if (feof(image->pi_addr2line) || ferror(image->pi_addr2line)) {
+ warnx("WARNING: addr2line pipe error");
+ pclose(image->pi_addr2line);
+ image->pi_addr2line = NULL;
+ return (0);
+ }
+
+ fprintf(image->pi_addr2line, "%p\n", (void *)addr);
+
+ if (fgets(funcname, funcname_len, image->pi_addr2line) == NULL) {
+ warnx("WARNING: addr2line function name read error");
+ return (0);
+ }
+ sep = strchr(funcname, '\n');
+ if (sep != NULL)
+ *sep = '\0';
+
+ if (fgets(sourcefile, sourcefile_len, image->pi_addr2line) == NULL) {
+ warnx("WARNING: addr2line source file read error");
+ return (0);
+ }
+ sep = strchr(sourcefile, ':');
+ if (sep == NULL) {
+ warnx("WARNING: addr2line source line separator missing");
+ return (0);
+ }
+ *sep = '\0';
+ *sourceline = atoi(sep+1);
+ if (*sourceline == 0)
+ return (0);
+
+ return (1);
+}
+
+/*
* Add a {pmcid,name} mapping.
*/
static void
-pmcstat_pmcid_add(pmc_id_t pmcid, pmcstat_interned_string ps,
- struct pmcstat_args *a)
+pmcstat_pmcid_add(pmc_id_t pmcid, pmcstat_interned_string ps)
{
- struct pmcstat_pmcrecord *pr;
- struct stat st;
- char fullpath[PATH_MAX];
+ struct pmcstat_pmcrecord *pr, *prm;
/* Replace an existing name for the PMC. */
+ prm = NULL;
LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
- if (pr->pr_pmcid == pmcid) {
- pr->pr_pmcname = ps;
- return;
- }
+ if (pr->pr_pmcid == pmcid) {
+ pr->pr_pmcname = ps;
+ return;
+ } else if (pr->pr_pmcname == ps)
+ prm = pr;
/*
- * Otherwise, allocate a new descriptor and create the
- * appropriate directory to hold gmon.out files.
+ * Otherwise, allocate a new descriptor and call the
+ * plugins hook.
*/
if ((pr = malloc(sizeof(*pr))) == NULL)
err(EX_OSERR, "ERROR: Cannot allocate pmc record");
pr->pr_pmcid = pmcid;
pr->pr_pmcname = ps;
- LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next);
+ pr->pr_pmcin = pmcstat_npmcs++;
+ pr->pr_merge = prm == NULL ? pr : prm;
- (void) snprintf(fullpath, sizeof(fullpath), "%s/%s", a->pa_samplesdir,
- pmcstat_string_unintern(ps));
-
- /* If the path name exists, it should be a directory */
- if (stat(fullpath, &st) == 0 && S_ISDIR(st.st_mode))
- return;
+ LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next);
- if (mkdir(fullpath, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) < 0)
- err(EX_OSERR, "ERROR: Cannot create directory \"%s\"",
- fullpath);
+ if (plugins[args.pa_pplugin].pl_newpmc != NULL)
+ plugins[args.pa_pplugin].pl_newpmc(ps, pr);
+ if (plugins[args.pa_plugin].pl_newpmc != NULL)
+ plugins[args.pa_plugin].pl_newpmc(ps, pr);
}
/*
* Given a pmcid in use, find its human-readable name.
*/
-static const char *
+const char *
pmcstat_pmcid_to_name(pmc_id_t pmcid)
{
struct pmcstat_pmcrecord *pr;
- char fullpath[PATH_MAX];
LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
if (pr->pr_pmcid == pmcid)
return (pmcstat_string_unintern(pr->pr_pmcname));
- /* create a default name and add this entry */
- if ((pr = malloc(sizeof(*pr))) == NULL)
- err(EX_OSERR, "ERROR: ");
- pr->pr_pmcid = pmcid;
+ err(EX_SOFTWARE, "ERROR: cannot find pmcid");
+ return NULL;
+}
- (void) snprintf(fullpath, sizeof(fullpath), "%X", (unsigned int) pmcid);
- pr->pr_pmcname = pmcstat_string_intern(fullpath);
+/*
+ * Convert PMC index to name.
+ */
- LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next);
+const char *
+pmcstat_pmcindex_to_name(int pmcin)
+{
+ struct pmcstat_pmcrecord *pr;
+
+ LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
+ if (pr->pr_pmcin == pmcin)
+ return pmcstat_string_unintern(pr->pr_pmcname);
+
+ err(EX_SOFTWARE, "ERROR: cannot find pmcid name");
+ return NULL;
+}
+
+/*
+ * Return PMC record with given index.
+ */
+
+struct pmcstat_pmcrecord *
+pmcstat_pmcindex_to_pmcr(int pmcin)
+{
+ struct pmcstat_pmcrecord *pr;
+
+ LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
+ if (pr->pr_pmcin == pmcin)
+ return pr;
- return (pmcstat_string_unintern(pr->pr_pmcname));
+ err(EX_SOFTWARE, "ERROR: invalid pmcindex");
+ return NULL;
+}
+
+/*
+ * Get PMC record by id, apply merge policy.
+ */
+
+static struct pmcstat_pmcrecord *
+pmcstat_lookup_pmcid(pmc_id_t pmcid)
+{
+ struct pmcstat_pmcrecord *pr;
+
+ LIST_FOREACH(pr, &pmcstat_pmcs, pr_next) {
+ if (pr->pr_pmcid == pmcid) {
+ if (pmcstat_mergepmc)
+ return pr->pr_merge;
+ return pr;
+ }
+ }
+
+ return NULL;
}
/*
@@ -1358,13 +1096,11 @@ pmcstat_pmcid_to_name(pmc_id_t pmcid)
static void
pmcstat_process_aout_exec(struct pmcstat_process *pp,
- struct pmcstat_image *image, uintfptr_t entryaddr,
- struct pmcstat_args *a)
+ struct pmcstat_image *image, uintfptr_t entryaddr)
{
(void) pp;
(void) image;
(void) entryaddr;
- (void) a;
/* TODO Implement a.out handling */
}
@@ -1374,8 +1110,7 @@ pmcstat_process_aout_exec(struct pmcstat_process *pp,
static void
pmcstat_process_elf_exec(struct pmcstat_process *pp,
- struct pmcstat_image *image, uintfptr_t entryaddr,
- struct pmcstat_args *a)
+ struct pmcstat_image *image, uintfptr_t entryaddr)
{
uintmax_t libstart;
struct pmcstat_image *rtldimage;
@@ -1414,8 +1149,7 @@ pmcstat_process_elf_exec(struct pmcstat_process *pp,
* this we can figure out the address where the
* runtime loader's file object had been mapped to.
*/
- rtldimage = pmcstat_image_from_path(image->pi_dynlinkerpath,
- 0);
+ rtldimage = pmcstat_image_from_path(image->pi_dynlinkerpath, 0);
if (rtldimage == NULL) {
warnx("WARNING: Cannot find image for \"%s\".",
pmcstat_string_unintern(image->pi_dynlinkerpath));
@@ -1424,7 +1158,7 @@ pmcstat_process_elf_exec(struct pmcstat_process *pp,
}
if (rtldimage->pi_type == PMCSTAT_IMAGE_UNKNOWN)
- pmcstat_image_get_elf_params(rtldimage, a);
+ pmcstat_image_get_elf_params(rtldimage);
if (rtldimage->pi_type != PMCSTAT_IMAGE_ELF32 &&
rtldimage->pi_type != PMCSTAT_IMAGE_ELF64) {
@@ -1495,8 +1229,7 @@ pmcstat_process_lookup(pid_t pid, int allocate)
static void
pmcstat_process_exec(struct pmcstat_process *pp,
- pmcstat_interned_string path, uintfptr_t entryaddr,
- struct pmcstat_args *a)
+ pmcstat_interned_string path, uintfptr_t entryaddr)
{
struct pmcstat_image *image;
@@ -1506,7 +1239,7 @@ pmcstat_process_exec(struct pmcstat_process *pp,
}
if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
- pmcstat_image_determine_type(image, a);
+ pmcstat_image_determine_type(image);
assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN);
@@ -1514,12 +1247,12 @@ pmcstat_process_exec(struct pmcstat_process *pp,
case PMCSTAT_IMAGE_ELF32:
case PMCSTAT_IMAGE_ELF64:
pmcstat_stats.ps_exec_elf++;
- pmcstat_process_elf_exec(pp, image, entryaddr, a);
+ pmcstat_process_elf_exec(pp, image, entryaddr);
break;
case PMCSTAT_IMAGE_AOUT:
pmcstat_stats.ps_exec_aout++;
- pmcstat_process_aout_exec(pp, image, entryaddr, a);
+ pmcstat_process_aout_exec(pp, image, entryaddr);
break;
case PMCSTAT_IMAGE_INDETERMINABLE:
@@ -1537,7 +1270,7 @@ pmcstat_process_exec(struct pmcstat_process *pp,
* Find the map entry associated with process 'p' at PC value 'pc'.
*/
-static struct pmcstat_pcmap *
+struct pmcstat_pcmap *
pmcstat_process_find_map(struct pmcstat_process *p, uintfptr_t pc)
{
struct pmcstat_pcmap *ppm;
@@ -1552,444 +1285,36 @@ pmcstat_process_find_map(struct pmcstat_process *p, uintfptr_t pc)
return (NULL);
}
-static struct pmcstat_cgnode *
-pmcstat_cgnode_allocate(struct pmcstat_image *image, uintfptr_t pc)
-{
- struct pmcstat_cgnode *cg;
-
- if ((cg = malloc(sizeof(*cg))) == NULL)
- err(EX_OSERR, "ERROR: Cannot allocate callgraph node");
-
- cg->pcg_image = image;
- cg->pcg_func = pc;
-
- cg->pcg_count = 0;
- cg->pcg_nchildren = 0;
- LIST_INIT(&cg->pcg_children);
-
- return (cg);
-}
-
-/*
- * Free a node and its children.
- */
-static void
-pmcstat_cgnode_free(struct pmcstat_cgnode *cg)
-{
- struct pmcstat_cgnode *cgc, *cgtmp;
-
- LIST_FOREACH_SAFE(cgc, &cg->pcg_children, pcg_sibling, cgtmp)
- pmcstat_cgnode_free(cgc);
- free(cg);
-}
-
-/*
- * Look for a callgraph node associated with pmc `pmcid' in the global
- * hash table that corresponds to the given `pc' value in the process
- * `pp'.
- */
-static struct pmcstat_cgnode *
-pmcstat_cgnode_hash_lookup_pc(struct pmcstat_process *pp, uint32_t pmcid,
- uintfptr_t pc, int usermode)
-{
- struct pmcstat_pcmap *ppm;
- struct pmcstat_symbol *sym;
- struct pmcstat_image *image;
- struct pmcstat_cgnode *cg;
- struct pmcstat_cgnode_hash *h;
- uintfptr_t loadaddress;
- unsigned int i, hash;
-
- ppm = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, pc);
- if (ppm == NULL)
- return (NULL);
-
- image = ppm->ppm_image;
-
- loadaddress = ppm->ppm_lowpc + image->pi_vaddr - image->pi_start;
- pc -= loadaddress; /* Convert to an offset in the image. */
-
- /*
- * Try determine the function at this offset. If we can't
- * find a function round leave the `pc' value alone.
- */
- if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
- pc = sym->ps_start;
-
- for (hash = i = 0; i < sizeof(uintfptr_t); i++)
- hash += (pc >> i) & 0xFF;
-
- hash &= PMCSTAT_HASH_MASK;
-
- cg = NULL;
- LIST_FOREACH(h, &pmcstat_cgnode_hash[hash], pch_next)
- {
- if (h->pch_pmcid != pmcid)
- continue;
-
- cg = h->pch_cgnode;
-
- assert(cg != NULL);
-
- if (cg->pcg_image == image && cg->pcg_func == pc)
- return (cg);
- }
-
- /*
- * We haven't seen this (pmcid, pc) tuple yet, so allocate a
- * new callgraph node and a new hash table entry for it.
- */
- cg = pmcstat_cgnode_allocate(image, pc);
- if ((h = malloc(sizeof(*h))) == NULL)
- err(EX_OSERR, "ERROR: Could not allocate callgraph node");
-
- h->pch_pmcid = pmcid;
- h->pch_cgnode = cg;
- LIST_INSERT_HEAD(&pmcstat_cgnode_hash[hash], h, pch_next);
-
- pmcstat_cgnode_hash_count++;
-
- return (cg);
-}
-
-/*
- * Compare two callgraph nodes for sorting.
- */
-static int
-pmcstat_cgnode_compare(const void *a, const void *b)
-{
- const struct pmcstat_cgnode *const *pcg1, *const *pcg2, *cg1, *cg2;
-
- pcg1 = (const struct pmcstat_cgnode *const *) a;
- cg1 = *pcg1;
- pcg2 = (const struct pmcstat_cgnode *const *) b;
- cg2 = *pcg2;
-
- /* Sort in reverse order */
- if (cg1->pcg_count < cg2->pcg_count)
- return (1);
- if (cg1->pcg_count > cg2->pcg_count)
- return (-1);
- return (0);
-}
-
-/*
- * Find (allocating if a needed) a callgraph node in the given
- * parent with the same (image, pcoffset) pair.
- */
-
-static struct pmcstat_cgnode *
-pmcstat_cgnode_find(struct pmcstat_cgnode *parent, struct pmcstat_image *image,
- uintfptr_t pcoffset)
-{
- struct pmcstat_cgnode *child;
-
- LIST_FOREACH(child, &parent->pcg_children, pcg_sibling) {
- if (child->pcg_image == image &&
- child->pcg_func == pcoffset)
- return (child);
- }
-
- /*
- * Allocate a new structure.
- */
-
- child = pmcstat_cgnode_allocate(image, pcoffset);
-
- /*
- * Link it into the parent.
- */
- LIST_INSERT_HEAD(&parent->pcg_children, child, pcg_sibling);
- parent->pcg_nchildren++;
-
- return (child);
-}
-
-/*
- * Print one callgraph node. The output format is:
- *
- * indentation %(parent's samples) #nsamples function@object
- */
-static void
-pmcstat_cgnode_print(struct pmcstat_args *a, struct pmcstat_cgnode *cg,
- int depth, uint32_t total)
-{
- uint32_t n;
- const char *space;
- struct pmcstat_symbol *sym;
- struct pmcstat_cgnode **sortbuffer, **cgn, *pcg;
-
- space = " ";
-
- if (depth > 0)
- (void) fprintf(a->pa_graphfile, "%*s", depth, space);
-
- if (cg->pcg_count == total)
- (void) fprintf(a->pa_graphfile, "100.0%% ");
- else
- (void) fprintf(a->pa_graphfile, "%05.2f%% ",
- 100.0 * cg->pcg_count / total);
-
- n = fprintf(a->pa_graphfile, " [%u] ", cg->pcg_count);
-
- /* #samples is a 12 character wide field. */
- if (n < 12)
- (void) fprintf(a->pa_graphfile, "%*s", 12 - n, space);
-
- if (depth > 0)
- (void) fprintf(a->pa_graphfile, "%*s", depth, space);
-
- sym = pmcstat_symbol_search(cg->pcg_image, cg->pcg_func);
- if (sym)
- (void) fprintf(a->pa_graphfile, "%s",
- pmcstat_string_unintern(sym->ps_name));
- else
- (void) fprintf(a->pa_graphfile, "%p",
- (void *) (cg->pcg_image->pi_vaddr + cg->pcg_func));
-
- if (pmcstat_previous_filename_printed !=
- cg->pcg_image->pi_fullpath) {
- pmcstat_previous_filename_printed = cg->pcg_image->pi_fullpath;
- (void) fprintf(a->pa_graphfile, " @ %s\n",
- pmcstat_string_unintern(
- pmcstat_previous_filename_printed));
- } else
- (void) fprintf(a->pa_graphfile, "\n");
-
- if (cg->pcg_nchildren == 0)
- return;
-
- if ((sortbuffer = (struct pmcstat_cgnode **)
- malloc(sizeof(struct pmcstat_cgnode *) *
- cg->pcg_nchildren)) == NULL)
- err(EX_OSERR, "ERROR: Cannot print callgraph");
- cgn = sortbuffer;
-
- LIST_FOREACH(pcg, &cg->pcg_children, pcg_sibling)
- *cgn++ = pcg;
-
- assert(cgn - sortbuffer == (int) cg->pcg_nchildren);
-
- qsort(sortbuffer, cg->pcg_nchildren, sizeof(struct pmcstat_cgnode *),
- pmcstat_cgnode_compare);
-
- for (cgn = sortbuffer, n = 0; n < cg->pcg_nchildren; n++, cgn++)
- pmcstat_cgnode_print(a, *cgn, depth+1, cg->pcg_count);
-
- free(sortbuffer);
-}
-
-/*
- * Record a callchain.
- */
-
-static void
-pmcstat_record_callchain(struct pmcstat_process *pp, uint32_t pmcid,
- uint32_t nsamples, uintfptr_t *cc, int usermode, struct pmcstat_args *a)
-{
- uintfptr_t pc, loadaddress;
- uint32_t n;
- struct pmcstat_image *image;
- struct pmcstat_pcmap *ppm;
- struct pmcstat_symbol *sym;
- struct pmcstat_cgnode *parent, *child;
-
- /*
- * Find the callgraph node recorded in the global hash table
- * for this (pmcid, pc).
- */
-
- pc = cc[0];
- parent = pmcstat_cgnode_hash_lookup_pc(pp, pmcid, pc, usermode);
- if (parent == NULL) {
- pmcstat_stats.ps_callchain_dubious_frames++;
- return;
- }
-
- parent->pcg_count++;
-
- /*
- * For each return address in the call chain record, subject
- * to the maximum depth desired.
- * - Find the image associated with the sample. Stop if there
- * there is no valid image at that address.
- * - Find the function that overlaps the return address.
- * - If found: use the start address of the function.
- * If not found (say an object's symbol table is not present or
- * is incomplete), round down to th gprof bucket granularity.
- * - Convert return virtual address to an offset in the image.
- * - Look for a child with the same {offset,image} tuple,
- * inserting one if needed.
- * - Increment the count of occurrences of the child.
- */
-
- for (n = 1; n < (uint32_t) a->pa_graphdepth && n < nsamples; n++,
- parent = child) {
- pc = cc[n];
-
- ppm = pmcstat_process_find_map(usermode ? pp :
- pmcstat_kernproc, pc);
- if (ppm == NULL)
- return;
-
- image = ppm->ppm_image;
- loadaddress = ppm->ppm_lowpc + image->pi_vaddr -
- image->pi_start;
- pc -= loadaddress;
-
- if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
- pc = sym->ps_start;
-
- child = pmcstat_cgnode_find(parent, image, pc);
- child->pcg_count++;
- }
-}
-
-/*
- * Printing a callgraph for a PMC.
- */
-static void
-pmcstat_callgraph_print_for_pmcid(struct pmcstat_args *a,
- struct pmcstat_pmcrecord *pmcr)
-{
- int n, nentries;
- uint32_t nsamples, pmcid;
- struct pmcstat_cgnode **sortbuffer, **cgn;
- struct pmcstat_cgnode_hash *pch;
-
- /*
- * We pull out all callgraph nodes in the top-level hash table
- * with a matching PMC id. We then sort these based on the
- * frequency of occurrence. Each callgraph node is then
- * printed.
- */
-
- nsamples = 0;
- pmcid = pmcr->pr_pmcid;
- if ((sortbuffer = (struct pmcstat_cgnode **)
- malloc(sizeof(struct pmcstat_cgnode *) *
- pmcstat_cgnode_hash_count)) == NULL)
- err(EX_OSERR, "ERROR: Cannot sort callgraph");
- cgn = sortbuffer;
-
- memset(sortbuffer, 0xFF, pmcstat_cgnode_hash_count *
- sizeof(struct pmcstat_cgnode **));
-
- for (n = 0; n < PMCSTAT_NHASH; n++)
- LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
- if (pch->pch_pmcid == pmcid) {
- nsamples += pch->pch_cgnode->pcg_count;
- *cgn++ = pch->pch_cgnode;
- }
-
- nentries = cgn - sortbuffer;
- assert(nentries <= pmcstat_cgnode_hash_count);
-
- if (nentries == 0)
- return;
-
- qsort(sortbuffer, nentries, sizeof(struct pmcstat_cgnode *),
- pmcstat_cgnode_compare);
-
- (void) fprintf(a->pa_graphfile,
- "@ %s [%u samples]\n\n",
- pmcstat_string_unintern(pmcr->pr_pmcname),
- nsamples);
-
- for (cgn = sortbuffer, n = 0; n < nentries; n++, cgn++) {
- pmcstat_previous_filename_printed = NULL;
- pmcstat_cgnode_print(a, *cgn, 0, nsamples);
- (void) fprintf(a->pa_graphfile, "\n");
- }
-
- free(sortbuffer);
-}
-
-/*
- * Print out callgraphs.
- */
-
-static void
-pmcstat_callgraph_print(struct pmcstat_args *a)
-{
- struct pmcstat_pmcrecord *pmcr;
-
- LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
- pmcstat_callgraph_print_for_pmcid(a, pmcr);
-}
-
-static void
-pmcstat_cgnode_do_gmon_arcs(struct pmcstat_cgnode *cg, pmc_id_t pmcid)
-{
- struct pmcstat_cgnode *cgc;
-
- /*
- * Look for child nodes that belong to the same image.
- */
-
- LIST_FOREACH(cgc, &cg->pcg_children, pcg_sibling) {
- if (cgc->pcg_image == cg->pcg_image)
- pmcstat_gmon_append_arc(cg->pcg_image, pmcid,
- cgc->pcg_func, cg->pcg_func, cgc->pcg_count);
- if (cgc->pcg_nchildren > 0)
- pmcstat_cgnode_do_gmon_arcs(cgc, pmcid);
- }
-}
-
-static void
-pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmc_id_t pmcid)
-{
- int n;
- struct pmcstat_cgnode_hash *pch;
-
- for (n = 0; n < PMCSTAT_NHASH; n++)
- LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
- if (pch->pch_pmcid == pmcid &&
- pch->pch_cgnode->pcg_nchildren > 1)
- pmcstat_cgnode_do_gmon_arcs(pch->pch_cgnode,
- pmcid);
-}
-
-
-static void
-pmcstat_callgraph_do_gmon_arcs(void)
-{
- struct pmcstat_pmcrecord *pmcr;
-
- LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
- pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmcr->pr_pmcid);
-}
-
/*
* Convert a hwpmc(4) log to profile information. A system-wide
* callgraph is generated if FLAG_DO_CALLGRAPHS is set. gmon.out
* files usable by gprof(1) are created if FLAG_DO_GPROF is set.
*/
static int
-pmcstat_analyze_log(struct pmcstat_args *a)
+pmcstat_analyze_log(void)
{
uint32_t cpu, cpuflags;
- uintfptr_t pc, newpc;
+ uintfptr_t pc;
pid_t pid;
struct pmcstat_image *image;
- struct pmcstat_symbol *sym;
struct pmcstat_process *pp, *ppnew;
struct pmcstat_pcmap *ppm, *ppmtmp;
struct pmclog_ev ev;
+ struct pmcstat_pmcrecord *pmcr;
pmcstat_interned_string image_path;
- assert(a->pa_flags & FLAG_DO_ANALYSIS);
+ assert(args.pa_flags & FLAG_DO_ANALYSIS);
if (elf_version(EV_CURRENT) == EV_NONE)
err(EX_UNAVAILABLE, "Elf library intialization failed");
- while (pmclog_read(a->pa_logparser, &ev) == 0) {
+ while (pmclog_read(args.pa_logparser, &ev) == 0) {
assert(ev.pl_state == PMCLOG_OK);
switch (ev.pl_type) {
case PMCLOG_TYPE_INITIALIZE:
if ((ev.pl_u.pl_i.pl_version & 0xFF000000) !=
- PMC_VERSION_MAJOR << 24 && a->pa_verbosity > 0)
+ PMC_VERSION_MAJOR << 24 && args.pa_verbosity > 0)
warnx("WARNING: Log version 0x%x does not "
"match compiled version 0x%x.",
ev.pl_u.pl_i.pl_version,
@@ -2019,7 +1344,7 @@ pmcstat_analyze_log(struct pmcstat_args *a)
pl_pathname);
image = pmcstat_image_from_path(image_path, pid == -1);
if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
- pmcstat_image_determine_type(image, a);
+ pmcstat_image_determine_type(image);
if (image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE)
pmcstat_image_link(pp, image,
ev.pl_u.pl_mi.pl_start);
@@ -2059,16 +1384,23 @@ pmcstat_analyze_log(struct pmcstat_args *a)
pc = ev.pl_u.pl_s.pl_pc;
pp = pmcstat_process_lookup(ev.pl_u.pl_s.pl_pid,
PMCSTAT_ALLOCATE);
- if ((ppm = pmcstat_process_find_map(pp, pc)) == NULL &&
- (ppm = pmcstat_process_find_map(pmcstat_kernproc,
- pc)) == NULL) { /* unknown process,offset pair */
- pmcstat_stats.ps_samples_unknown_offset++;
- break;
- }
- pmcstat_image_increment_bucket(ppm, pc,
- ev.pl_u.pl_s.pl_pmcid, a);
+ /* Get PMC record. */
+ pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_s.pl_pmcid);
+ assert(pmcr != NULL);
+ /*
+ * Call the plugins processing
+ * TODO: move pmcstat_process_find_map inside plugins
+ */
+
+ if (plugins[args.pa_pplugin].pl_process != NULL)
+ plugins[args.pa_pplugin].pl_process(
+ pp, pmcr, 1, &pc,
+ pmcstat_process_find_map(pp, pc) != NULL, 0);
+ plugins[args.pa_plugin].pl_process(
+ pp, pmcr, 1, &pc,
+ pmcstat_process_find_map(pp, pc) != NULL, 0);
break;
case PMCLOG_TYPE_CALLCHAIN:
@@ -2078,7 +1410,7 @@ pmcstat_analyze_log(struct pmcstat_args *a)
cpu = PMC_CALLCHAIN_CPUFLAGS_TO_CPU(cpuflags);
/* Filter on the CPU id. */
- if ((a->pa_cpumask & (1 << cpu)) == 0) {
+ if ((args.pa_cpumask & (1 << cpu)) == 0) {
pmcstat_stats.ps_samples_skipped++;
break;
}
@@ -2086,45 +1418,27 @@ pmcstat_analyze_log(struct pmcstat_args *a)
pp = pmcstat_process_lookup(ev.pl_u.pl_cc.pl_pid,
PMCSTAT_ALLOCATE);
- if ((a->pa_flags & FLAG_WANTS_MAPPINGS) == 0)
- pmcstat_record_callchain(pp,
- ev.pl_u.pl_cc.pl_pmcid,
- ev.pl_u.pl_cc.pl_npc, ev.pl_u.pl_cc.pl_pc,
- PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags), a);
-
- if ((a->pa_flags &
- (FLAG_DO_GPROF | FLAG_WANTS_MAPPINGS)) == 0)
- break;
-
- pc = ev.pl_u.pl_cc.pl_pc[0];
- if (PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags) == 0)
- pp = pmcstat_kernproc;
- ppm = pmcstat_process_find_map(pp, pc);
- if (ppm == NULL) {
-
- /* Unknown offset. */
- pmcstat_stats.ps_samples_unknown_offset++;
- break;
- }
- if (a->pa_flags & FLAG_WANTS_MAPPINGS) {
- image = ppm->ppm_image;
- newpc = pc - (ppm->ppm_lowpc +
- (image->pi_vaddr - image->pi_start));
- sym = pmcstat_symbol_search(image, newpc);
- if (sym == NULL)
- break;
- fprintf(a->pa_graphfile, "%p %s 0x%jx 0x%jx\n",
- (void *)pc,
- pmcstat_string_unintern(sym->ps_name),
- (uintmax_t)(sym->ps_start +
- image->pi_vaddr), (uintmax_t)(sym->ps_end +
- image->pi_vaddr));
- break;
- }
+ /* Get PMC record. */
+ pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_cc.pl_pmcid);
+ assert(pmcr != NULL);
- pmcstat_image_increment_bucket(ppm, pc,
- ev.pl_u.pl_cc.pl_pmcid, a);
+ /*
+ * Call the plugins processing
+ */
+ if (plugins[args.pa_pplugin].pl_process != NULL)
+ plugins[args.pa_pplugin].pl_process(
+ pp, pmcr,
+ ev.pl_u.pl_cc.pl_npc,
+ ev.pl_u.pl_cc.pl_pc,
+ PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags),
+ cpu);
+ plugins[args.pa_plugin].pl_process(
+ pp, pmcr,
+ ev.pl_u.pl_cc.pl_npc,
+ ev.pl_u.pl_cc.pl_pc,
+ PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags),
+ cpu);
break;
case PMCLOG_TYPE_PMCALLOCATE:
@@ -2133,7 +1447,7 @@ pmcstat_analyze_log(struct pmcstat_args *a)
* PMC and its name.
*/
pmcstat_pmcid_add(ev.pl_u.pl_a.pl_pmcid,
- pmcstat_string_intern(ev.pl_u.pl_a.pl_evname), a);
+ pmcstat_string_intern(ev.pl_u.pl_a.pl_evname));
break;
case PMCLOG_TYPE_PROCEXEC:
@@ -2156,7 +1470,7 @@ pmcstat_analyze_log(struct pmcstat_args *a)
ev.pl_u.pl_x.pl_pathname);
assert(image_path != NULL);
pmcstat_process_exec(pp, image_path,
- ev.pl_u.pl_x.pl_entryaddr, a);
+ ev.pl_u.pl_x.pl_entryaddr);
break;
case PMCLOG_TYPE_PROCEXIT:
@@ -2224,16 +1538,16 @@ pmcstat_analyze_log(struct pmcstat_args *a)
*/
static int
-pmcstat_print_log(struct pmcstat_args *a)
+pmcstat_print_log(void)
{
struct pmclog_ev ev;
uint32_t npc;
- while (pmclog_read(a->pa_logparser, &ev) == 0) {
+ while (pmclog_read(args.pa_logparser, &ev) == 0) {
assert(ev.pl_state == PMCLOG_OK);
switch (ev.pl_type) {
case PMCLOG_TYPE_CALLCHAIN:
- PMCSTAT_PRINT_ENTRY(a, "callchain",
+ PMCSTAT_PRINT_ENTRY("callchain",
"%d 0x%x %d %d %c", ev.pl_u.pl_cc.pl_pid,
ev.pl_u.pl_cc.pl_pmcid,
PMC_CALLCHAIN_CPUFLAGS_TO_CPU(ev.pl_u.pl_cc. \
@@ -2241,95 +1555,95 @@ pmcstat_print_log(struct pmcstat_args *a)
PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(ev.pl_u.pl_cc.\
pl_cpuflags) ? 'u' : 's');
for (npc = 0; npc < ev.pl_u.pl_cc.pl_npc; npc++)
- PMCSTAT_PRINT_ENTRY(a, "...", "%p",
+ PMCSTAT_PRINT_ENTRY("...", "%p",
(void *) ev.pl_u.pl_cc.pl_pc[npc]);
break;
case PMCLOG_TYPE_CLOSELOG:
- PMCSTAT_PRINT_ENTRY(a,"closelog",);
+ PMCSTAT_PRINT_ENTRY("closelog",);
break;
case PMCLOG_TYPE_DROPNOTIFY:
- PMCSTAT_PRINT_ENTRY(a,"drop",);
+ PMCSTAT_PRINT_ENTRY("drop",);
break;
case PMCLOG_TYPE_INITIALIZE:
- PMCSTAT_PRINT_ENTRY(a,"initlog","0x%x \"%s\"",
+ PMCSTAT_PRINT_ENTRY("initlog","0x%x \"%s\"",
ev.pl_u.pl_i.pl_version,
pmc_name_of_cputype(ev.pl_u.pl_i.pl_arch));
if ((ev.pl_u.pl_i.pl_version & 0xFF000000) !=
- PMC_VERSION_MAJOR << 24 && a->pa_verbosity > 0)
+ PMC_VERSION_MAJOR << 24 && args.pa_verbosity > 0)
warnx("WARNING: Log version 0x%x != expected "
"version 0x%x.", ev.pl_u.pl_i.pl_version,
PMC_VERSION);
break;
case PMCLOG_TYPE_MAP_IN:
- PMCSTAT_PRINT_ENTRY(a,"map-in","%d %p \"%s\"",
+ PMCSTAT_PRINT_ENTRY("map-in","%d %p \"%s\"",
ev.pl_u.pl_mi.pl_pid,
(void *) ev.pl_u.pl_mi.pl_start,
ev.pl_u.pl_mi.pl_pathname);
break;
case PMCLOG_TYPE_MAP_OUT:
- PMCSTAT_PRINT_ENTRY(a,"map-out","%d %p %p",
+ PMCSTAT_PRINT_ENTRY("map-out","%d %p %p",
ev.pl_u.pl_mo.pl_pid,
(void *) ev.pl_u.pl_mo.pl_start,
(void *) ev.pl_u.pl_mo.pl_end);
break;
case PMCLOG_TYPE_PCSAMPLE:
- PMCSTAT_PRINT_ENTRY(a,"sample","0x%x %d %p %c",
+ PMCSTAT_PRINT_ENTRY("sample","0x%x %d %p %c",
ev.pl_u.pl_s.pl_pmcid,
ev.pl_u.pl_s.pl_pid,
(void *) ev.pl_u.pl_s.pl_pc,
ev.pl_u.pl_s.pl_usermode ? 'u' : 's');
break;
case PMCLOG_TYPE_PMCALLOCATE:
- PMCSTAT_PRINT_ENTRY(a,"allocate","0x%x \"%s\" 0x%x",
+ PMCSTAT_PRINT_ENTRY("allocate","0x%x \"%s\" 0x%x",
ev.pl_u.pl_a.pl_pmcid,
ev.pl_u.pl_a.pl_evname,
ev.pl_u.pl_a.pl_flags);
break;
case PMCLOG_TYPE_PMCATTACH:
- PMCSTAT_PRINT_ENTRY(a,"attach","0x%x %d \"%s\"",
+ PMCSTAT_PRINT_ENTRY("attach","0x%x %d \"%s\"",
ev.pl_u.pl_t.pl_pmcid,
ev.pl_u.pl_t.pl_pid,
ev.pl_u.pl_t.pl_pathname);
break;
case PMCLOG_TYPE_PMCDETACH:
- PMCSTAT_PRINT_ENTRY(a,"detach","0x%x %d",
+ PMCSTAT_PRINT_ENTRY("detach","0x%x %d",
ev.pl_u.pl_d.pl_pmcid,
ev.pl_u.pl_d.pl_pid);
break;
case PMCLOG_TYPE_PROCCSW:
- PMCSTAT_PRINT_ENTRY(a,"cswval","0x%x %d %jd",
+ PMCSTAT_PRINT_ENTRY("cswval","0x%x %d %jd",
ev.pl_u.pl_c.pl_pmcid,
ev.pl_u.pl_c.pl_pid,
ev.pl_u.pl_c.pl_value);
break;
case PMCLOG_TYPE_PROCEXEC:
- PMCSTAT_PRINT_ENTRY(a,"exec","0x%x %d %p \"%s\"",
+ PMCSTAT_PRINT_ENTRY("exec","0x%x %d %p \"%s\"",
ev.pl_u.pl_x.pl_pmcid,
ev.pl_u.pl_x.pl_pid,
(void *) ev.pl_u.pl_x.pl_entryaddr,
ev.pl_u.pl_x.pl_pathname);
break;
case PMCLOG_TYPE_PROCEXIT:
- PMCSTAT_PRINT_ENTRY(a,"exitval","0x%x %d %jd",
+ PMCSTAT_PRINT_ENTRY("exitval","0x%x %d %jd",
ev.pl_u.pl_e.pl_pmcid,
ev.pl_u.pl_e.pl_pid,
ev.pl_u.pl_e.pl_value);
break;
case PMCLOG_TYPE_PROCFORK:
- PMCSTAT_PRINT_ENTRY(a,"fork","%d %d",
+ PMCSTAT_PRINT_ENTRY("fork","%d %d",
ev.pl_u.pl_f.pl_oldpid,
ev.pl_u.pl_f.pl_newpid);
break;
case PMCLOG_TYPE_USERDATA:
- PMCSTAT_PRINT_ENTRY(a,"userdata","0x%x",
+ PMCSTAT_PRINT_ENTRY("userdata","0x%x",
ev.pl_u.pl_u.pl_userdata);
break;
case PMCLOG_TYPE_SYSEXIT:
- PMCSTAT_PRINT_ENTRY(a,"exit","%d",
+ PMCSTAT_PRINT_ENTRY("exit","%d",
ev.pl_u.pl_se.pl_pid);
break;
default:
- fprintf(a->pa_printfile, "unknown event (type %d).\n",
+ fprintf(args.pa_printfile, "unknown event (type %d).\n",
ev.pl_type);
}
}
@@ -2354,13 +1668,13 @@ pmcstat_print_log(struct pmcstat_args *a)
*/
int
-pmcstat_close_log(struct pmcstat_args *a)
+pmcstat_close_log(void)
{
if (pmc_flush_logfile() < 0 ||
pmc_configure_logfile(-1) < 0)
err(EX_OSERR, "ERROR: logging failed");
- a->pa_flags &= ~(FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE);
- return (a->pa_flags & FLAG_HAS_PIPE ? PMCSTAT_EXITING :
+ args.pa_flags &= ~(FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE);
+ return (args.pa_flags & FLAG_HAS_PIPE ? PMCSTAT_EXITING :
PMCSTAT_FINISHED);
}
@@ -2456,17 +1770,208 @@ pmcstat_open_log(const char *path, int mode)
*/
int
-pmcstat_process_log(struct pmcstat_args *a)
+pmcstat_process_log(void)
{
/*
* If analysis has not been asked for, just print the log to
* the current output file.
*/
- if (a->pa_flags & FLAG_DO_PRINT)
- return (pmcstat_print_log(a));
+ if (args.pa_flags & FLAG_DO_PRINT)
+ return (pmcstat_print_log());
else
- return (pmcstat_analyze_log(a));
+ return (pmcstat_analyze_log());
+}
+
+/*
+ * Refresh top display.
+ */
+
+static void
+pmcstat_refresh_top(void)
+{
+ char pmcname[40];
+
+ /* If in pause mode do not refresh display. */
+ if (pmcstat_pause)
+ return;
+
+ /* Format PMC name. */
+ if (pmcstat_mergepmc)
+ snprintf(pmcname, sizeof(pmcname), "[%s]",
+ pmcstat_pmcindex_to_name(pmcstat_pmcinfilter));
+ else
+ snprintf(pmcname, sizeof(pmcname), "%s.%d",
+ pmcstat_pmcindex_to_name(pmcstat_pmcinfilter),
+ pmcstat_pmcinfilter);
+
+ PMCSTAT_PRINTBEGIN();
+ PMCSTAT_PRINTW("PMC: %s Samples: %u processed, %u invalid\n\n",
+ pmcname,
+ pmcstat_stats.ps_samples_total,
+ pmcstat_stats.ps_samples_unknown_offset +
+ pmcstat_stats.ps_samples_indeterminable +
+ pmcstat_stats.ps_callchain_dubious_frames);
+ if (plugins[args.pa_plugin].pl_topdisplay != NULL)
+ plugins[args.pa_plugin].pl_topdisplay();
+ PMCSTAT_PRINTEND();
+}
+
+/*
+ * Find the next pmc index to display.
+ */
+
+static void
+pmcstat_changefilter(void)
+{
+ int pmcin;
+ struct pmcstat_pmcrecord *pmcr;
+
+ /*
+ * Find the next merge target.
+ */
+ if (pmcstat_mergepmc) {
+ pmcin = pmcstat_pmcinfilter;
+
+ do {
+ pmcr = pmcstat_pmcindex_to_pmcr(pmcstat_pmcinfilter);
+ if (pmcr == pmcr->pr_merge)
+ break;
+
+ pmcstat_pmcinfilter++;
+ if (pmcstat_pmcinfilter >= pmcstat_npmcs)
+ pmcstat_pmcinfilter = 0;
+
+ } while (pmcstat_pmcinfilter != pmcin);
+ }
+}
+
+/*
+ * Top mode keypress.
+ */
+
+int
+pmcstat_keypress_log(void)
+{
+ int c, ret = 0;
+ WINDOW *w;
+
+ w = newwin(1, 0, 1, 0);
+ c = wgetch(w);
+ wprintw(w, "Key: %c => ", c);
+ switch (c) {
+ case 'c':
+ wprintw(w, "enter mode 'd' or 'a' => ");
+ c = wgetch(w);
+ if (c == 'd') {
+ args.pa_topmode = PMCSTAT_TOP_DELTA;
+ wprintw(w, "switching to delta mode");
+ } else {
+ args.pa_topmode = PMCSTAT_TOP_ACCUM;
+ wprintw(w, "switching to accumulation mode");
+ }
+ break;
+ case 'm':
+ pmcstat_mergepmc = !pmcstat_mergepmc;
+ /*
+ * Changing merge state require data reset.
+ */
+ if (plugins[args.pa_plugin].pl_shutdown != NULL)
+ plugins[args.pa_plugin].pl_shutdown(NULL);
+ bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
+ if (plugins[args.pa_plugin].pl_init != NULL)
+ plugins[args.pa_plugin].pl_init();
+
+ /* Update filter to be on a merge target. */
+ pmcstat_changefilter();
+ wprintw(w, "merge PMC %s", pmcstat_mergepmc ? "on" : "off");
+ break;
+ case 'n':
+ /* Close current plugin. */
+ if (plugins[args.pa_plugin].pl_shutdown != NULL)
+ plugins[args.pa_plugin].pl_shutdown(NULL);
+
+ /* Find next top display available. */
+ do {
+ args.pa_plugin++;
+ if (plugins[args.pa_plugin].pl_name == NULL)
+ args.pa_plugin = 0;
+ } while (plugins[args.pa_plugin].pl_topdisplay == NULL);
+
+ /* Open new plugin. */
+ bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
+ if (plugins[args.pa_plugin].pl_init != NULL)
+ plugins[args.pa_plugin].pl_init();
+ wprintw(w, "switching to plugin %s",
+ plugins[args.pa_plugin].pl_name);
+ break;
+ case 'p':
+ pmcstat_pmcinfilter++;
+ if (pmcstat_pmcinfilter >= pmcstat_npmcs)
+ pmcstat_pmcinfilter = 0;
+ pmcstat_changefilter();
+ wprintw(w, "switching to PMC %s.%d",
+ pmcstat_pmcindex_to_name(pmcstat_pmcinfilter),
+ pmcstat_pmcinfilter);
+ break;
+ case ' ':
+ pmcstat_pause = !pmcstat_pause;
+ if (pmcstat_pause)
+ wprintw(w, "pause => press space again to continue");
+ break;
+ case 'q':
+ wprintw(w, "exiting...");
+ ret = 1;
+ default:
+ if (plugins[args.pa_plugin].pl_topkeypress != NULL)
+ if (plugins[args.pa_plugin].pl_topkeypress(c, w))
+ ret = 1;
+ }
+
+ wrefresh(w);
+ delwin(w);
+ return ret;
+}
+
+
+/*
+ * Top mode display.
+ */
+
+void
+pmcstat_display_log(void)
+{
+
+ pmcstat_refresh_top();
+
+ /* Reset everythings if delta mode. */
+ if (args.pa_topmode == PMCSTAT_TOP_DELTA) {
+ if (plugins[args.pa_plugin].pl_shutdown != NULL)
+ plugins[args.pa_plugin].pl_shutdown(NULL);
+ bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
+ if (plugins[args.pa_plugin].pl_init != NULL)
+ plugins[args.pa_plugin].pl_init();
+ }
+
+}
+
+/*
+ * Configure a plugins.
+ */
+
+void
+pmcstat_pluginconfigure_log(char *opt)
+{
+
+ if (strncmp(opt, "threshold=", 10) == 0) {
+ pmcstat_threshold = atof(opt+10);
+ } else {
+ if (plugins[args.pa_plugin].pl_configure != NULL) {
+ if (!plugins[args.pa_plugin].pl_configure(opt))
+ err(EX_USAGE,
+ "ERROR: unknown option <%s>.", opt);
+ }
+ }
}
/*
@@ -2474,12 +1979,10 @@ pmcstat_process_log(struct pmcstat_args *a)
*/
void
-pmcstat_initialize_logging(struct pmcstat_args *a)
+pmcstat_initialize_logging(void)
{
int i;
- (void) a;
-
/* use a convenient format for 'ldd' output */
if (setenv("LD_TRACE_LOADED_OBJECTS_FMT1","%o \"%p\" %x\n",1) != 0)
err(EX_OSERR, "ERROR: Cannot setenv");
@@ -2499,6 +2002,21 @@ pmcstat_initialize_logging(struct pmcstat_args *a)
if ((pmcstat_kernproc = pmcstat_process_lookup((pid_t) -1,
PMCSTAT_ALLOCATE)) == NULL)
err(EX_OSERR, "ERROR: Cannot initialize logging");
+
+ /* PMC count. */
+ pmcstat_npmcs = 0;
+
+ /* Merge PMC with same name. */
+ pmcstat_mergepmc = args.pa_mergepmc;
+
+ /*
+ * Initialize plugins
+ */
+
+ if (plugins[args.pa_pplugin].pl_init != NULL)
+ plugins[args.pa_pplugin].pl_init();
+ if (plugins[args.pa_plugin].pl_init != NULL)
+ plugins[args.pa_plugin].pl_init();
}
/*
@@ -2506,99 +2024,57 @@ pmcstat_initialize_logging(struct pmcstat_args *a)
*/
void
-pmcstat_shutdown_logging(struct pmcstat_args *a)
+pmcstat_shutdown_logging(void)
{
int i;
FILE *mf;
- struct pmcstat_gmonfile *pgf, *pgftmp;
struct pmcstat_image *pi, *pitmp;
struct pmcstat_process *pp, *pptmp;
- struct pmcstat_cgnode_hash *pch, *pchtmp;
+ struct pmcstat_pcmap *ppm, *ppmtmp;
/* determine where to send the map file */
mf = NULL;
- if (a->pa_mapfilename != NULL)
- mf = (strcmp(a->pa_mapfilename, "-") == 0) ?
- a->pa_printfile : fopen(a->pa_mapfilename, "w");
+ if (args.pa_mapfilename != NULL)
+ mf = (strcmp(args.pa_mapfilename, "-") == 0) ?
+ args.pa_printfile : fopen(args.pa_mapfilename, "w");
- if (mf == NULL && a->pa_flags & FLAG_DO_GPROF &&
- a->pa_verbosity >= 2)
- mf = a->pa_printfile;
+ if (mf == NULL && args.pa_flags & FLAG_DO_GPROF &&
+ args.pa_verbosity >= 2)
+ mf = args.pa_printfile;
if (mf)
(void) fprintf(mf, "MAP:\n");
-
- if (a->pa_flags & FLAG_DO_CALLGRAPHS)
- pmcstat_callgraph_print(a);
-
- /*
- * Sync back all gprof flat profile data.
- */
- for (i = 0; i < PMCSTAT_NHASH; i++) {
- LIST_FOREACH(pi, &pmcstat_image_hash[i], pi_next) {
- if (mf)
- (void) fprintf(mf, " \"%s\" => \"%s\"",
- pmcstat_string_unintern(pi->pi_execpath),
- pmcstat_string_unintern(
- pi->pi_samplename));
-
- /* flush gmon.out data to disk */
- LIST_FOREACH(pgf, &pi->pi_gmlist, pgf_next) {
- pmcstat_gmon_unmap_file(pgf);
- if (mf)
- (void) fprintf(mf, " %s/%d",
- pmcstat_pmcid_to_name(
- pgf->pgf_pmcid),
- pgf->pgf_nsamples);
- if (pgf->pgf_overflow && a->pa_verbosity >= 1)
- warnx("WARNING: profile \"%s\" "
- "overflowed.",
- pmcstat_string_unintern(
- pgf->pgf_name));
- }
-
- if (mf)
- (void) fprintf(mf, "\n");
- }
- }
-
/*
- * Compute arcs and add these to the gprof files.
+ * Shutdown the plugins
*/
- if (a->pa_flags & FLAG_DO_GPROF && a->pa_graphdepth > 1)
- pmcstat_callgraph_do_gmon_arcs();
- /*
- * Free memory.
- */
- for (i = 0; i < PMCSTAT_NHASH; i++) {
- LIST_FOREACH_SAFE(pch, &pmcstat_cgnode_hash[i], pch_next,
- pchtmp) {
- pmcstat_cgnode_free(pch->pch_cgnode);
- free(pch);
- }
- }
+ if (plugins[args.pa_plugin].pl_shutdown != NULL)
+ plugins[args.pa_plugin].pl_shutdown(mf);
+ if (plugins[args.pa_pplugin].pl_shutdown != NULL)
+ plugins[args.pa_pplugin].pl_shutdown(mf);
for (i = 0; i < PMCSTAT_NHASH; i++) {
- LIST_FOREACH_SAFE(pi, &pmcstat_image_hash[i], pi_next, pitmp)
- {
- LIST_FOREACH_SAFE(pgf, &pi->pi_gmlist, pgf_next,
- pgftmp) {
- if (pgf->pgf_file)
- (void) fclose(pgf->pgf_file);
- LIST_REMOVE(pgf, pgf_next);
- free(pgf);
- }
- if (pi->pi_symbols)
- free(pi->pi_symbols);
-
+ LIST_FOREACH_SAFE(pi, &pmcstat_image_hash[i], pi_next,
+ pitmp) {
+ if (plugins[args.pa_plugin].pl_shutdownimage != NULL)
+ plugins[args.pa_plugin].pl_shutdownimage(pi);
+ if (plugins[args.pa_pplugin].pl_shutdownimage != NULL)
+ plugins[args.pa_pplugin].pl_shutdownimage(pi);
+
+ free(pi->pi_symbols);
+ if (pi->pi_addr2line != NULL)
+ pclose(pi->pi_addr2line);
LIST_REMOVE(pi, pi_next);
free(pi);
}
LIST_FOREACH_SAFE(pp, &pmcstat_process_hash[i], pp_next,
pptmp) {
+ TAILQ_FOREACH_SAFE(ppm, &pp->pp_map, ppm_next, ppmtmp) {
+ TAILQ_REMOVE(&pp->pp_map, ppm, ppm_next);
+ free(ppm);
+ }
LIST_REMOVE(pp, pp_next);
free(pp);
}
@@ -2610,23 +2086,23 @@ pmcstat_shutdown_logging(struct pmcstat_args *a)
* Print errors unless -q was specified. Print all statistics
* if verbosity > 1.
*/
-#define PRINT(N,V,A) do { \
- if (pmcstat_stats.ps_##V || (A)->pa_verbosity >= 2) \
- (void) fprintf((A)->pa_printfile, " %-40s %d\n",\
+#define PRINT(N,V) do { \
+ if (pmcstat_stats.ps_##V || args.pa_verbosity >= 2) \
+ (void) fprintf(args.pa_printfile, " %-40s %d\n",\
N, pmcstat_stats.ps_##V); \
} while (0)
- if (a->pa_verbosity >= 1 && a->pa_flags & FLAG_DO_GPROF) {
- (void) fprintf(a->pa_printfile, "CONVERSION STATISTICS:\n");
- PRINT("#exec/a.out", exec_aout, a);
- PRINT("#exec/elf", exec_elf, a);
- PRINT("#exec/unknown", exec_indeterminable, a);
- PRINT("#exec handling errors", exec_errors, a);
- PRINT("#samples/total", samples_total, a);
- PRINT("#samples/unclaimed", samples_unknown_offset, a);
- PRINT("#samples/unknown-object", samples_indeterminable, a);
- PRINT("#callchain/dubious-frames", callchain_dubious_frames,
- a);
+ if (args.pa_verbosity >= 1 && (args.pa_flags & FLAG_DO_ANALYSIS) &&
+ (args.pa_flags & FLAG_DO_TOP) == 0) {
+ (void) fprintf(args.pa_printfile, "CONVERSION STATISTICS:\n");
+ PRINT("#exec/a.out", exec_aout);
+ PRINT("#exec/elf", exec_elf);
+ PRINT("#exec/unknown", exec_indeterminable);
+ PRINT("#exec handling errors", exec_errors);
+ PRINT("#samples/total", samples_total);
+ PRINT("#samples/unclaimed", samples_unknown_offset);
+ PRINT("#samples/unknown-object", samples_indeterminable);
+ PRINT("#callchain/dubious-frames", callchain_dubious_frames);
}
if (mf)
diff --git a/usr.sbin/pmcstat/pmcstat_log.h b/usr.sbin/pmcstat/pmcstat_log.h
new file mode 100644
index 0000000..de92649
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcstat_log.h
@@ -0,0 +1,196 @@
+/*-
+ * Copyright (c) 2005-2007, Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
+ * Copyright (c) 2009, Fabien Thomas
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PMCSTAT_LOG_H_
+#define _PMCSTAT_LOG_H_
+
+typedef const void *pmcstat_interned_string;
+
+/*
+ * A 'pmcstat_process' structure models processes. Each process is
+ * associated with a set of pmcstat_pcmap structures that map
+ * addresses inside it to executable objects. This set is implemented
+ * as a list, kept sorted in ascending order of mapped addresses.
+ *
+ * 'pp_pid' holds the pid of the process. When a process exits, the
+ * 'pp_isactive' field is set to zero, but the process structure is
+ * not immediately reclaimed because there may still be samples in the
+ * log for this process.
+ */
+
+struct pmcstat_process {
+ LIST_ENTRY(pmcstat_process) pp_next; /* hash-next */
+ pid_t pp_pid; /* associated pid */
+ int pp_isactive; /* whether active */
+ uintfptr_t pp_entryaddr; /* entry address */
+ TAILQ_HEAD(,pmcstat_pcmap) pp_map; /* address range map */
+};
+extern LIST_HEAD(pmcstat_process_hash_list, pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH];
+
+/*
+ * A 'pmcstat_image' structure describes an executable program on
+ * disk. 'pi_execpath' is a cookie representing the pathname of
+ * the executable. 'pi_start' and 'pi_end' are the least and greatest
+ * virtual addresses for the text segments in the executable.
+ * 'pi_gmonlist' contains a linked list of gmon.out files associated
+ * with this image.
+ */
+
+enum pmcstat_image_type {
+ PMCSTAT_IMAGE_UNKNOWN = 0, /* never looked at the image */
+ PMCSTAT_IMAGE_INDETERMINABLE, /* can't tell what the image is */
+ PMCSTAT_IMAGE_ELF32, /* ELF 32 bit object */
+ PMCSTAT_IMAGE_ELF64, /* ELF 64 bit object */
+ PMCSTAT_IMAGE_AOUT /* AOUT object */
+};
+
+struct pmcstat_image {
+ LIST_ENTRY(pmcstat_image) pi_next; /* hash link */
+ TAILQ_ENTRY(pmcstat_image) pi_lru; /* LRU list */
+ pmcstat_interned_string pi_execpath; /* cookie */
+ pmcstat_interned_string pi_samplename; /* sample path name */
+ pmcstat_interned_string pi_fullpath; /* path to FS object */
+ pmcstat_interned_string pi_name; /* display name */
+
+ enum pmcstat_image_type pi_type; /* executable type */
+
+ /*
+ * Executables have pi_start and pi_end; these are zero
+ * for shared libraries.
+ */
+ uintfptr_t pi_start; /* start address (inclusive) */
+ uintfptr_t pi_end; /* end address (exclusive) */
+ uintfptr_t pi_entry; /* entry address */
+ uintfptr_t pi_vaddr; /* virtual address where loaded */
+ int pi_isdynamic; /* whether a dynamic object */
+ int pi_iskernelmodule;
+ pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */
+
+ /* All symbols associated with this object. */
+ struct pmcstat_symbol *pi_symbols;
+ size_t pi_symcount;
+
+ /* Handle to addr2line for this image. */
+ FILE *pi_addr2line;
+
+ /*
+ * Plugins private data
+ */
+
+ /* gprof:
+ * An image can be associated with one or more gmon.out files;
+ * one per PMC.
+ */
+ LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
+};
+extern LIST_HEAD(pmcstat_image_hash_list, pmcstat_image) pmcstat_image_hash[PMCSTAT_NHASH];
+
+/*
+ * A 'pmcstat_pcmap' structure maps a virtual address range to an
+ * underlying 'pmcstat_image' descriptor.
+ */
+struct pmcstat_pcmap {
+ TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
+ uintfptr_t ppm_lowpc;
+ uintfptr_t ppm_highpc;
+ struct pmcstat_image *ppm_image;
+};
+
+/*
+ * Each function symbol tracked by pmcstat(8).
+ */
+
+struct pmcstat_symbol {
+ pmcstat_interned_string ps_name;
+ uint64_t ps_start;
+ uint64_t ps_end;
+};
+
+/*
+ * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable
+ * names.
+ */
+
+struct pmcstat_pmcrecord {
+ LIST_ENTRY(pmcstat_pmcrecord) pr_next;
+ pmc_id_t pr_pmcid;
+ int pr_pmcin;
+ pmcstat_interned_string pr_pmcname;
+ struct pmcstat_pmcrecord *pr_merge;
+};
+extern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs; /* PMC list */
+
+/*
+ * Misc. statistics
+ */
+struct pmcstat_stats {
+ int ps_exec_aout; /* # a.out executables seen */
+ int ps_exec_elf; /* # elf executables seen */
+ int ps_exec_errors; /* # errors processing executables */
+ int ps_exec_indeterminable; /* # unknown executables seen */
+ int ps_samples_total; /* total number of samples processed */
+ int ps_samples_skipped; /* #samples filtered out for any reason */
+ int ps_samples_unknown_offset; /* #samples of rank 0 not in a map */
+ int ps_samples_indeterminable; /* #samples in indeterminable images */
+ int ps_callchain_dubious_frames;/* #dubious frame pointers seen */
+};
+extern struct pmcstat_stats pmcstat_stats; /* statistics */
+
+extern struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
+
+extern int pmcstat_npmcs; /* PMC count. */
+
+/*
+ * Top mode global options.
+ */
+float pmcstat_threshold; /* Threshold to filter node. */
+int pmcstat_pmcinfilter; /* PMC index displayed. */
+
+/* Function prototypes */
+const char *pmcstat_pmcid_to_name(pmc_id_t _pmcid);
+const char *pmcstat_pmcindex_to_name(int pmcin);
+struct pmcstat_pmcrecord *pmcstat_pmcindex_to_pmcr(int pmcin);
+struct pmcstat_pcmap *pmcstat_process_find_map(struct pmcstat_process *_p,
+ uintfptr_t _pc);
+struct pmcstat_symbol *pmcstat_symbol_search(struct pmcstat_image *image,
+ uintfptr_t addr);
+const char *pmcstat_string_unintern(pmcstat_interned_string _is);
+pmcstat_interned_string pmcstat_string_intern(const char *_s);
+void pmcstat_image_determine_type(struct pmcstat_image *_image);
+pmcstat_interned_string pmcstat_string_lookup(const char *_s);
+int pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr,
+ char *sourcefile, size_t sourcefile_len, unsigned *sourceline,
+ char *funcname, size_t funcname_len);
+
+#endif /* _PMCSTAT_LOG_H_ */
+
diff --git a/usr.sbin/pmcstat/pmcstat_top.h b/usr.sbin/pmcstat/pmcstat_top.h
new file mode 100644
index 0000000..281410b
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcstat_top.h
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2009, Fabien Thomas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PMCSTAT_TOP_H_
+#define _PMCSTAT_TOP_H_
+
+/* Return the ncurses attributes for the given value. */
+#define PMCSTAT_ATTRPERCENT(b) \
+ ((b) > 10.0 ? (args.pa_topcolor ? COLOR_PAIR(1) : A_BOLD) : \
+ ((b) > 5.0 ? (args.pa_topcolor ? COLOR_PAIR(2) : 0) : \
+ ((b) > 2.5 ? (args.pa_topcolor ? COLOR_PAIR(3) : 0) : 0)))
+
+/* Print to the default ncurse windows if on a terminal or to the file. */
+#define PMCSTAT_PRINTW(...) do { \
+ if (args.pa_toptty) \
+ printw(__VA_ARGS__); \
+ else \
+ fprintf(args.pa_printfile, __VA_ARGS__);\
+} while (0)
+
+/* If ncurses mode active set attributes. */
+#define PMCSTAT_ATTRON(b) do { \
+ if (args.pa_toptty) \
+ attron(b); \
+} while (0)
+
+/* If ncurses mode active unset attributes. */
+#define PMCSTAT_ATTROFF(b) do { \
+ if (args.pa_toptty) \
+ attroff(b); \
+} while (0)
+
+/* Erase screen and set cursor to top left. */
+#define PMCSTAT_PRINTBEGIN() do { \
+ if (args.pa_toptty) \
+ clear(); \
+} while (0)
+
+/* Flush buffer to backend. */
+#define PMCSTAT_PRINTEND() do { \
+ if (!args.pa_toptty) { \
+ PMCSTAT_PRINTW("---\n"); \
+ fflush(args.pa_printfile); \
+ } else \
+ refresh(); \
+} while (0)
+
+/* Function prototypes */
+
+#endif /* _PMCSTAT_TOP_H_ */
diff --git a/usr.sbin/pnpinfo/Makefile b/usr.sbin/pnpinfo/Makefile
index 294b4f7..164ef37 100644
--- a/usr.sbin/pnpinfo/Makefile
+++ b/usr.sbin/pnpinfo/Makefile
@@ -11,4 +11,6 @@ CFLAGS+= -I${.CURDIR}/../../sys
CFLAGS+= -DPC98
.endif
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/portsnap/make_index/Makefile b/usr.sbin/portsnap/make_index/Makefile
index 65b1a8e..87768f6 100644
--- a/usr.sbin/portsnap/make_index/Makefile
+++ b/usr.sbin/portsnap/make_index/Makefile
@@ -2,7 +2,6 @@
PROG= make_index
NO_MAN=
-WARNS?= 6
BINDIR= ${LIBEXECDIR}
diff --git a/usr.sbin/portsnap/phttpget/Makefile b/usr.sbin/portsnap/phttpget/Makefile
index 154ff15..6f003e3 100644
--- a/usr.sbin/portsnap/phttpget/Makefile
+++ b/usr.sbin/portsnap/phttpget/Makefile
@@ -2,7 +2,6 @@
PROG= phttpget
NO_MAN=
-WARNS?= 6
BINDIR= ${LIBEXECDIR}
diff --git a/usr.sbin/portsnap/portsnap/portsnap.sh b/usr.sbin/portsnap/portsnap/portsnap.sh
index 0660b41..f554809 100644
--- a/usr.sbin/portsnap/portsnap/portsnap.sh
+++ b/usr.sbin/portsnap/portsnap/portsnap.sh
@@ -140,7 +140,7 @@ parse_cmdline() {
if [ ! -z "${SERVERNAME}" ]; then usage; fi
shift; SERVERNAME="$1"
;;
- cron | extract | fetch | update)
+ cron | extract | fetch | update | alfred)
COMMANDS="${COMMANDS} $1"
;;
*)
@@ -1040,6 +1040,22 @@ cmd_update() {
update_run || exit 1
}
+# Alfred command. Run 'fetch' or 'cron' depending on
+# whether stdin is a terminal; then run 'update' or
+# 'extract' depending on whether ${PORTSDIR} exists.
+cmd_alfred() {
+ if [ -t 0 ]; then
+ cmd_fetch
+ else
+ cmd_cron
+ fi
+ if [ -d ${PORTSDIR} ]; then
+ cmd_update
+ else
+ cmd_extract
+ fi
+}
+
#### Entry point
# Make sure we find utilities from the base system
diff --git a/usr.sbin/powerd/Makefile b/usr.sbin/powerd/Makefile
index 6adb188..62f8da1 100644
--- a/usr.sbin/powerd/Makefile
+++ b/usr.sbin/powerd/Makefile
@@ -2,13 +2,8 @@
PROG= powerd
MAN= powerd.8
-WARNS?= 6
DPADD= ${LIBUTIL}
LDADD= -lutil
-.if ${MACHINE_ARCH} == "i386"
-CFLAGS+=-DUSE_APM
-.endif
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/powerd/powerd.8 b/usr.sbin/powerd/powerd.8
index 7465410..5808862 100644
--- a/usr.sbin/powerd/powerd.8
+++ b/usr.sbin/powerd/powerd.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 24, 2008
+.Dd December 21, 2009
.Dt POWERD 8
.Os
.Sh NAME
@@ -45,7 +45,7 @@ The
.Nm
utility monitors the system state and sets various power control options
accordingly.
-It offers three modes (maximum, minimum, and adaptive) that can be
+It offers four modes (maximum, minimum, adaptive and hiadaptive) that can be
individually selected while on AC power or batteries.
The modes maximum, minimum, adaptive and hiadaptive may be abbreviated
max, min, adp, hadp.
@@ -57,9 +57,10 @@ Adaptive mode attempts to strike a balance by degrading performance when
the system appears idle and increasing it when the system is busy.
It offers a good balance between a small performance loss for greatly
increased power savings.
-Hiadaptive mode is alike adaptive mode, but tuned for systems where
+Hiadaptive mode is like adaptive mode, but tuned for systems where
performance and interactivity are more important then power consumption.
-It rises frequency faster, drops slower and keeps twice lower CPU load.
+It increases frequency faster, reduces the frequency less aggressively and
+will maintain full frequency for longer.
The default mode is adaptive for battery power and hiadaptive for the rest.
.Pp
The
diff --git a/usr.sbin/powerd/powerd.c b/usr.sbin/powerd/powerd.c
index e1b2a55..b4ba05d 100644
--- a/usr.sbin/powerd/powerd.c
+++ b/usr.sbin/powerd/powerd.c
@@ -46,6 +46,10 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
+#ifdef __i386__
+#define USE_APM
+#endif
+
#ifdef USE_APM
#include <machine/apm_bios.h>
#endif
@@ -259,7 +263,7 @@ get_freq_id(int freq, int *freqs, int numfreqs)
* to APM. If nothing succeeds, we'll just run in default mode.
*/
static void
-acline_init()
+acline_init(void)
{
acline_mib_len = 4;
diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile
index e8ae0e3..11003d7 100644
--- a/usr.sbin/ppp/Makefile
+++ b/usr.sbin/ppp/Makefile
@@ -25,6 +25,9 @@ PPP_NO_SUID=
.if ${MK_ATM} == "no"
PPP_NO_ATM=
.endif
+.if ${MK_NETGRAPH} == "no"
+PPP_NO_NETGRAPH=
+.endif
.if ${MK_PAM_SUPPORT} == "no"
PPP_NO_PAM=
.endif
diff --git a/usr.sbin/ppp/id.c b/usr.sbin/ppp/id.c
index 440d460..ec66574 100644
--- a/usr.sbin/ppp/id.c
+++ b/usr.sbin/ppp/id.c
@@ -49,7 +49,7 @@
#else
#include <libutil.h>
#endif
-#include <utmp.h>
+#include <utmpx.h>
#include "log.h"
#include "main.h"
@@ -202,36 +202,25 @@ ID0uu_unlock(const char *basettyname)
}
void
-ID0login(struct utmp *ut)
+ID0login(const struct utmpx *ut)
{
ID0set0();
- if (logout(ut->ut_line)) {
- log_Printf(LogID0, "logout(\"%s\")\n", ut->ut_line);
- logwtmp(ut->ut_line, "", "");
- log_Printf(LogID0, "logwtmp(\"%s\", \"\", \"\")\n", ut->ut_line);
- }
- login(ut);
- log_Printf(LogID0, "login(\"%s\", \"%.*s\")\n",
- ut->ut_line, (int)(sizeof ut->ut_name), ut->ut_name);
+ pututxline(ut);
+ log_Printf(LogID0, "pututxline(\"%.*s\", \"%.*s\", \"%.*s\", \"%.*s\")\n",
+ (int)sizeof ut->ut_id, ut->ut_id,
+ (int)sizeof ut->ut_user, ut->ut_user,
+ (int)sizeof ut->ut_line, ut->ut_line,
+ (int)sizeof ut->ut_host, ut->ut_host);
ID0setuser();
}
void
-ID0logout(const char *device, int nologout)
+ID0logout(const struct utmpx *ut)
{
- struct utmp ut;
- char ut_line[sizeof ut.ut_line + 1];
-
- strncpy(ut_line, device, sizeof ut_line - 1);
- ut_line[sizeof ut_line - 1] = '\0';
-
ID0set0();
- if (nologout || logout(ut_line)) {
- log_Printf(LogID0, "logout(\"%s\")\n", ut_line);
- logwtmp(ut_line, "", "");
- log_Printf(LogID0, "logwtmp(\"%s\", \"\", \"\")\n", ut_line);
- } else
- log_Printf(LogERROR, "ID0logout: No longer logged in on %s\n", ut_line);
+ pututxline(ut);
+ log_Printf(LogID0, "pututxline(\"%.*s\")\n",
+ (int)sizeof ut->ut_id, ut->ut_id);
ID0setuser();
}
diff --git a/usr.sbin/ppp/id.h b/usr.sbin/ppp/id.h
index 6125ab5..2357dc7 100644
--- a/usr.sbin/ppp/id.h
+++ b/usr.sbin/ppp/id.h
@@ -27,7 +27,7 @@
*/
#ifndef NOSUID
-struct utmp;
+struct utmpx;
struct sockaddr_un;
extern void ID0init(void);
@@ -41,8 +41,8 @@ extern int ID0write(int, const void *, size_t);
extern int ID0uu_lock(const char *);
extern int ID0uu_lock_txfr(const char *, pid_t);
extern int ID0uu_unlock(const char *);
-extern void ID0login(struct utmp *);
-extern void ID0logout(const char *, int);
+extern void ID0login(const struct utmpx *);
+extern void ID0logout(const struct utmpx *);
extern int ID0bind_un(int, const struct sockaddr_un *);
extern int ID0connect_un(int, const struct sockaddr_un *);
extern int ID0kill(pid_t, int);
@@ -64,20 +64,8 @@ extern int ID0NgMkSockNode(const char *, int *, int *);
#define ID0uu_lock uu_lock
#define ID0uu_lock_txfr uu_lock_txfr
#define ID0uu_unlock uu_unlock
-#define ID0login(u) \
- do { \
- if (logout((u)->ut_line)) \
- logwtmp((u)->ut_line, "", ""); \
- login(u); \
- } while (0)
-#define ID0logout(dev, no) \
- do { \
- struct utmp ut; \
- strncpy(ut.ut_line, dev, sizeof ut.ut_line - 1); \
- ut.ut_line[sizeof ut.ut_line - 1] = '\0'; \
- if (no || logout(ut.ut_line)) \
- logwtmp(ut.ut_line, "", ""); \
- } while (0)
+#define ID0login pututxline
+#define ID0logout pututxline
#define ID0bind_un(s, n) bind(s, (const struct sockaddr *)(n), sizeof *(n))
#define ID0connect_un(s, n) \
connect(s, (const struct sockaddr *)(n), sizeof *(n))
diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c
index 0377800..4083aa9 100644
--- a/usr.sbin/ppp/physical.c
+++ b/usr.sbin/ppp/physical.c
@@ -25,6 +25,7 @@
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/socket.h>
+#include <sys/time.h>
#include <sys/un.h>
#include <errno.h>
@@ -42,7 +43,7 @@
#include <termios.h>
#include <time.h>
#include <unistd.h>
-#include <utmp.h>
+#include <utmpx.h>
#if defined(__OpenBSD__) || defined(__NetBSD__)
#include <sys/ioctl.h>
#include <util.h>
@@ -106,8 +107,6 @@
#endif
#include "tcpmss.h"
-#define PPPOTCPLINE "ppp"
-
static int physical_DescriptorWrite(struct fdescriptor *, struct bundle *,
const fd_set *);
@@ -333,6 +332,7 @@ physical_Close(struct physical *p)
{
int newsid;
char fn[PATH_MAX];
+ struct utmpx ut;
if (p->fd < 0)
return;
@@ -344,12 +344,11 @@ physical_Close(struct physical *p)
physical_StopDeviceTimer(p);
if (p->Utmp) {
- if (p->handler && (p->handler->type == TCP_DEVICE ||
- p->handler->type == UDP_DEVICE))
- /* Careful - we logged in on line ``ppp'' with IP as our host */
- ID0logout(PPPOTCPLINE, 1);
- else
- ID0logout(p->name.base, 0);
+ memset(&ut, 0, sizeof ut);
+ ut.ut_type = DEAD_PROCESS;
+ gettimeofday(&ut.ut_tv, NULL);
+ snprintf(ut.ut_id, sizeof ut.ut_id, "%xppp", (int)getpid());
+ ID0logout(&ut);
p->Utmp = 0;
}
newsid = tcgetpgrp(p->fd) == getpgrp();
@@ -911,16 +910,17 @@ void
physical_Login(struct physical *p, const char *name)
{
if (p->type == PHYS_DIRECT && *p->name.base && !p->Utmp) {
- struct utmp ut;
+ struct utmpx ut;
const char *connstr;
char *colon;
memset(&ut, 0, sizeof ut);
- ut.ut_time = time(NULL);
- strncpy(ut.ut_name, name, sizeof ut.ut_name);
+ ut.ut_type = USER_PROCESS;
+ gettimeofday(&ut.ut_tv, NULL);
+ snprintf(ut.ut_id, sizeof ut.ut_id, "%xppp", (int)getpid());
+ strncpy(ut.ut_user, name, sizeof ut.ut_user);
if (p->handler && (p->handler->type == TCP_DEVICE ||
p->handler->type == UDP_DEVICE)) {
- strncpy(ut.ut_line, PPPOTCPLINE, sizeof ut.ut_line);
strncpy(ut.ut_host, p->name.base, sizeof ut.ut_host);
colon = memchr(ut.ut_host, ':', sizeof ut.ut_host);
if (colon)
@@ -931,7 +931,7 @@ physical_Login(struct physical *p, const char *name)
/* mgetty sets this to the connection speed */
strncpy(ut.ut_host, connstr, sizeof ut.ut_host);
ID0login(&ut);
- p->Utmp = ut.ut_time;
+ p->Utmp = 1;
}
}
diff --git a/usr.sbin/ppp/physical.h b/usr.sbin/ppp/physical.h
index ab0cdba..cf3408e 100644
--- a/usr.sbin/ppp/physical.h
+++ b/usr.sbin/ppp/physical.h
@@ -97,7 +97,7 @@ struct physical {
char *base;
} name;
- time_t Utmp; /* Are we in utmp ? */
+ int Utmp; /* Are we in utmp ? */
pid_t session_owner; /* HUP this when closing the link */
struct device *handler; /* device specific handler */
diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4
index 6663759..a711d58 100644
--- a/usr.sbin/ppp/ppp.8.m4
+++ b/usr.sbin/ppp/ppp.8.m4
@@ -44,10 +44,10 @@ changecom(,)dnl
This is a user process
.Em PPP
software package.
-Normally,
+Sometimes,
.Em PPP
is implemented as a part of the kernel (e.g., as managed by
-.Xr pppd 8 )
+.Nm pppd )
and it is thus somewhat hard to debug and/or modify its behaviour.
However, in this implementation
.Em PPP
@@ -2701,7 +2701,7 @@ program.
Note: There is a problem negotiating
.Ar deflate
capabilities with
-.Xr pppd 8
+.Nm pppd
- a
.Em PPP
implementation available under many operating systems.
@@ -2734,7 +2734,7 @@ Default: Disabled and Denied.
This is a variance of the
.Ar deflate
option, allowing negotiation with the
-.Xr pppd 8
+.Nm pppd
program.
Refer to the
.Ar deflate
@@ -2882,7 +2882,7 @@ acts as the authenticatee with both protocols
the protocols are used alternately in response to challenges.
.Pp
Note: If only LANMan is enabled,
-.Xr pppd 8
+.Nm pppd
(version 2.3.5) misbehaves when acting as authenticatee.
It provides both
the NT and the LANMan answers, but also suggests that only the NT answer
@@ -6091,7 +6091,6 @@ ifdef({LOCALRAD},{},{.Xr libradius 3 ,
.Xr named 8 ,
.Xr ping 8 ,
.Xr pppctl 8 ,
-.Xr pppd 8 ,
.Xr pppoed 8 ,
.Xr route 8 ,
.Xr sshd 8 ,
diff --git a/usr.sbin/pppctl/Makefile b/usr.sbin/pppctl/Makefile
index 6cdcc3d..2f2be4b 100644
--- a/usr.sbin/pppctl/Makefile
+++ b/usr.sbin/pppctl/Makefile
@@ -3,6 +3,8 @@
PROG= pppctl
MAN= pppctl.8
+WARNS?= 2
+
DPADD= ${LIBPTHREAD} ${LIBEDIT} ${LIBTERMCAP}
LDADD= -lpthread -ledit -ltermcap
diff --git a/usr.sbin/praliases/Makefile b/usr.sbin/praliases/Makefile
index 81fd4d1..120028d 100644
--- a/usr.sbin/praliases/Makefile
+++ b/usr.sbin/praliases/Makefile
@@ -11,6 +11,8 @@ MAN= praliases.8
CFLAGS+= -I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
CFLAGS+= -DNEWDB -DNOT_SENDMAIL
+WARNS?= 2
+
LIBSMDIR= ${.OBJDIR}/../../lib/libsm
LIBSM= ${LIBSMDIR}/libsm.a
diff --git a/usr.sbin/praudit/Makefile b/usr.sbin/praudit/Makefile
index 4ff08fd..6a61fd1 100644
--- a/usr.sbin/praudit/Makefile
+++ b/usr.sbin/praudit/Makefile
@@ -8,6 +8,8 @@ OPENBSMDIR=${.CURDIR}/../../contrib/openbsm
PROG= praudit
MAN= praudit.1
+WARNS?= 3
+
DPADD= ${LIBBSM}
LDADD= -lbsm
diff --git a/usr.sbin/procctl/Makefile b/usr.sbin/procctl/Makefile
index 5cb35e7..880b93a 100644
--- a/usr.sbin/procctl/Makefile
+++ b/usr.sbin/procctl/Makefile
@@ -3,6 +3,4 @@
PROG= procctl
MAN= procctl.8
-WARNS?= 2
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/pstat/Makefile b/usr.sbin/pstat/Makefile
index 4620dde..414708c 100644
--- a/usr.sbin/pstat/Makefile
+++ b/usr.sbin/pstat/Makefile
@@ -6,8 +6,6 @@ LINKS= ${BINDIR}/pstat ${BINDIR}/swapinfo
MAN= pstat.8
MLINKS= pstat.8 swapinfo.8
-WARNS?= 6
-
DPADD= ${LIBKVM} ${LIBUTIL}
LDADD= -lkvm -lutil
diff --git a/usr.sbin/pw/Makefile b/usr.sbin/pw/Makefile
index 8937124..ae0023c 100644
--- a/usr.sbin/pw/Makefile
+++ b/usr.sbin/pw/Makefile
@@ -6,6 +6,8 @@ SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c pw_vpw.c \
grupd.c pwupd.c fileupd.c edgroup.c psdate.c \
bitmap.c cpdir.c rm_r.c
+WARNS?= 1
+
DPADD= ${LIBCRYPT} ${LIBUTIL}
LDADD= -lcrypt -lutil
diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c
index 4c62fe8..c8364ca 100644
--- a/usr.sbin/pw/pw_user.c
+++ b/usr.sbin/pw/pw_user.c
@@ -41,16 +41,11 @@ static const char rcsid[] =
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
-#include <utmp.h>
#include <login_cap.h>
#include "pw.h"
#include "bitmap.h"
-#if (MAXLOGNAME-1) > UT_NAMESIZE
-#define LOGNAMESIZE UT_NAMESIZE
-#else
#define LOGNAMESIZE (MAXLOGNAME-1)
-#endif
static char locked_str[] = "*LOCKED*";
diff --git a/usr.sbin/pwd_mkdb/Makefile b/usr.sbin/pwd_mkdb/Makefile
index c3aaeb3..7616629 100644
--- a/usr.sbin/pwd_mkdb/Makefile
+++ b/usr.sbin/pwd_mkdb/Makefile
@@ -7,7 +7,6 @@ PROG= pwd_mkdb
MAN= pwd_mkdb.8
SRCS= pw_scan.c pwd_mkdb.c
-WARNS?= 4
CFLAGS+= -I${.CURDIR}/../../lib/libc/gen # for pw_scan.h
.include <bsd.prog.mk>
diff --git a/usr.sbin/quotaon/Makefile b/usr.sbin/quotaon/Makefile
index 0a07f06..23ba8d1 100644
--- a/usr.sbin/quotaon/Makefile
+++ b/usr.sbin/quotaon/Makefile
@@ -6,8 +6,6 @@ LINKS= ${BINDIR}/quotaon ${BINDIR}/quotaoff
MAN= quotaon.8
MLINKS= quotaon.8 quotaoff.8
-WARNS?= 4
-
DPADD= ${LIBUTIL}
LDADD= -lutil
diff --git a/usr.sbin/quotaon/quotaon.c b/usr.sbin/quotaon/quotaon.c
index 0f8ef98..d510e80 100644
--- a/usr.sbin/quotaon/quotaon.c
+++ b/usr.sbin/quotaon/quotaon.c
@@ -153,9 +153,7 @@ usage(void)
}
int
-quotaonoff(fs, offmode, type)
- struct fstab *fs;
- int offmode, type;
+quotaonoff(struct fstab *fs, int offmode, int type)
{
struct quotafile *qf;
diff --git a/usr.sbin/repquota/Makefile b/usr.sbin/repquota/Makefile
index 9da22c2..ed80132 100644
--- a/usr.sbin/repquota/Makefile
+++ b/usr.sbin/repquota/Makefile
@@ -6,6 +6,4 @@ MAN= repquota.8
DPADD= ${LIBUTIL}
LDADD= -lutil
-WARNS?= 4
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/rip6query/Makefile b/usr.sbin/rip6query/Makefile
index e0ea621..fac9028 100644
--- a/usr.sbin/rip6query/Makefile
+++ b/usr.sbin/rip6query/Makefile
@@ -4,7 +4,6 @@
PROG= rip6query
MAN= rip6query.8
-WARNS?= 2
CFLAGS+= -I${.CURDIR}/../route6d
.include <bsd.prog.mk>
diff --git a/usr.sbin/rip6query/rip6query.c b/usr.sbin/rip6query/rip6query.c
index 0bf56fd..4426bbc 100644
--- a/usr.sbin/rip6query/rip6query.c
+++ b/usr.sbin/rip6query/rip6query.c
@@ -68,9 +68,7 @@ static const char *sa_n2a(struct sockaddr *);
static const char *inet6_n2a(struct in6_addr *);
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char *argv[])
{
struct netinfo6 *np;
struct sockaddr_in6 fsock;
@@ -175,15 +173,14 @@ main(argc, argv)
}
static void
-usage()
+usage(void)
{
fprintf(stderr, "usage: rip6query [-I iface] address\n");
}
/* getnameinfo() is preferred as we may be able to show ifindex as ifname */
static const char *
-sa_n2a(sa)
- struct sockaddr *sa;
+sa_n2a(struct sockaddr *sa)
{
static char buf[NI_MAXHOST];
@@ -195,8 +192,7 @@ sa_n2a(sa)
}
static const char *
-inet6_n2a(addr)
- struct in6_addr *addr;
+inet6_n2a(struct in6_addr *addr)
{
static char buf[NI_MAXHOST];
diff --git a/usr.sbin/rmt/Makefile b/usr.sbin/rmt/Makefile
index 579a02b..8a678b6 100644
--- a/usr.sbin/rmt/Makefile
+++ b/usr.sbin/rmt/Makefile
@@ -4,8 +4,6 @@
PROG= rmt
MAN= rmt.8
-WARNS?= 4
-
# called from /usr/src/etc/Makefile
etc-rmt:
rm -f ${DESTDIR}/etc/rmt
diff --git a/usr.sbin/rmt/rmt.c b/usr.sbin/rmt/rmt.c
index af4f954..f5e3cc1 100644
--- a/usr.sbin/rmt/rmt.c
+++ b/usr.sbin/rmt/rmt.c
@@ -206,8 +206,7 @@ ioerror:
}
void
-getstring(bp)
- char *bp;
+getstring(char *bp)
{
int i;
char *cp = bp;
@@ -222,9 +221,7 @@ getstring(bp)
}
char *
-checkbuf(rec, size)
- char *rec;
- int size;
+checkbuf(char *rec, int size)
{
if (size <= maxrecsize)
@@ -244,8 +241,7 @@ checkbuf(rec, size)
}
void
-error(num)
- int num;
+error(int num)
{
DEBUG2("rmtd: E %d (%s)\n", num, strerror(num));
diff --git a/usr.sbin/rndc-confgen/Makefile b/usr.sbin/rndc-confgen/Makefile
index b8a52dd..08f2d7e 100644
--- a/usr.sbin/rndc-confgen/Makefile
+++ b/usr.sbin/rndc-confgen/Makefile
@@ -17,6 +17,8 @@ SRCS+= rndc-confgen.c util.c
CFLAGS+= -I${SRCDIR}/unix/include -I${SRCDIR}/include -I${LIB_BIND_DIR}
+WARNS?= 3
+
DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
diff --git a/usr.sbin/rndc/Makefile b/usr.sbin/rndc/Makefile
index 2ca7697..9cd356f 100644
--- a/usr.sbin/rndc/Makefile
+++ b/usr.sbin/rndc/Makefile
@@ -17,6 +17,8 @@ SRCS+= rndc.c util.c
CFLAGS+= -I${SRCDIR}/unix/include -I${SRCDIR}/include -I${LIB_BIND_DIR}
+WARNS?= 3
+
DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
diff --git a/usr.sbin/route6d/Makefile b/usr.sbin/route6d/Makefile
index 308aad7..df23d33 100644
--- a/usr.sbin/route6d/Makefile
+++ b/usr.sbin/route6d/Makefile
@@ -6,4 +6,6 @@ MAN= route6d.8
CFLAGS+= -DHAVE_POLL_H
+WARNS?= 1
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/rpc.lockd/Makefile b/usr.sbin/rpc.lockd/Makefile
index 961ad17..c81da82 100644
--- a/usr.sbin/rpc.lockd/Makefile
+++ b/usr.sbin/rpc.lockd/Makefile
@@ -7,7 +7,7 @@ MLINKS= rpc.lockd.8 lockd.8
SRCS= kern.c nlm_prot_svc.c lockd.c lock_proc.c lockd_lock.c
CFLAGS+= -I. -I${DESTDIR}/usr/include/rpcsvc
-#WARNS?= 2
+WARNS?= 0
DPADD= ${LIBRPCSVC} ${LIBUTIL}
LDADD= -lrpcsvc -lutil
diff --git a/usr.sbin/rpc.statd/Makefile b/usr.sbin/rpc.statd/Makefile
index 6d8053c..e69a9d6 100644
--- a/usr.sbin/rpc.statd/Makefile
+++ b/usr.sbin/rpc.statd/Makefile
@@ -5,7 +5,7 @@ MAN= rpc.statd.8
SRCS= file.c sm_inter_svc.c sm_inter.h statd.c procs.c
CFLAGS+= -I.
-#WARNS?= 2
+WARNS?= 2
DPADD= ${LIBRPCSVC}
LDADD= -lrpcsvc
diff --git a/usr.sbin/rpc.umntall/Makefile b/usr.sbin/rpc.umntall/Makefile
index 0a829c3..fc4a399 100644
--- a/usr.sbin/rpc.umntall/Makefile
+++ b/usr.sbin/rpc.umntall/Makefile
@@ -5,6 +5,6 @@ PROG= rpc.umntall
MAN= rpc.umntall.8
SRCS= rpc.umntall.c mounttab.c
-#WARNS?= 2
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/usr.sbin/rpc.umntall/mounttab.c b/usr.sbin/rpc.umntall/mounttab.c
index 9d7fe2f..56333ca 100644
--- a/usr.sbin/rpc.umntall/mounttab.c
+++ b/usr.sbin/rpc.umntall/mounttab.c
@@ -45,14 +45,15 @@ __FBSDID("$FreeBSD$");
struct mtablist *mtabhead;
-static void badline(char *field, char *bad);
+static void badline(const char *field, const char *bad);
/*
* Add an entry to PATH_MOUNTTAB for each mounted NFS filesystem,
* so the client can notify the NFS server even after reboot.
*/
int
-add_mtab(char *hostp, char *dirp) {
+add_mtab(char *hostp, char *dirp)
+{
FILE *mtabfile;
if ((mtabfile = fopen(PATH_MOUNTTAB, "a")) == NULL)
@@ -69,12 +70,13 @@ add_mtab(char *hostp, char *dirp) {
* Read mounttab line for line and return struct mtablist.
*/
int
-read_mtab() {
+read_mtab(void)
+{
struct mtablist **mtabpp, *mtabp;
char *hostp, *dirp, *cp;
char str[STRSIZ];
char *timep, *endp;
- time_t time;
+ time_t actiontime;
u_long ultmp;
FILE *mtabfile;
@@ -86,7 +88,7 @@ read_mtab() {
return (0);
}
}
- time = 0;
+ actiontime = 0;
mtabpp = &mtabhead;
while (fgets(str, STRSIZ, mtabfile) != NULL) {
cp = str;
@@ -113,13 +115,13 @@ read_mtab() {
badline("time", timep);
continue;
}
- time = ultmp;
+ actiontime = ultmp;
if ((mtabp = malloc(sizeof (struct mtablist))) == NULL) {
syslog(LOG_ERR, "malloc");
fclose(mtabfile);
return (0);
}
- mtabp->mtab_time = time;
+ mtabp->mtab_time = actiontime;
memmove(mtabp->mtab_host, hostp, MNTNAMLEN);
mtabp->mtab_host[MNTNAMLEN - 1] = '\0';
memmove(mtabp->mtab_dirp, dirp, MNTPATHLEN);
@@ -137,7 +139,8 @@ read_mtab() {
* Unlink PATH_MOUNTAB if no entry is left.
*/
int
-write_mtab(int verbose) {
+write_mtab(int verbose)
+{
struct mtablist *mtabp, *mp;
FILE *mtabfile;
int line;
@@ -180,7 +183,8 @@ write_mtab(int verbose) {
* Mark the entries as clean where RPC calls have been done successfully.
*/
void
-clean_mtab(char *hostp, char *dirp, int verbose) {
+clean_mtab(char *hostp, char *dirp, int verbose)
+{
struct mtablist *mtabp;
char *host;
@@ -205,7 +209,8 @@ clean_mtab(char *hostp, char *dirp, int verbose) {
* Free struct mtablist mtab.
*/
void
-free_mtab() {
+free_mtab(void)
+{
struct mtablist *mtabp;
while ((mtabp = mtabhead) != NULL) {
@@ -218,7 +223,8 @@ free_mtab() {
* Print bad lines to syslog.
*/
static void
-badline(char *field, char *bad) {
+badline(const char *field, const char *bad)
+{
syslog(LOG_ERR, "bad mounttab %s field '%s'", field,
(bad == NULL) ? "<null>" : bad);
}
diff --git a/usr.sbin/rpc.yppasswdd/Makefile b/usr.sbin/rpc.yppasswdd/Makefile
index bbd2658..b6a0a8c 100644
--- a/usr.sbin/rpc.yppasswdd/Makefile
+++ b/usr.sbin/rpc.yppasswdd/Makefile
@@ -14,7 +14,7 @@ SRCS= util.c yp_access.c yp_dblookup.c yp_dbwrite.c \
GENSRCS=yp.h yp_clnt.c yppasswd.h yppasswd_private.h yppasswd_private_svc.c \
yppasswd_private_xdr.c yppasswd_svc.c
-WARNS?= 4
+WARNS?= 5
CFLAGS+= -fno-strict-aliasing
CFLAGS+= -I${.CURDIR}/../../usr.sbin/vipw \
-I${.CURDIR}/../../usr.sbin/ypserv \
diff --git a/usr.sbin/rpc.ypupdated/Makefile b/usr.sbin/rpc.ypupdated/Makefile
index 4fe19c9..fecb837 100644
--- a/usr.sbin/rpc.ypupdated/Makefile
+++ b/usr.sbin/rpc.ypupdated/Makefile
@@ -11,6 +11,8 @@ SRCS= ypupdate_prot_svc.c ypupdate_prot.h ypupdated_main.c \
#CFLAGS+= -DYP
CFLAGS+= -I${.CURDIR}/../ypserv -I. -I${.CURDIR}/../../libexec/ypxfr
+WARNS?= 1
+
DPADD= ${LIBRPCSVC}
LDADD= -lrpcsvc
diff --git a/usr.sbin/rpc.ypxfrd/Makefile b/usr.sbin/rpc.ypxfrd/Makefile
index 70729b1..ee9e242 100644
--- a/usr.sbin/rpc.ypxfrd/Makefile
+++ b/usr.sbin/rpc.ypxfrd/Makefile
@@ -9,6 +9,8 @@ SRCS= ypxfrd_svc.c ypxfrd.h ypxfrd_server.c yp_error.c \
CFLAGS+= -I. -DXFRBLOCKSIZE=65535
+WARNS?= 2
+
DPADD= ${LIBRPCSVC}
LDADD= -lrpcsvc
diff --git a/usr.sbin/rpcbind/Makefile b/usr.sbin/rpcbind/Makefile
index 3251378..dd042f2 100644
--- a/usr.sbin/rpcbind/Makefile
+++ b/usr.sbin/rpcbind/Makefile
@@ -14,6 +14,8 @@ CFLAGS+= -DPORTMAP -DLIBWRAP
CFLAGS+= -DINET6
.endif
+WARNS?= 1
+
DPADD= ${LIBWRAP} ${LIBUTIL}
LDADD= -lwrap -lutil
diff --git a/usr.sbin/rpcbind/rpcb_svc_com.c b/usr.sbin/rpcbind/rpcb_svc_com.c
index ab7c8ff..79cb937 100644
--- a/usr.sbin/rpcbind/rpcb_svc_com.c
+++ b/usr.sbin/rpcbind/rpcb_svc_com.c
@@ -1224,6 +1224,7 @@ handle_reply(int fd, SVCXPRT *xprt)
goto done;
do {
+ fromlen = sizeof(ss);
inlen = recvfrom(fd, buffer, RPC_BUF_MAX, 0,
(struct sockaddr *)&ss, &fromlen);
} while (inlen < 0 && errno == EINTR);
diff --git a/usr.sbin/rpcbind/rpcbind.c b/usr.sbin/rpcbind/rpcbind.c
index b601da5..5a76a68 100644
--- a/usr.sbin/rpcbind/rpcbind.c
+++ b/usr.sbin/rpcbind/rpcbind.c
@@ -92,6 +92,7 @@ int oldstyle_local = 0;
int verboselog = 0;
char **hosts = NULL;
+struct sockaddr **bound_sa;
int ipv6_only = 0;
int nhosts = 0;
int on = 1;
@@ -119,6 +120,7 @@ static void rbllist_add(rpcprog_t, rpcvers_t, struct netconfig *,
struct netbuf *);
static void terminate(int);
static void parseargs(int, char *[]);
+static void update_bound_sa(void);
int
main(int argc, char *argv[])
@@ -130,6 +132,8 @@ main(int argc, char *argv[])
parseargs(argc, argv);
+ update_bound_sa();
+
/* Check that another rpcbind isn't already running. */
if ((rpcbindlockfd = (open(RPCBINDDLOCK,
O_RDONLY|O_CREAT, 0444))) == -1)
@@ -323,8 +327,7 @@ init_transport(struct netconfig *nconf)
* If no hosts were specified, just bind to INADDR_ANY.
* Otherwise make sure 127.0.0.1 is added to the list.
*/
- nhostsbak = nhosts;
- nhostsbak++;
+ nhostsbak = nhosts + 1;
hosts = realloc(hosts, nhostsbak * sizeof(char *));
if (nhostsbak == 1)
hosts[0] = "*";
@@ -657,6 +660,75 @@ error:
return (1);
}
+/*
+ * Create the list of addresses that we're bound to. Normally, this
+ * list is empty because we're listening on the wildcard address
+ * (nhost == 0). If -h is specified on the command line, then
+ * bound_sa will have a list of the addresses that the program binds
+ * to specifically. This function takes that list and converts them to
+ * struct sockaddr * and stores them in bound_sa.
+ */
+static void
+update_bound_sa(void)
+{
+ struct addrinfo hints, *res = NULL;
+ int i;
+
+ if (nhosts == 0)
+ return;
+ bound_sa = malloc(sizeof(*bound_sa) * nhosts);
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ for (i = 0; i < nhosts; i++) {
+ if (getaddrinfo(hosts[i], NULL, &hints, &res) != 0)
+ continue;
+ bound_sa[i] = malloc(res->ai_addrlen);
+ memcpy(bound_sa[i], res->ai_addr, res->ai_addrlen);
+ }
+}
+
+/*
+ * Match the sa against the list of addresses we've bound to. If
+ * we've not specifically bound to anything, we match everything.
+ * Otherwise, if the IPv4 or IPv6 address matches one of the addresses
+ * in bound_sa, we return true. If not, we return false.
+ */
+int
+listen_addr(const struct sockaddr *sa)
+{
+ int i;
+
+ /*
+ * If nhosts == 0, then there were no -h options on the
+ * command line, so all addresses are addresses we're
+ * listening to.
+ */
+ if (nhosts == 0)
+ return 1;
+ for (i = 0; i < nhosts; i++) {
+ if (bound_sa[i] == NULL ||
+ sa->sa_family != bound_sa[i]->sa_family)
+ continue;
+ switch (sa->sa_family) {
+ case AF_INET:
+ if (memcmp(&SA2SINADDR(sa), &SA2SINADDR(bound_sa[i]),
+ sizeof(struct in_addr)) == 0)
+ return (1);
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if (memcmp(&SA2SIN6ADDR(sa), &SA2SIN6ADDR(bound_sa[i]),
+ sizeof(struct in6_addr)) == 0)
+ return (1);
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ return (0);
+}
+
static void
rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf,
struct netbuf *addr)
diff --git a/usr.sbin/rpcbind/rpcbind.h b/usr.sbin/rpcbind/rpcbind.h
index 5537ce4..717bb3b 100644
--- a/usr.sbin/rpcbind/rpcbind.h
+++ b/usr.sbin/rpcbind/rpcbind.h
@@ -134,6 +134,7 @@ void read_warmstart(void);
char *addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
char *netid);
+int listen_addr(const struct sockaddr *sa);
void network_init(void);
struct sockaddr *local_sa(int);
@@ -141,4 +142,12 @@ struct sockaddr *local_sa(int);
#define RPCB_ALLVERS 0
#define RPCB_ONEVERS 1
+/* To convert a struct sockaddr to IPv4 or IPv6 address */
+#define SA2SIN(sa) ((struct sockaddr_in *)(sa))
+#define SA2SINADDR(sa) (SA2SIN(sa)->sin_addr)
+#ifdef INET6
+#define SA2SIN6(sa) ((struct sockaddr_in6 *)(sa))
+#define SA2SIN6ADDR(sa) (SA2SIN6(sa)->sin6_addr)
+#endif
+
#endif /* rpcbind_h */
diff --git a/usr.sbin/rpcbind/util.c b/usr.sbin/rpcbind/util.c
index 66797a7..7a300d2 100644
--- a/usr.sbin/rpcbind/util.c
+++ b/usr.sbin/rpcbind/util.c
@@ -18,13 +18,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with 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 NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -58,13 +51,6 @@
#include "rpcbind.h"
-#define SA2SIN(sa) ((struct sockaddr_in *)(sa))
-#define SA2SINADDR(sa) (SA2SIN(sa)->sin_addr)
-#ifdef INET6
-#define SA2SIN6(sa) ((struct sockaddr_in6 *)(sa))
-#define SA2SIN6ADDR(sa) (SA2SIN6(sa)->sin6_addr)
-#endif
-
static struct sockaddr_in *local_in4;
#ifdef INET6
static struct sockaddr_in6 *local_in6;
@@ -176,9 +162,13 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
goto freeit;
/*
- * Loop through all interfaces. For each interface, see if the
- * network portion of its address is equal to that of the client.
- * If so, we have found the interface that we want to use.
+ * Loop through all interfaces. For each interface, see if it
+ * is either the loopback interface (which we always listen
+ * on) or is one of the addresses the program bound to (the
+ * wildcard by default, or a subset if -h is specified) and
+ * the network portion of its address is equal to that of the
+ * client. If so, we have found the interface that we want to
+ * use.
*/
bestif = NULL;
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
@@ -189,6 +179,9 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
!(ifap->ifa_flags & IFF_UP))
continue;
+ if (!(ifap->ifa_flags & IFF_LOOPBACK) && !listen_addr(ifsa))
+ continue;
+
switch (hint_sa->sa_family) {
case AF_INET:
/*
diff --git a/usr.sbin/rrenumd/Makefile b/usr.sbin/rrenumd/Makefile
index c31a7c7..091e528 100644
--- a/usr.sbin/rrenumd/Makefile
+++ b/usr.sbin/rrenumd/Makefile
@@ -21,6 +21,8 @@ SRCS= rrenumd.c parser.y lexer.l
CFLAGS+= -DIPSEC -I. -I${.CURDIR}
YFLAGS= -d
+WARNS?= 2
+
LDADD= -lipsec -ll -ly
DPADD= ${LIBIPSEC} ${LIBL} ${LIBY}
diff --git a/usr.sbin/rtadvd/Makefile b/usr.sbin/rtadvd/Makefile
index f7e2021..90b45f1 100644
--- a/usr.sbin/rtadvd/Makefile
+++ b/usr.sbin/rtadvd/Makefile
@@ -20,4 +20,6 @@ SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c
CFLAGS+= -DHAVE_ARC4RANDOM -DHAVE_POLL_H -DROUTEINFO
+WARNS?= 1
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/rtprio/Makefile b/usr.sbin/rtprio/Makefile
index ebc7bd1..b612f2b 100644
--- a/usr.sbin/rtprio/Makefile
+++ b/usr.sbin/rtprio/Makefile
@@ -5,4 +5,6 @@ PROG= rtprio
LINKS= ${BINDIR}/rtprio ${BINDIR}/idprio
MLINKS= rtprio.1 idprio.1
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/rtsold/Makefile b/usr.sbin/rtsold/Makefile
index 1afa0f6..efc322c 100644
--- a/usr.sbin/rtsold/Makefile
+++ b/usr.sbin/rtsold/Makefile
@@ -19,8 +19,8 @@ MAN= rtsold.8
MLINKS= rtsold.8 rtsol.8
SRCS= rtsold.c rtsol.c if.c probe.c dump.c rtsock.c
+WARNS?= 3
CFLAGS+= -DHAVE_ARC4RANDOM -DHAVE_POLL_H
-
DPADD= ${LIBKVM}
LDADD= -lkvm
diff --git a/usr.sbin/rtsold/dump.c b/usr.sbin/rtsold/dump.c
index 62056ae..2756b87 100644
--- a/usr.sbin/rtsold/dump.c
+++ b/usr.sbin/rtsold/dump.c
@@ -52,8 +52,8 @@ static FILE *fp;
extern struct ifinfo *iflist;
static void dump_interface_status(void);
-static char *sec2str(time_t);
-char *ifstatstr[] = {"IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE"};
+static const char *sec2str(time_t);
+static const char * const ifstatstr[] = {"IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE"};
static void
dump_interface_status(void)
@@ -97,7 +97,7 @@ dump_interface_status(void)
}
void
-rtsold_dump_file(char *dumpfile)
+rtsold_dump_file(const char *dumpfile)
{
if ((fp = fopen(dumpfile, "w")) == NULL) {
warnmsg(LOG_WARNING, __func__, "open a dump file(%s): %s",
@@ -108,7 +108,7 @@ rtsold_dump_file(char *dumpfile)
fclose(fp);
}
-static char *
+static const char *
sec2str(time_t total)
{
static char result[256];
diff --git a/usr.sbin/rtsold/if.c b/usr.sbin/rtsold/if.c
index e8786ff..c555d2a 100644
--- a/usr.sbin/rtsold/if.c
+++ b/usr.sbin/rtsold/if.c
@@ -82,7 +82,6 @@ interface_up(char *name)
struct in6_ndireq nd;
int llflag;
int s;
- int error;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
diff --git a/usr.sbin/rtsold/probe.c b/usr.sbin/rtsold/probe.c
index 61c47bc..6d0ea79 100644
--- a/usr.sbin/rtsold/probe.c
+++ b/usr.sbin/rtsold/probe.c
@@ -118,7 +118,7 @@ defrouter_probe(struct ifinfo *ifinfo)
goto closeandend;
}
- for (i = 0; dr.defrouter[i].if_index && i < PRLSTSIZ; i++) {
+ for (i = 0; i < DRLSTSIZ && dr.defrouter[i].if_index; i++) {
if (ifindex && dr.defrouter[i].if_index == ifindex) {
/* sanity check */
if (!IN6_IS_ADDR_LINKLOCAL(&dr.defrouter[i].rtaddr)) {
diff --git a/usr.sbin/rtsold/rtsock.c b/usr.sbin/rtsold/rtsock.c
index 0de6e85..726c1e6 100644
--- a/usr.sbin/rtsold/rtsock.c
+++ b/usr.sbin/rtsold/rtsock.c
@@ -94,9 +94,9 @@ rtsock_input(int s)
char *lim, *next;
struct rt_msghdr *rtm;
int idx;
- size_t len;
+ ssize_t len;
int ret = 0;
- const size_t lenlim =
+ const ssize_t lenlim =
offsetof(struct rt_msghdr, rtm_msglen) + sizeof(rtm->rtm_msglen);
n = read(s, msg, sizeof(msg));
@@ -135,7 +135,7 @@ rtsock_input(int s)
#ifdef RTM_IFANNOUNCE /*NetBSD 1.5 or later*/
static int
-rtsock_input_ifannounce(int s, struct rt_msghdr *rtm, char *lim)
+rtsock_input_ifannounce(int s __unused, struct rt_msghdr *rtm, char *lim)
{
struct if_announcemsghdr *ifan;
struct ifinfo *ifinfo;
diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c
index 3420f2f..be2a9b8 100644
--- a/usr.sbin/rtsold/rtsol.c
+++ b/usr.sbin/rtsold/rtsol.c
@@ -72,8 +72,10 @@ static int rcvcmsglen;
int rssock;
-static struct sockaddr_in6 sin6_allrouters =
-{sizeof(sin6_allrouters), AF_INET6};
+static struct sockaddr_in6 sin6_allrouters = {
+ .sin6_len = sizeof(sin6_allrouters),
+ .sin6_family = AF_INET6,
+};
static void call_script(char *, char *);
static int safefile(const char *);
@@ -183,7 +185,7 @@ sendpacket(struct ifinfo *ifinfo)
struct in6_pktinfo *pi;
struct cmsghdr *cm;
int hoplimit = 255;
- int i;
+ ssize_t i;
struct sockaddr_in6 dst;
dst = sin6_allrouters;
@@ -213,7 +215,7 @@ sendpacket(struct ifinfo *ifinfo)
"send RS on %s, whose state is %d",
ifinfo->ifname, ifinfo->state);
i = sendmsg(rssock, &sndmhdr, 0);
- if (i < 0 || i != ifinfo->rs_datalen) {
+ if (i < 0 || (size_t)i != ifinfo->rs_datalen) {
/*
* ENETDOWN is not so serious, especially when using several
* network cards on a mobile node. We ignore it.
@@ -231,7 +233,8 @@ void
rtsol_input(int s)
{
u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
- int ifindex = 0, i, *hlimp = NULL;
+ int ifindex = 0, *hlimp = NULL;
+ ssize_t i;
struct in6_pktinfo *pi = NULL;
struct ifinfo *ifi = NULL;
struct icmp6_hdr *icp;
@@ -272,9 +275,9 @@ rtsol_input(int s)
return;
}
- if (i < sizeof(struct nd_router_advert)) {
+ if ((size_t)i < sizeof(struct nd_router_advert)) {
warnmsg(LOG_INFO, __func__,
- "packet size(%d) is too short", i);
+ "packet size(%zd) is too short", i);
return;
}
diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c
index 93fb1eb..0db050c 100644
--- a/usr.sbin/rtsold/rtsold.c
+++ b/usr.sbin/rtsold/rtsold.c
@@ -32,15 +32,20 @@
*/
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <net/if.h>
#include <net/if_dl.h>
+#include <net/if_var.h>
#include <netinet/in.h>
#include <netinet/icmp6.h>
+#include <netinet/in_var.h>
+
+#include <netinet6/nd6.h>
#include <signal.h>
#include <unistd.h>
@@ -86,10 +91,10 @@ int main(int, char **);
static int mobile_node = 0;
#ifndef SMALL
static int do_dump;
-static char *dumpfilename = "/var/run/rtsold.dump"; /* XXX: should be configurable */
+static const char *dumpfilename = "/var/run/rtsold.dump"; /* XXX: should be configurable */
#endif
#if 1
-static char *pidfilename = "/var/run/rtsold.pid"; /* should be configurable */
+static const char *pidfilename = "/var/run/rtsold.pid"; /* should be configurable */
#endif
#if 0
@@ -108,7 +113,8 @@ main(int argc, char **argv)
{
int s, ch, once = 0;
struct timeval *timeout;
- char *argv0, *opts;
+ char *argv0;
+ const char *opts;
#ifdef HAVE_POLL_H
struct pollfd set[2];
#else
@@ -729,7 +735,7 @@ rtsol_timer_update(struct ifinfo *ifinfo)
#ifndef SMALL
static void
-rtsold_set_dump_file(int sig)
+rtsold_set_dump_file(int sig __unused)
{
do_dump = 1;
}
@@ -785,8 +791,9 @@ autoifprobe(void)
static char **argv = NULL;
static int n = 0;
char **a;
- int i, found;
+ int s = 0, i, found;
struct ifaddrs *ifap, *ifa, *target;
+ struct in6_ndireq nd;
/* initialize */
while (n--)
@@ -800,6 +807,11 @@ autoifprobe(void)
if (getifaddrs(&ifap) != 0)
return NULL;
+ if (!Fflag && (s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ err(1, "socket");
+ /* NOTREACHED */
+ }
+
target = NULL;
/* find an ethernet */
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
@@ -825,6 +837,23 @@ autoifprobe(void)
if (found)
continue;
+ /*
+ * Skip the interfaces which IPv6 and/or accepting RA
+ * is disabled.
+ */
+ if (!Fflag) {
+ memset(&nd, 0, sizeof(nd));
+ strlcpy(nd.ifname, ifa->ifa_name, sizeof(nd.ifname));
+ if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) {
+ err(1, "ioctl(SIOCGIFINFO_IN6)");
+ /* NOTREACHED */
+ }
+ if ((nd.ndi.flags & ND6_IFF_IFDISABLED))
+ continue;
+ if (!(nd.ndi.flags & ND6_IFF_ACCEPT_RTADV))
+ continue;
+ }
+
/* if we find multiple candidates, just warn. */
if (n != 0 && dflag > 1)
warnx("multiple interfaces found");
@@ -837,7 +866,6 @@ autoifprobe(void)
if (!argv[n])
err(1, "malloc");
n++;
- argv[n] = NULL;
}
if (n) {
@@ -852,6 +880,8 @@ autoifprobe(void)
warnx("probing %s", argv[i]);
}
}
+ if (!Fflag)
+ close(s);
freeifaddrs(ifap);
return argv;
}
diff --git a/usr.sbin/rtsold/rtsold.h b/usr.sbin/rtsold/rtsold.h
index 8a3cfa6..8aef490 100644
--- a/usr.sbin/rtsold/rtsold.h
+++ b/usr.sbin/rtsold/rtsold.h
@@ -97,7 +97,7 @@ extern int probe_init(void);
extern void defrouter_probe(struct ifinfo *);
/* dump.c */
-extern void rtsold_dump_file(char *);
+extern void rtsold_dump_file(const char *);
/* rtsock.c */
extern int rtsock_open(void);
diff --git a/usr.sbin/rwhod/Makefile b/usr.sbin/rwhod/Makefile
index def0e6e..f1b5d99 100644
--- a/usr.sbin/rwhod/Makefile
+++ b/usr.sbin/rwhod/Makefile
@@ -4,7 +4,6 @@
PROG= rwhod
MAN= rwhod.8
-# XXX breaks on Alpha due to alignment constraints
-#WARNS?= 4
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/usr.sbin/rwhod/rwhod.8 b/usr.sbin/rwhod/rwhod.8
index 642eeeb..59fb4ad 100644
--- a/usr.sbin/rwhod/rwhod.8
+++ b/usr.sbin/rwhod/rwhod.8
@@ -188,9 +188,8 @@ 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
+includes the contents of the entry from the user accounting database
+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
diff --git a/usr.sbin/rwhod/rwhod.c b/usr.sbin/rwhod/rwhod.c
index 96fd9ec..6b63843 100644
--- a/usr.sbin/rwhod/rwhod.c
+++ b/usr.sbin/rwhod/rwhod.c
@@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$");
#include <syslog.h>
#include <timeconv.h>
#include <unistd.h>
-#include <utmp.h>
+#include <utmpx.h>
#include <pwd.h>
#include <grp.h>
@@ -146,7 +146,7 @@ struct neighbor {
struct neighbor *neighbors;
struct whod mywd;
struct servent *sp;
-int s, utmpf;
+int s;
#define WHDRSIZE (int)(sizeof(mywd) - sizeof(mywd.wd_we))
@@ -231,11 +231,6 @@ main(int argc, char *argv[])
*cp = '\0';
strncpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname) - 1);
mywd.wd_hostname[sizeof(mywd.wd_hostname) - 1] = '\0';
- 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");
@@ -383,73 +378,43 @@ verify(name, maxlen)
return (size > 0);
}
-int utmptime;
-int utmpent;
-int utmpsize = 0;
-struct utmp *utmp;
-int alarmcount;
-
void
-onalrm(signo)
- int signo __unused;
+onalrm(int signo __unused)
{
- register struct neighbor *np;
- register struct whoent *we = mywd.wd_we, *wlast;
- register int i;
+ struct neighbor *np;
+ struct whoent *we = mywd.wd_we, *wend;
struct stat stb;
+ struct utmpx *ut;
+ static int alarmcount = 0;
double avenrun[3];
time_t now;
- int cc;
+ int i, 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);
- utmp = (struct utmp *)reallocf(utmp, utmpsize);
- if (utmp == NULL) {
- syslog(LOG_WARNING, "malloc failed");
- utmpsize = 0;
- goto done;
- }
- }
- (void) lseek(utmpf, (off_t)0, L_SET);
- cc = read(utmpf, (char *)utmp, stb.st_size);
- if (cc < 0) {
- syslog(LOG_ERR, "read(%s): %m", _PATH_UTMP);
- 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;
+ wend = &mywd.wd_we[1024 / sizeof(struct whoent)];
+ setutxent();
+ while ((ut = getutxent()) != NULL && we < wend) {
+ if (ut->ut_type != USER_PROCESS)
+ continue;
+ strncpy(we->we_utmp.out_line, ut->ut_line,
+ sizeof(we->we_utmp.out_line));
+ strncpy(we->we_utmp.out_name, ut->ut_user,
+ sizeof(we->we_utmp.out_name));
+ we->we_utmp.out_time =
+ htonl(_time_to_time32(ut->ut_tv.tv_sec));
+ we++;
}
+ endutxent();
- /*
- * 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)) {
+ if (chdir(_PATH_DEV)) {
syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV);
exit(1);
}
- we = mywd.wd_we;
- for (i = 0; i < utmpent; i++) {
+ wend = we;
+ for (we = mywd.wd_we; we < wend; we++) {
if (stat(we->we_utmp.out_line, &stb) >= 0)
we->we_idle = htonl(now - stb.st_atime);
we++;
@@ -457,7 +422,7 @@ onalrm(signo)
(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;
+ cc = (char *)wend - (char *)&mywd;
mywd.wd_sendtime = htonl(_time_to_time32(time(NULL)));
mywd.wd_vers = WHODVERSION;
mywd.wd_type = WHODTYPE_STATUS;
@@ -485,11 +450,10 @@ onalrm(signo)
} else (void) sendto(s, (char *)&mywd, cc, 0,
np->n_addr, np->n_addrlen);
}
- if (utmpent && chdir(_PATH_RWHODIR)) {
+ if (chdir(_PATH_RWHODIR)) {
syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR);
exit(1);
}
-done:
(void) alarm(AL_INTERVAL);
}
diff --git a/usr.sbin/sa/Makefile b/usr.sbin/sa/Makefile
index 718cbc8..0adf1f8 100644
--- a/usr.sbin/sa/Makefile
+++ b/usr.sbin/sa/Makefile
@@ -6,6 +6,4 @@ PROG= sa
MAN= sa.8
SRCS= main.c db.c pdb.c usrdb.c readrec.c
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/sa/main.c b/usr.sbin/sa/main.c
index 7be13e5..64736ac 100644
--- a/usr.sbin/sa/main.c
+++ b/usr.sbin/sa/main.c
@@ -300,7 +300,7 @@ main(int argc, char **argv)
}
static void
-usage()
+usage(void)
{
(void)fprintf(stderr,
"usage: sa [-abcdDfijkKlmnqrstu] [-P file] [-U file] [-v cutoff] [file ...]\n");
diff --git a/usr.sbin/sa/pdb.c b/usr.sbin/sa/pdb.c
index 38beb55..e5e35f5 100644
--- a/usr.sbin/sa/pdb.c
+++ b/usr.sbin/sa/pdb.c
@@ -94,14 +94,14 @@ v1_to_v2(DBT *key __unused, DBT *data)
/* Copy pdb_file to in-memory pacct_db. */
int
-pacct_init()
+pacct_init(void)
{
return (db_copy_in(&pacct_db, pdb_file, "process accounting",
NULL, v1_to_v2));
}
void
-pacct_destroy()
+pacct_destroy(void)
{
db_destroy(pacct_db, "process accounting");
}
@@ -150,14 +150,14 @@ pacct_add(const struct cmdinfo *ci)
/* Copy in-memory pacct_db to pdb_file. */
int
-pacct_update()
+pacct_update(void)
{
return (db_copy_out(pacct_db, pdb_file, "process accounting",
NULL));
}
void
-pacct_print()
+pacct_print(void)
{
BTREEINFO bti;
DBT key, data, ndata;
diff --git a/usr.sbin/sa/usrdb.c b/usr.sbin/sa/usrdb.c
index 07a5033..50778ef 100644
--- a/usr.sbin/sa/usrdb.c
+++ b/usr.sbin/sa/usrdb.c
@@ -97,7 +97,7 @@ v1_to_v2(DBT *key, DBT *data)
/* Copy usrdb_file to in-memory usracct_db. */
int
-usracct_init()
+usracct_init(void)
{
BTREEINFO bti;
@@ -109,7 +109,7 @@ usracct_init()
}
void
-usracct_destroy()
+usracct_destroy(void)
{
db_destroy(usracct_db, "user accounting");
}
@@ -166,7 +166,7 @@ usracct_add(const struct cmdinfo *ci)
/* Copy in-memory usracct_db to usrdb_file. */
int
-usracct_update()
+usracct_update(void)
{
BTREEINFO bti;
@@ -178,7 +178,7 @@ usracct_update()
}
void
-usracct_print()
+usracct_print(void)
{
DBT key, data;
struct userinfo uistore, *ui = &uistore;
diff --git a/usr.sbin/sade/termcap.c b/usr.sbin/sade/termcap.c
index 3e80a41..1c2f39b 100644
--- a/usr.sbin/sade/termcap.c
+++ b/usr.sbin/sade/termcap.c
@@ -83,13 +83,13 @@ set_termcap(void)
#else
if (ColorDisplay) {
if (!term) {
- if (setenv("TERM", "cons25", 1) < 0)
+ if (setenv("TERM", "xterm", 1) < 0)
return -1;
}
}
else {
if (!term) {
- if (setenv("TERM", "cons25-m", 1) < 0)
+ if (setenv("TERM", "vt100", 1) < 0)
return -1;
}
}
diff --git a/usr.sbin/sendmail/Makefile b/usr.sbin/sendmail/Makefile
index 0b89297..a9f7fbb 100644
--- a/usr.sbin/sendmail/Makefile
+++ b/usr.sbin/sendmail/Makefile
@@ -43,6 +43,8 @@ CFLAGS+= ${DBMDEF} ${NIS} -DTCPWRAPPERS ${MAPS}
CFLAGS+= -DNETINET6
.endif
+WARNS?= 1
+
DPADD= ${LIBUTIL} ${LIBWRAP}
LDADD= -lutil -lwrap
diff --git a/usr.sbin/service/Makefile b/usr.sbin/service/Makefile
new file mode 100644
index 0000000..a03714d
--- /dev/null
+++ b/usr.sbin/service/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+SCRIPTS=service.sh
+MAN= service.8
+
+.include <bsd.prog.mk>
+
diff --git a/usr.sbin/service/service.8 b/usr.sbin/service/service.8
new file mode 100644
index 0000000..a7f3135
--- /dev/null
+++ b/usr.sbin/service/service.8
@@ -0,0 +1,131 @@
+.\" Copyright (c) 2009 Douglas Barton
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 26, 2009
+.Dt service 8
+.Os
+.Sh NAME
+.Nm service
+.Nd "control (start/stop/etc.) or list system services"
+.Sh SYNOPSIS
+.Nm
+.Fl e
+.Nm
+.Op Fl v
+.Fl l | r
+.Nm
+.Op Fl v
+.Ar <rc.d script> start|stop|etc.
+.Sh DESCRIPTION
+The
+.Nm
+command is an easy interface to the rc.d system.
+Its primary purpose is to start and stop services provided
+by the rc.d scripts.
+When used for this purpose it will set the same restricted
+environment that is in use at boot time (see below).
+It can also be used to list
+the scripts using various criteria.
+.Pp
+The options are as follows:
+.Bl -tag -width F1
+.It Fl e
+List services that are enabled.
+The list of scripts to check is compiled using
+.Xr rcorder 8
+the same way that it is done in
+.Xr rc 8 ,
+then that list of scripts is checked for an
+.Qq rcvar
+assignment.
+If present the script is checked to see if it is enabled.
+.It Fl l
+List all files in
+.Pa /etc/rc.d
+and the local startup directories.
+As described in
+.Xr rc.conf 5
+this is usually
+.Pa /usr/local/etc/rc.d .
+All files will be listed whether they are an actual
+rc.d script or not.
+.It Fl r
+Generate the
+.Xr rcorder 8
+as in
+.Fl e
+above, but list all of the files, not just what is enabled.
+.It Fl v
+Be slightly more verbose
+.El
+.Sh ENVIRONMENT
+When used to run rc.d scripts the
+.Nm
+command sets
+.Ev HOME
+to
+.Pa /
+and
+.Ev PATH
+to
+.Pa /sbin:/bin:/usr/sbin:/usr/bin
+which is how they are set in
+.Pa /etc/rc
+at boot time.
+.Sh EXIT STATUS
+.Ex -std
+.Sh EXAMPLES
+The following are examples of typical usage of the
+.Nm
+command:
+.Pp
+.Dl "service named status"
+.Dl "service -rv"
+.Pp
+The following programmable completion entry can be use in
+.Xr bash 1
+for the names of the rc.d scripts:
+.Dl "_service () {"
+.Dl " local cur"
+.Dl " cur=${COMP_WORDS[COMP_CWORD]}"
+.Dl " COMPREPLY=( $( compgen -W '$( service -l )' -- $cur ) )"
+.Dl " return 0"
+.Dl "}"
+.Dl "complete -F _service service"
+.Sh SEE ALSO
+.Xr bash 1 Pq Pa ports/shells/bash ,
+.Xr rc.conf 5 ,
+.Xr rc 8 ,
+.Xr rcorder 8
+.Sh HISTORY
+The
+.Nm
+manual page service first appeared in
+.Fx 7.3 .
+.Sh AUTHORS
+This
+manual page was written by
+.An Douglas Barton <dougb@FreeBSD.org> .
diff --git a/usr.sbin/service/service.sh b/usr.sbin/service/service.sh
new file mode 100755
index 0000000..1794315
--- /dev/null
+++ b/usr.sbin/service/service.sh
@@ -0,0 +1,120 @@
+#!/bin/sh
+
+# $FreeBSD$
+
+# Copyright (c) 2009 Douglas Barton
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must 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.
+
+. /etc/rc.subr
+load_rc_config 'XXX'
+
+usage () {
+ echo ''
+ echo 'Usage:'
+ echo "${0##*/} -e"
+ echo "${0##*/} [-v] -l | -r"
+ echo "${0##*/} [-v] <rc.d script> start|stop|etc."
+ echo "${0##*/} -h"
+ echo ''
+ echo '-e Show services that are enabled'
+ echo "-l List all scripts in /etc/rc.d and $local_startup"
+ echo '-r Show the results of boot time rcorder'
+ echo '-v Verbose'
+ echo ''
+}
+
+while getopts 'ehlrv' COMMAND_LINE_ARGUMENT ; do
+ case "${COMMAND_LINE_ARGUMENT}" in
+ e) ENABLED=eopt ;;
+ h) usage ; exit 0 ;;
+ l) LIST=lopt ;;
+ r) RCORDER=ropt ;;
+ v) VERBOSE=vopt ;;
+ *) usage ; exit 1 ;;
+ esac
+done
+shift $(( $OPTIND - 1 ))
+
+if [ -n "$ENABLED" -o -n "$RCORDER" ]; then
+ # Copied from /etc/rc
+ skip="-s nostart"
+ if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then
+ skip="$skip -s nojail"
+ fi
+ [ -n "$local_startup" ] && find_local_scripts_new
+ files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null`
+fi
+
+if [ -n "$ENABLED" ]; then
+ for file in $files; do
+ if grep -q ^rcvar $file; then
+ eval `grep ^name= $file`
+ eval `grep ^rcvar $file`
+ checkyesno $rcvar 2>/dev/null && echo $file
+ fi
+ done
+ exit 0
+fi
+
+if [ -n "$LIST" ]; then
+ for dir in /etc/rc.d $local_startup; do
+ [ -n "$VERBOSE" ] && echo "From ${dir}:"
+ cd $dir && for file in *; do echo $file; done
+ done
+ exit 0
+fi
+
+if [ -n "$RCORDER" ]; then
+ for file in $files; do
+ echo $file
+ if [ -n "$VERBOSE" ]; then
+ case "$file" in
+ */${early_late_divider})
+ echo '========= Early/Late Divider =========' ;;
+ esac
+ fi
+ done
+ exit 0
+fi
+
+if [ $# -gt 1 ]; then
+ script=$1
+ shift
+else
+ usage
+ exit 1
+fi
+
+cd /
+for dir in /etc/rc.d $local_startup; do
+ if [ -x "$dir/$script" ]; then
+ [ -n "$VERBOSE" ] && echo "$script is located in $dir"
+ exec env -i HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin $dir/$script $*
+ fi
+done
+
+# If the script was not found
+echo "$script does not exist in /etc/rc.d or the local startup"
+echo "directories (${local_startup})"
+exit 1
diff --git a/usr.sbin/setfmac/Makefile b/usr.sbin/setfmac/Makefile
index 34b979b..bcbd85f 100644
--- a/usr.sbin/setfmac/Makefile
+++ b/usr.sbin/setfmac/Makefile
@@ -4,6 +4,4 @@ PROG= setfmac
LINKS= ${BINDIR}/setfmac ${BINDIR}/setfsmac
MAN= setfmac.8 setfsmac.8
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/setpmac/Makefile b/usr.sbin/setpmac/Makefile
index ae7ee02..a8bc1ac 100644
--- a/usr.sbin/setpmac/Makefile
+++ b/usr.sbin/setpmac/Makefile
@@ -3,6 +3,4 @@
PROG= setpmac
MAN= setpmac.8
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/smbmsg/Makefile b/usr.sbin/smbmsg/Makefile
index a581b2c..2ae6404 100644
--- a/usr.sbin/smbmsg/Makefile
+++ b/usr.sbin/smbmsg/Makefile
@@ -3,6 +3,5 @@
PROG= smbmsg
MAN= smbmsg.8
-WARNS= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/smbmsg/smbmsg.8 b/usr.sbin/smbmsg/smbmsg.8
index efc7451..2b83979 100644
--- a/usr.sbin/smbmsg/smbmsg.8
+++ b/usr.sbin/smbmsg/smbmsg.8
@@ -273,7 +273,7 @@ Diagnostic messages issued are supposed to be self-explanatory.
.Xr smbus 4
.Rs
.%T "The SMBus specification"
-.%O http://www.smbus.org/specs/
+.%U http://www.smbus.org/specs/
.Re
.Sh HISTORY
The
diff --git a/usr.sbin/snapinfo/snapinfo.c b/usr.sbin/snapinfo/snapinfo.c
index 55b54a5..3ee66da 100644
--- a/usr.sbin/snapinfo/snapinfo.c
+++ b/usr.sbin/snapinfo/snapinfo.c
@@ -140,7 +140,7 @@ find_snapshot(struct statfs *sfs)
int
compare_function(const char *path, const struct stat *st, int flags,
-struct FTW * ftwv)
+ struct FTW * ftwv __unused)
{
if (flags == FTW_F && st->st_ino == inode) {
diff --git a/usr.sbin/sysinstall/Makefile b/usr.sbin/sysinstall/Makefile
index 3f2b758..bd08ac1 100644
--- a/usr.sbin/sysinstall/Makefile
+++ b/usr.sbin/sysinstall/Makefile
@@ -20,40 +20,11 @@ CFLAGS+= -DPC98
.endif
CFLAGS+= -I${.CURDIR}/../../gnu/lib/libdialog -I.
+WARNS?= 1
+
DPADD= ${LIBDIALOG} ${LIBNCURSES} ${LIBUTIL} ${LIBDISK} ${LIBFTPIO}
LDADD= -ldialog -lncurses -lutil -ldisk -lftpio
-#
-# When distributions have both UP and SMP kernels sysinstall
-# will probe for the number of cpus on the target machine and
-# automatically select which is appropriate. This can be overridden
-# through the menus or both kernels can be installed (with the
-# most "appropriate" one setup as /boot/kernel). For now this
-# is done for i386 and amd64; for other systems support must be
-# added to identify the cpu count if acpi and MPTable probing
-# is insufficient.
-#
-# The unmber of cpus probed is passed through the environment in
-# VAR_NCPUS ("ncpus") to scripts.
-#
-# Note that WITH_SMP is a compile time option that enables the
-# builtin menus for the SMP kernel configuration. If this kernel
-# is not built (see release/Makefile) then this should not be
-# enabled as sysinstall may try to select an SMP kernel config
-# where none is available. This option should not be needed--we
-# should probe for an SMP kernel in the distribution but doing
-# that is painful because of media changes and the structure of
-# sysinstall so for now it's a priori.
-#
-.if ${MACHINE} == "i386" || ${MACHINE_ARCH} == "amd64"
-SRCS+= acpi.c biosmptable.c
-.if exists(${.CURDIR}/../../sys/${MACHINE}/conf/SMP)
-CFLAGS+=-DWITH_SMP
-.endif
-DPADD+= ${LIBDEVINFO}
-LDADD+= -ldevinfo
-.endif
-
CLEANFILES= makedevs.c rtermcap
CLEANFILES+= keymap.tmp keymap.h countries.tmp countries.h
diff --git a/usr.sbin/sysinstall/acpi.c b/usr.sbin/sysinstall/acpi.c
deleted file mode 100644
index 4a375a1..0000000
--- a/usr.sbin/sysinstall/acpi.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*-
- * Copyright (c) 1998 Doug Rabson
- * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/endian.h>
-#include <sys/mman.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/wait.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <paths.h>
-#include <devinfo.h>
-
-#include "acpidump.h"
-#include "sysinstall.h"
-
-static void acpi_handle_apic(struct ACPIsdt *sdp);
-static struct ACPIsdt *acpi_map_sdt(vm_offset_t pa);
-static void acpi_handle_rsdt(struct ACPIsdt *rsdp);
-static struct acpi_user_mapping *acpi_user_find_mapping(vm_offset_t, size_t);
-static void * acpi_map_physical(vm_offset_t, size_t);
-
-/* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
-static int addr_size;
-
-static int ncpu;
-
-static void
-acpi_handle_apic(struct ACPIsdt *sdp)
-{
- struct MADTbody *madtp;
- struct MADT_APIC *mp;
- struct MADT_local_apic *apic;
- struct MADT_local_sapic *sapic;
-
- madtp = (struct MADTbody *) sdp->body;
- mp = (struct MADT_APIC *)madtp->body;
- while (((uintptr_t)mp) - ((uintptr_t)sdp) < sdp->len) {
- switch (mp->type) {
- case ACPI_MADT_APIC_TYPE_LOCAL_APIC:
- apic = &mp->body.local_apic;
- msgDebug("MADT: Found CPU APIC ID %d %s\n",
- apic->cpu_id,
- apic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED ?
- "enabled" : "disabled");
- if (apic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED)
- ncpu++;
- break;
- case ACPI_MADT_APIC_TYPE_LOCAL_SAPIC:
- sapic = &mp->body.local_sapic;
- msgDebug("MADT: Found CPU SAPIC ID %d %s\n",
- sapic->cpu_id,
- sapic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED ?
- "enabled" : "disabled");
- /* XXX is enable flag the same? */
- if (sapic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED)
- ncpu++;
- break;
- default:
- break;
- }
- mp = (struct MADT_APIC *) ((char *)mp + mp->len);
- }
-}
-
-static int
-acpi_checksum(void *p, size_t length)
-{
- u_int8_t *bp;
- u_int8_t sum;
-
- bp = p;
- sum = 0;
- while (length--)
- sum += *bp++;
-
- return (sum);
-}
-
-static struct ACPIsdt *
-acpi_map_sdt(vm_offset_t pa)
-{
- struct ACPIsdt *sp;
-
- sp = acpi_map_physical(pa, sizeof(struct ACPIsdt));
- if (sp != NULL)
- sp = acpi_map_physical(pa, sp->len);
- return (sp);
-}
-
-static void
-acpi_handle_rsdt(struct ACPIsdt *rsdp)
-{
- struct ACPIsdt *sdp;
- vm_offset_t addr;
- int entries, i;
-
- entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size;
- for (i = 0; i < entries; i++) {
- switch (addr_size) {
- case 4:
- addr = le32dec((char*)rsdp->body + i * addr_size);
- break;
- case 8:
- addr = le64dec((char*)rsdp->body + i * addr_size);
- break;
- default:
- assert((addr = 0));
- }
-
- sdp = (struct ACPIsdt *)acpi_map_sdt(addr);
- if (sdp == NULL) {
- msgDebug("%s: unable to map sdt\n", __func__);
- continue;
- }
- if (acpi_checksum(sdp, sdp->len)) {
-#if 0
- msgDebug("RSDT entry %d (sig %.4s) has bad checksum\n",
- i, sdp->signature);
-#endif
- continue;
- }
- if (!memcmp(sdp->signature, "APIC", 4))
- acpi_handle_apic(sdp);
- }
-}
-
-static char machdep_acpi_root[] = "machdep.acpi_root";
-static int acpi_mem_fd = -1;
-
-struct acpi_user_mapping {
- LIST_ENTRY(acpi_user_mapping) link;
- vm_offset_t pa;
- caddr_t va;
- size_t size;
-};
-
-LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping) maplist;
-
-static int
-acpi_user_init(void)
-{
-
- if (acpi_mem_fd == -1) {
- acpi_mem_fd = open(_PATH_MEM, O_RDONLY);
- if (acpi_mem_fd == -1) {
- msgDebug("%s: error opening %s: %s\n", __func__,
- _PATH_MEM, strerror(errno));
- return 0;
- }
- LIST_INIT(&maplist);
- }
- return 1;
-}
-
-static struct acpi_user_mapping *
-acpi_user_find_mapping(vm_offset_t pa, size_t size)
-{
- struct acpi_user_mapping *map;
-
- /* First search for an existing mapping */
- for (map = LIST_FIRST(&maplist); map; map = LIST_NEXT(map, link)) {
- if (map->pa <= pa && map->size >= pa + size - map->pa)
- return (map);
- }
-
- /* Then create a new one */
- size = round_page(pa + size) - trunc_page(pa);
- pa = trunc_page(pa);
- map = malloc(sizeof(struct acpi_user_mapping));
- if (!map) {
- msgDebug("%s: out of memory: %s\n", __func__, strerror(errno));
- return (map);
- }
- map->pa = pa;
- map->va = mmap(0, size, PROT_READ, MAP_SHARED, acpi_mem_fd, pa);
- map->size = size;
- if ((intptr_t) map->va == -1) {
- msgDebug("%s: can't mmap address %lu size %lu: %s\n", __func__,
- (unsigned long) pa, (unsigned long) size, strerror(errno));
- free(map);
- return (NULL);
- }
- LIST_INSERT_HEAD(&maplist, map, link);
-
- return (map);
-}
-
-static void *
-acpi_map_physical(vm_offset_t pa, size_t size)
-{
- struct acpi_user_mapping *map;
-
- map = acpi_user_find_mapping(pa, size);
- return (map == NULL ? NULL : map->va + (pa - map->pa));
-}
-
-static struct ACPIrsdp *
-acpi_get_rsdp(u_long addr)
-{
- struct ACPIrsdp rsdp;
- size_t len;
-
- /* Read in the table signature and check it. */
- pread(acpi_mem_fd, &rsdp, 8, addr);
- if (memcmp(rsdp.signature, "RSD PTR ", 8))
- return (NULL);
-
- /* Read the entire table. */
- pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr);
-
- /* Run the checksum only over the version 1 header. */
- if (acpi_checksum(&rsdp, 20))
- return (NULL);
-
- /* If the revision is 0, assume a version 1 length. */
- if (rsdp.revision == 0)
- len = 20;
- else
- len = rsdp.length;
-
- /* XXX Should handle ACPI 2.0 RSDP extended checksum here. */
-
- return (acpi_map_physical(addr, len));
-}
-
-static const char *
-devstate(devinfo_state_t state)
-{
- switch (state) {
- case DIS_NOTPRESENT:
- return "not-present";
- case DIS_ALIVE:
- return "alive";
- case DIS_ATTACHED:
- return "attached";
- case DIS_BUSY:
- return "busy";
- default:
- return "unknown-state";
- }
-}
-
-static int
-acpi0_check(struct devinfo_dev *dd, void *arg)
-{
- printf("%s: %s %s\n", __func__, dd->dd_name, devstate(dd->dd_state));
- /* NB: device must be present AND attached */
- if (strcmp(dd->dd_name, "acpi0") == 0)
- return (dd->dd_state == DIS_ATTACHED ||
- dd->dd_state == DIS_BUSY);
- return devinfo_foreach_device_child(dd, acpi0_check, arg);
-}
-
-static int
-acpi0_present(void)
-{
- struct devinfo_dev *root;
- int found;
-
- found = 0;
- devinfo_init();
- root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE);
- if (root != NULL)
- found = devinfo_foreach_device_child(root, acpi0_check, NULL);
- devinfo_free();
- return found;
-}
-
-int
-acpi_detect(void)
-{
- struct ACPIrsdp *rp;
- struct ACPIsdt *rsdp;
- u_long addr;
- size_t len;
-
- if (!acpi0_present()) {
- msgDebug("%s: no acpi0 device located\n", __func__);
- return -1;
- }
-
- if (!acpi_user_init())
- return -1;
-
- /* Attempt to use sysctl to find RSD PTR record. */
- len = sizeof(addr);
- if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) != 0) {
- msgDebug("%s: cannot find ACPI information\n", __func__);
- return -1;
- }
- rp = acpi_get_rsdp(addr);
- if (rp == NULL) {
- msgDebug("%s: cannot find ACPI information: "
- "sysctl %s does not point to RSDP\n", __func__,
- machdep_acpi_root);
- return -1;
- }
- if (rp->revision < 2) {
- rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr);
- if (rsdp == NULL)
- return -1;
- if (memcmp(rsdp->signature, "RSDT", 4) != 0 ||
- acpi_checksum(rsdp, rsdp->len) != 0) {
- msgDebug("%s: RSDT is corrupted\n", __func__);
- return -1;
- }
- addr_size = sizeof(uint32_t);
- } else {
- rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->xsdt_addr);
- if (rsdp == NULL)
- return -1;
- if (memcmp(rsdp->signature, "XSDT", 4) != 0 ||
- acpi_checksum(rsdp, rsdp->len) != 0) {
- msgDebug("%s: XSDT is corrupted\n", __func__);
- return -1;
- }
- addr_size = sizeof(uint64_t);
- }
- ncpu = 0;
- acpi_handle_rsdt(rsdp);
- return (ncpu == 0 ? 1 : ncpu);
-}
diff --git a/usr.sbin/sysinstall/acpidump.h b/usr.sbin/sysinstall/acpidump.h
deleted file mode 100644
index 9c2b5b6..0000000
--- a/usr.sbin/sysinstall/acpidump.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*-
- * Copyright (c) 1999 Doug Rabson
- * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _ACPIDUMP_H_
-#define _ACPIDUMP_H_
-
-/* Root System Description Pointer */
-struct ACPIrsdp {
- u_char signature[8];
- u_char sum;
- u_char oem[6];
- u_char revision;
- u_int32_t rsdt_addr;
- u_int32_t length;
- u_int64_t xsdt_addr;
- u_char xsum;
- u_char _reserved_[3];
-} __packed;
-
-/* System Description Table */
-struct ACPIsdt {
- u_char signature[4];
- u_int32_t len;
- u_char rev;
- u_char check;
- u_char oemid[6];
- u_char oemtblid[8];
- u_int32_t oemrev;
- u_char creator[4];
- u_int32_t crerev;
-#define SIZEOF_SDT_HDR 36 /* struct size except body */
- u_int32_t body[1];/* This member should be casted */
-} __packed;
-
-struct MADT_local_apic {
- u_char cpu_id;
- u_char apic_id;
- u_int32_t flags;
-#define ACPI_MADT_APIC_LOCAL_FLAG_ENABLED 1
-} __packed;
-
-struct MADT_io_apic {
- u_char apic_id;
- u_char reserved;
- u_int32_t apic_addr;
- u_int32_t int_base;
-} __packed;
-
-struct MADT_int_override {
- u_char bus;
- u_char source;
- u_int32_t intr;
- u_int16_t mps_flags;
-#define MPS_INT_FLAG_POLARITY_MASK 0x3
-#define MPS_INT_FLAG_POLARITY_CONFORM 0x0
-#define MPS_INT_FLAG_POLARITY_HIGH 0x1
-#define MPS_INT_FLAG_POLARITY_LOW 0x3
-#define MPS_INT_FLAG_TRIGGER_MASK 0xc
-#define MPS_INT_FLAG_TRIGGER_CONFORM 0x0
-#define MPS_INT_FLAG_TRIGGER_EDGE 0x4
-#define MPS_INT_FLAG_TRIGGER_LEVEL 0xc
-} __packed;
-
-struct MADT_nmi {
- u_int16_t mps_flags;
- u_int32_t intr;
-} __packed;
-
-struct MADT_local_nmi {
- u_char cpu_id;
- u_int16_t mps_flags;
- u_char lintpin;
-} __packed;
-
-struct MADT_local_apic_override {
- u_char reserved[2];
- u_int64_t apic_addr;
-} __packed;
-
-struct MADT_io_sapic {
- u_char apic_id;
- u_char reserved;
- u_int32_t int_base;
- u_int64_t apic_addr;
-} __packed;
-
-struct MADT_local_sapic {
- u_char cpu_id;
- u_char apic_id;
- u_char apic_eid;
- u_char reserved[3];
- u_int32_t flags;
-} __packed;
-
-struct MADT_int_src {
- u_int16_t mps_flags;
- u_char type;
-#define ACPI_MADT_APIC_INT_SOURCE_PMI 1
-#define ACPI_MADT_APIC_INT_SOURCE_INIT 2
-#define ACPI_MADT_APIC_INT_SOURCE_CPEI 3 /* Corrected Platform Error */
- u_char cpu_id;
- u_char cpu_eid;
- u_char sapic_vector;
- u_int32_t intr;
- u_char reserved[4];
-} __packed;
-
-struct MADT_APIC {
- u_char type;
-#define ACPI_MADT_APIC_TYPE_LOCAL_APIC 0
-#define ACPI_MADT_APIC_TYPE_IO_APIC 1
-#define ACPI_MADT_APIC_TYPE_INT_OVERRIDE 2
-#define ACPI_MADT_APIC_TYPE_NMI 3
-#define ACPI_MADT_APIC_TYPE_LOCAL_NMI 4
-#define ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE 5
-#define ACPI_MADT_APIC_TYPE_IO_SAPIC 6
-#define ACPI_MADT_APIC_TYPE_LOCAL_SAPIC 7
-#define ACPI_MADT_APIC_TYPE_INT_SRC 8
- u_char len;
- union {
- struct MADT_local_apic local_apic;
- struct MADT_io_apic io_apic;
- struct MADT_int_override int_override;
- struct MADT_nmi nmi;
- struct MADT_local_nmi local_nmi;
- struct MADT_local_apic_override local_apic_override;
- struct MADT_io_sapic io_sapic;
- struct MADT_local_sapic local_sapic;
- struct MADT_int_src int_src;
- } body;
-} __packed;
-
-struct MADTbody {
- u_int32_t lapic_addr;
- u_int32_t flags;
-#define ACPI_APIC_FLAG_PCAT_COMPAT 1 /* System has dual-8259 setup. */
- u_char body[1];
-} __packed;
-
-/*
- * Addresses to scan on ia32 for the RSD PTR. According to section 5.2.2
- * of the ACPI spec, we only consider two regions for the base address:
- * 1. EBDA (1 KB area addressed to by 16 bit pointer at 0x40E)
- * 2. High memory (0xE0000 - 0xFFFFF)
- */
-#define RSDP_EBDA_PTR 0x40E
-#define RSDP_EBDA_SIZE 0x400
-#define RSDP_HI_START 0xE0000
-#define RSDP_HI_SIZE 0x20000
-
-#endif /* !_ACPIDUMP_H_ */
diff --git a/usr.sbin/sysinstall/biosmptable.c b/usr.sbin/sysinstall/biosmptable.c
deleted file mode 100644
index 5a507bd..0000000
--- a/usr.sbin/sysinstall/biosmptable.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*-
- * Copyright (c) 2005 Sandvine Incorporated. All righs reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must 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.
- *
- * Author: Ed Maste <emaste@phaedrus.sandvine.ca>
- */
-
-/*
- * This module detects Intel Multiprocessor spec info (mptable) and returns
- * the number of cpu's identified.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <machine/mptable.h>
-
-#include <err.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <paths.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "sysinstall.h"
-
-#define MPFPS_SIG "_MP_"
-#define MPCTH_SIG "PCMP"
-
-#define PTOV(pa) ((off_t)(pa))
-
-static mpfps_t biosmptable_find_mpfps(void);
-static mpfps_t biosmptable_search_mpfps(off_t base, int length);
-static mpcth_t biosmptable_check_mpcth(off_t addr);
-
-static int memopen(void);
-static void memclose(void);
-
-int
-biosmptable_detect(void)
-{
- mpfps_t mpfps;
- mpcth_t mpcth;
- char *entry_type_p;
- proc_entry_ptr proc;
- int ncpu, i;
-
- if (!memopen())
- return -1; /* XXX 0? */
- /* locate and validate the mpfps */
- mpfps = biosmptable_find_mpfps();
- mpcth = NULL;
- if (mpfps == NULL) {
- ncpu = 0;
- } else if (mpfps->config_type != 0) {
- /*
- * If thie config_type is nonzero then this is a default configuration
- * from Chapter 5 in the MP spec. Report 2 cpus and 1 I/O APIC.
- */
- ncpu = 2;
- } else {
- ncpu = 0;
- mpcth = biosmptable_check_mpcth(PTOV(mpfps->pap));
- if (mpcth != NULL) {
- entry_type_p = (char *)(mpcth + 1);
- for (i = 0; i < mpcth->entry_count; i++) {
- switch (*entry_type_p) {
- case 0:
- entry_type_p += sizeof(struct PROCENTRY);
- proc = (proc_entry_ptr) entry_type_p;
- msgDebug("MPTable: Found CPU APIC ID %d %s\n",
- proc->apic_id,
- proc->cpu_flags & PROCENTRY_FLAG_EN ?
- "enabled" : "disabled");
- if (proc->cpu_flags & PROCENTRY_FLAG_EN)
- ncpu++;
- break;
- case 1:
- entry_type_p += sizeof(struct BUSENTRY);
- break;
- case 2:
- entry_type_p += sizeof(struct IOAPICENTRY);
- break;
- case 3:
- case 4:
- entry_type_p += sizeof(struct INTENTRY);
- break;
- default:
- msgDebug("%s: unknown mptable entry type (%d)\n",
- __func__, *entry_type_p);
- goto done; /* XXX error return? */
- }
- }
- done:
- ;
- }
- }
- memclose();
- if (mpcth != NULL)
- free(mpcth);
- if (mpfps != NULL)
- free(mpfps);
-
- return ncpu;
-}
-
-static int pfd = -1;
-
-static int
-memopen(void)
-{
- if (pfd < 0) {
- pfd = open(_PATH_MEM, O_RDONLY);
- if (pfd < 0)
- warn("%s: cannot open", _PATH_MEM);
- }
- return pfd >= 0;
-}
-
-static void
-memclose(void)
-{
- if (pfd >= 0) {
- close(pfd);
- pfd = -1;
- }
-}
-
-static int
-memread(off_t addr, void* entry, size_t size)
-{
- if ((size_t)pread(pfd, entry, size, addr) != size) {
- warn("pread (%zu @ 0x%llx)", size, addr);
- return 0;
- }
- return 1;
-}
-
-
-/*
- * Find the MP Floating Pointer Structure. See the MP spec section 4.1.
- */
-static mpfps_t
-biosmptable_find_mpfps(void)
-{
- mpfps_t mpfps;
- uint16_t addr;
-
- /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
- if (!memread(PTOV(0x40E), &addr, sizeof(addr)))
- return (NULL);
- mpfps = biosmptable_search_mpfps(PTOV(addr << 4), 0x400);
- if (mpfps != NULL)
- return (mpfps);
-
- /* Check the BIOS. */
- mpfps = biosmptable_search_mpfps(PTOV(0xf0000), 0x10000);
- if (mpfps != NULL)
- return (mpfps);
-
- return (NULL);
-}
-
-static mpfps_t
-biosmptable_search_mpfps(off_t base, int length)
-{
- mpfps_t mpfps;
- u_int8_t *cp, sum;
- int ofs, idx;
-
- mpfps = malloc(sizeof(*mpfps));
- if (mpfps == NULL) {
- msgDebug("%s: unable to malloc space for "
- "MP Floating Pointer Structure\n", __func__);
- return (NULL);
- }
- /* search on 16-byte boundaries */
- for (ofs = 0; ofs < length; ofs += 16) {
- if (!memread(base + ofs, mpfps, sizeof(*mpfps)))
- break;
-
- /* compare signature, validate checksum */
- if (!strncmp(mpfps->signature, MPFPS_SIG, strlen(MPFPS_SIG))) {
- cp = (u_int8_t *)mpfps;
- sum = 0;
- /* mpfps is 16 bytes, or one "paragraph" */
- if (mpfps->length != 1) {
- msgDebug("%s: bad mpfps length (%d)\n",
- __func__, mpfps->length);
- continue;
- }
- for (idx = 0; idx < mpfps->length * 16; idx++)
- sum += *(cp + idx);
- if (sum != 0) {
- msgDebug("%s: bad mpfps checksum (%d)\n", __func__, sum);
- continue;
- }
- return (mpfps);
- }
- }
- free(mpfps);
- return (NULL);
-}
-
-static mpcth_t
-biosmptable_check_mpcth(off_t addr)
-{
- mpcth_t mpcth;
- u_int8_t *cp, sum;
- int idx, table_length;
-
- /* mpcth must be in the first 1MB */
- if ((u_int32_t)addr >= 1024 * 1024) {
- msgDebug("%s: bad mpcth address (0x%llx)\n", __func__, addr);
- return (NULL);
- }
-
- mpcth = malloc(sizeof(*mpcth));
- if (mpcth == NULL) {
- msgDebug("%s: unable to malloc space for "
- "MP Configuration Table Header\n", __func__);
- return (NULL);
- }
- if (!memread(addr, mpcth, sizeof(*mpcth)))
- goto bad;
- /* Compare signature and validate checksum. */
- if (strncmp(mpcth->signature, MPCTH_SIG, strlen(MPCTH_SIG)) != 0) {
- msgDebug("%s: bad mpcth signature\n", __func__);
- goto bad;
- }
- table_length = mpcth->base_table_length;
- mpcth = realloc(mpcth, table_length);
- if (mpcth == NULL) {
- msgDebug("%s: unable to realloc space for mpcth (len %u)\n",
- __func__, table_length);
- return (NULL);
- }
- if (!memread(addr, mpcth, table_length))
- goto bad;
- cp = (u_int8_t *)mpcth;
- sum = 0;
- for (idx = 0; idx < mpcth->base_table_length; idx++)
- sum += *(cp + idx);
- if (sum != 0) {
- msgDebug("%s: bad mpcth checksum (%d)\n", __func__, sum);
- goto bad;
- }
-
- return mpcth;
-bad:
- free(mpcth);
- return (NULL);
-}
diff --git a/usr.sbin/sysinstall/cdrom.c b/usr.sbin/sysinstall/cdrom.c
index a5029ec..6bc72d8 100644
--- a/usr.sbin/sysinstall/cdrom.c
+++ b/usr.sbin/sysinstall/cdrom.c
@@ -43,6 +43,7 @@
#include <sys/errno.h>
#include <sys/param.h>
#include <sys/wait.h>
+#include <sys/cdio.h>
#include <unistd.h>
#include <grp.h>
#include <fcntl.h>
@@ -58,6 +59,8 @@ static Boolean previouslyMounted; /* Was the disc already mounted? */
static char mountpoint[MAXPATHLEN] = "/dist";
int CDROMInitQuiet;
+static void mediaEjectCDROM(Device *dev);
+
static properties
read_props(char *name)
{
@@ -218,4 +221,24 @@ mediaShutdownCDROM(Device *dev)
msgConfirm("Could not unmount the CDROM/DVD from %s: %s", mountpoint, strerror(errno));
else
cdromMounted = FALSE;
+
+ mediaEjectCDROM(dev);
+}
+
+static void
+mediaEjectCDROM(Device *dev)
+{
+ int fd = -1;
+
+ msgDebug("Ejecting CDROM/DVD at %s", dev->devname);
+
+ fd = open(dev->devname, O_RDONLY);
+
+ if (fd < 0)
+ msgDebug("Could not eject the CDROM/DVD from %s: %s", dev->devname, strerror(errno));
+ else {
+ ioctl(fd, CDIOCALLOW);
+ ioctl(fd, CDIOCEJECT);
+ close(fd);
+ }
}
diff --git a/usr.sbin/sysinstall/devices.c b/usr.sbin/sysinstall/devices.c
index b95fdc5..a2b7939 100644
--- a/usr.sbin/sysinstall/devices.c
+++ b/usr.sbin/sysinstall/devices.c
@@ -105,6 +105,7 @@ static struct _devname {
NETWORK("bfe", "Broadcom BCM440x PCI Ethernet card"),
NETWORK("bge", "Broadcom BCM570x PCI Gigabit Ethernet card"),
NETWORK("bm", "Apple BMAC Built-in Ethernet"),
+ NETWORK("bwn", "Broadcom BCM43xx IEEE 802.11 wireless adapter"),
NETWORK("cas", "Sun Cassini/Cassini+ or NS DP83065 Saturn Ethernet"),
NETWORK("cue", "CATC USB Ethernet adapter"),
NETWORK("cxgb", "Chelsio T3 10Gb Ethernet card"),
diff --git a/usr.sbin/sysinstall/disks.c b/usr.sbin/sysinstall/disks.c
index 919b97d..a1c09b6 100644
--- a/usr.sbin/sysinstall/disks.c
+++ b/usr.sbin/sysinstall/disks.c
@@ -333,7 +333,7 @@ diskGetSelectCount(Device ***devs)
void
diskPartition(Device *dev)
{
- char *cp, *p;
+ char *p;
int rv, key = 0;
int i;
Boolean chunking;
diff --git a/usr.sbin/sysinstall/dist.c b/usr.sbin/sysinstall/dist.c
index 3c84a1d..1a2dd5b 100644
--- a/usr.sbin/sysinstall/dist.c
+++ b/usr.sbin/sysinstall/dist.c
@@ -99,9 +99,6 @@ static Distribution DistTable[] = {
/* The kernel distributions */
static Distribution KernelDistTable[] = {
DTE_TARBALL("GENERIC", &KernelDists, KERNEL_GENERIC, "/boot"),
-#ifdef WITH_SMP
- DTE_TARBALL("SMP", &KernelDists, KERNEL_SMP, "/boot"),
-#endif
DTE_END,
};
@@ -207,12 +204,7 @@ distConfig(dialogMenuItem *self)
int
selectKernel(void)
{
-#ifdef WITH_SMP
- /* select default kernel based on deduced cpu count */
- return NCpus > 1 ? DIST_KERNEL_SMP : DIST_KERNEL_GENERIC;
-#else
return DIST_KERNEL_GENERIC;
-#endif
}
int
@@ -783,6 +775,10 @@ distSetDoc(dialogMenuItem *self)
{
int i;
+ /* Assume no docs for non-interactive installs. */
+ if (variable_get(VAR_NONINTERACTIVE))
+ return DITEM_SUCCESS | DITEM_RESTORE;
+
dialog_clear_norefresh();
if (!dmenuOpenSimple(&MenuDocInstall, FALSE))
i = DITEM_FAILURE;
diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c
index a2979c9..ac22803 100644
--- a/usr.sbin/sysinstall/install.c
+++ b/usr.sbin/sysinstall/install.c
@@ -938,20 +938,12 @@ installFixupKernel(dialogMenuItem *self, int dists)
/* All of this is done only as init, just to be safe */
if (RunningAsInit) {
/*
- * Install something as /boot/kernel. Prefer SMP
- * over GENERIC--this should handle the case where
- * both SMP and GENERIC are installed (otherwise we
- * select the one kernel that was installed).
+ * Install something as /boot/kernel.
*
* NB: we assume any existing kernel has been saved
* already and the /boot/kernel we remove is empty.
*/
vsystem("rm -rf /boot/kernel");
-#if WITH_SMP
- if (dists & DIST_KERNEL_SMP)
- vsystem("mv /boot/SMP /boot/kernel");
- else
-#endif
vsystem("mv /boot/GENERIC /boot/kernel");
}
return DITEM_SUCCESS | DITEM_RESTORE;
@@ -1255,11 +1247,6 @@ installVarDefaults(dialogMenuItem *self)
variable_set2(SYSTEM_STATE, "init", 0);
variable_set2(VAR_NEWFS_ARGS, "-b 16384 -f 2048", 0);
variable_set2(VAR_CONSTERM, "NO", 0);
-#if (defined(__i386__) && !defined(PC98)) || defined(__amd64__)
- NCpus = acpi_detect();
- if (NCpus == -1)
- NCpus = biosmptable_detect();
-#endif
if (NCpus <= 0)
NCpus = 1;
snprintf(ncpus, sizeof(ncpus), "%u", NCpus);
diff --git a/usr.sbin/sysinstall/label.c b/usr.sbin/sysinstall/label.c
index 2ca947a..08cd3df 100644
--- a/usr.sbin/sysinstall/label.c
+++ b/usr.sbin/sysinstall/label.c
@@ -384,11 +384,7 @@ new_part(PartType type, char *mpoint, Boolean newfs)
pi->newfs_data.newfs_ufs.acls = FALSE;
pi->newfs_data.newfs_ufs.multilabel = FALSE;
pi->newfs_data.newfs_ufs.softupdates = strcmp(mpoint, "/");
-#ifdef PC98
- pi->newfs_data.newfs_ufs.ufs1 = TRUE;
-#else
pi->newfs_data.newfs_ufs.ufs1 = FALSE;
-#endif
}
return pi;
diff --git a/usr.sbin/sysinstall/menus.c b/usr.sbin/sysinstall/menus.c
index 8ea7f98..decb4fd 100644
--- a/usr.sbin/sysinstall/menus.c
+++ b/usr.sbin/sysinstall/menus.c
@@ -1031,10 +1031,6 @@ DMenu MenuKernelDistributions = {
NULL, clearKernel, NULL, NULL, ' ', ' ', ' ' },
{ " GENERIC", "GENERIC kernel configuration",
dmenuFlagCheck, dmenuSetFlag, NULL, &KernelDists, '[', 'X', ']', DIST_KERNEL_GENERIC },
-#ifdef WITH_SMP
- { " SMP", "GENERIC symmetric multiprocessor kernel configuration",
- dmenuFlagCheck, dmenuSetFlag, NULL, &KernelDists, '[', 'X', ']', DIST_KERNEL_SMP },
-#endif
{ NULL } },
};
diff --git a/usr.sbin/sysinstall/package.c b/usr.sbin/sysinstall/package.c
index 212b654..9aa4589 100644
--- a/usr.sbin/sysinstall/package.c
+++ b/usr.sbin/sysinstall/package.c
@@ -139,7 +139,7 @@ package_extract(Device *dev, char *name, Boolean depended)
/* If necessary, initialize the ldconfig hints */
if (!file_readable("/var/run/ld-elf.so.hints"))
- vsystem("ldconfig /usr/lib /usr/lib/compat /usr/local/lib /usr/X11R6/lib");
+ vsystem("ldconfig /usr/lib /usr/lib/compat /usr/local/lib");
/* Be initially optimistic */
ret = DITEM_SUCCESS;
diff --git a/usr.sbin/sysinstall/sysinstall.8 b/usr.sbin/sysinstall/sysinstall.8
index 46a14fc..cdaec6d 100644
--- a/usr.sbin/sysinstall/sysinstall.8
+++ b/usr.sbin/sysinstall/sysinstall.8
@@ -413,8 +413,6 @@ Possible distribution values are:
The base binary distribution.
.It Li GENERIC
The GENERIC kernel.
-.It Li SMP
-A kernel suitable for multiple processor systems.
.It Li doc
Miscellaneous documentation
.It Li games
diff --git a/usr.sbin/sysinstall/tcpip.c b/usr.sbin/sysinstall/tcpip.c
index f505a05..75a40e8 100644
--- a/usr.sbin/sysinstall/tcpip.c
+++ b/usr.sbin/sysinstall/tcpip.c
@@ -40,10 +40,17 @@
#include "sysinstall.h"
#include <sys/param.h>
#include <sys/sysctl.h>
+#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/sockio.h>
+
#include <netinet/in.h>
+#include <net/if.h>
+#include <net/if_media.h>
+
#include <netdb.h>
#include <paths.h>
+#include <ifaddrs.h>
/* The help file for the TCP/IP setup screen */
#define TCP_HELPFILE "tcp"
@@ -636,6 +643,51 @@ netHook(dialogMenuItem *self)
return devs ? DITEM_LEAVE_MENU : DITEM_FAILURE;
}
+static char *
+tcpDeviceScan(void)
+{
+ int s;
+ struct ifmediareq ifmr;
+ struct ifaddrs *ifap, *ifa;
+ struct if_data *ifd;
+ char *network_dev;
+
+ if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)
+ return (NULL);
+
+ if (getifaddrs(&ifap) < 0)
+ return (NULL);
+
+ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+ memset(&ifmr, 0, sizeof(ifmr));
+ strlcpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name));
+
+ if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
+ continue; /* some devices don't support this */
+
+ if ((ifmr.ifm_status & IFM_AVALID) == 0)
+ continue; /* not active */
+
+ if (IFM_TYPE(ifmr.ifm_active) != IFM_ETHER)
+ continue; /* not an ethernet device */
+
+ if (ifmr.ifm_status & IFM_ACTIVE) {
+ network_dev = strdup(ifa->ifa_name);
+ freeifaddrs(ifap);
+
+ if (!variable_get(VAR_NONINTERACTIVE))
+ msgConfirm("Using interface %s", network_dev);
+
+ msgDebug("tcpDeviceScan found %s", network_dev);
+ return (network_dev);
+ }
+ }
+
+ freeifaddrs(ifap);
+
+ return (NULL);
+}
+
/* Get a network device */
Device *
tcpDeviceSelect(void)
@@ -647,27 +699,38 @@ tcpDeviceSelect(void)
rval = NULL;
- if (variable_get(VAR_NONINTERACTIVE) && variable_get(VAR_NETWORK_DEVICE)) {
+ if (variable_get(VAR_NETWORK_DEVICE)) {
network_dev = variable_get(VAR_NETWORK_DEVICE);
+ /*
+ * netDev can be set to several types of values.
+ * If netDev is set to ANY, scan all network devices
+ * looking for a valid link, and go with the first
+ * device found. netDev can also be specified as a
+ * comma delimited list, with each network device
+ * tried in order. netDev can also be set to a single
+ * network device.
+ */
+ if (!strcmp(network_dev, "ANY"))
+ network_dev = strdup(tcpDeviceScan());
+
while ((dev = strsep(&network_dev, ",")) != NULL) {
devs = deviceFind(dev, DEVICE_TYPE_NETWORK);
cnt = deviceCount(devs);
+
if (cnt) {
- if (DITEM_STATUS(tcpOpenDialog(devs[0]) == DITEM_SUCCESS))
- return(devs[0]);
+ if (DITEM_STATUS(tcpOpenDialog(devs[0])) == DITEM_SUCCESS)
+ return (devs[0]);
}
}
- }
- devs = deviceFind(variable_get(VAR_NETWORK_DEVICE), DEVICE_TYPE_NETWORK);
- cnt = deviceCount(devs);
+ if (!variable_get(VAR_NONINTERACTIVE))
+ msgConfirm("No network devices available!");
- if (!cnt) {
- msgConfirm("No network devices available!");
- return NULL;
+ return (NULL);
}
- else if ((!RunningAsInit) && (variable_check("NETWORK_CONFIGURED=NO") != TRUE)) {
+
+ if ((!RunningAsInit) && (variable_check("NETWORK_CONFIGURED=NO") != TRUE)) {
if (!msgYesNo("Running multi-user, assume that the network is already configured?"))
return devs[0];
}
diff --git a/usr.sbin/sysinstall/termcap.c b/usr.sbin/sysinstall/termcap.c
index 0df0a77..4f2b2e9 100644
--- a/usr.sbin/sysinstall/termcap.c
+++ b/usr.sbin/sysinstall/termcap.c
@@ -125,17 +125,17 @@ set_termcap(void)
#else
if (ColorDisplay) {
if (!term) {
- if (setenv("TERM", "cons25", 1) < 0)
+ if (setenv("TERM", "xterm", 1) < 0)
return -1;
- if (setenv("TERMCAP", termcap_cons25, 1) < 0)
+ if (setenv("TERMCAP", termcap_xterm, 1) < 0)
return -1;
}
}
else {
if (!term) {
- if (setenv("TERM", "cons25-m", 1) < 0)
+ if (setenv("TERM", "vt100", 1) < 0)
return -1;
- if (setenv("TERMCAP", termcap_cons25_m, 1) < 0)
+ if (setenv("TERMCAP", termcap_vt100, 1) < 0)
return -1;
}
}
diff --git a/usr.sbin/sysinstall/user.c b/usr.sbin/sysinstall/user.c
index ed2e770..72b6716 100644
--- a/usr.sbin/sysinstall/user.c
+++ b/usr.sbin/sysinstall/user.c
@@ -35,7 +35,6 @@
*/
#include "sysinstall.h"
-#include <utmp.h>
#include <ctype.h>
#include <sys/param.h>
#include <sysexits.h>
@@ -47,7 +46,7 @@
#define GNAME_FIELD_LEN 32
#define GID_FIELD_LEN 11
#define GMEMB_FIELD_LEN 64
-
+#define UNAME_FIELD_LEN MAXLOGNAME
#define UID_FIELD_LEN 11
#define UGROUP_FIELD_LEN GNAME_FIELD_LEN
#define GECOS_FIELD_LEN 64
@@ -61,7 +60,7 @@
static char gname[GNAME_FIELD_LEN],
gid[GID_FIELD_LEN],
gmemb[GMEMB_FIELD_LEN],
- uname[UT_NAMESIZE + 1],
+ uname[UNAME_FIELD_LEN],
passwd[PASSWD_FIELD_LEN],
confpasswd[PASSWD_FIELD_LEN],
uid[UID_FIELD_LEN],
@@ -109,7 +108,7 @@ static Layout groupLayout[] = {
/* The user configuration menu. */
static Layout userLayout[] = {
#define LAYOUT_UNAME 0
- { 2, 6, UT_NAMESIZE, UT_NAMESIZE + 1,
+ { 2, 6, 16, UNAME_FIELD_LEN - 1,
"Login ID:", "The login name of the new user (mandatory)",
uname, STRINGOBJ, NULL },
#define LAYOUT_UID 1
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
index 3e628a2..b803969 100644
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
@@ -105,7 +106,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
-#include <utmp.h>
+#include <utmpx.h>
#include "pathnames.h"
#include "ttymsg.h"
@@ -170,7 +171,7 @@ struct filed {
#define PRI_GT 0x4
char *f_program; /* program this applies to */
union {
- char f_uname[MAXUNAMES][UT_NAMESIZE+1];
+ char f_uname[MAXUNAMES][MAXLOGNAME];
struct {
char f_hname[MAXHOSTNAMELEN];
struct addrinfo *f_addr;
@@ -352,6 +353,9 @@ main(int argc, char *argv[])
pid_t ppid = 1, spid;
socklen_t len;
+ if (madvise(NULL, 0, MADV_PROTECT) != 0)
+ dprintf("madvise() failed: %s\n", strerror(errno));
+
bindhostname = NULL;
while ((ch = getopt(argc, argv, "468Aa:b:cCdf:kl:m:nop:P:sS:Tuv"))
!= -1)
@@ -1338,29 +1342,20 @@ static void
wallmsg(struct filed *f, struct iovec *iov, const int iovlen)
{
static int reenter; /* avoid calling ourselves */
- FILE *uf;
- struct utmp ut;
+ struct utmpx *ut;
int i;
const 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;
- }
+ setutxent();
/* NOSTRICT */
- while (fread((char *)&ut, sizeof(ut), 1, uf) == 1) {
- if (ut.ut_name[0] == '\0')
+ while ((ut = getutxent()) != NULL) {
+ if (ut->ut_type != USER_PROCESS)
continue;
- /* We must use strncpy since ut_* may not be NUL terminated. */
- strncpy(line, ut.ut_line, sizeof(line) - 1);
- line[sizeof(line) - 1] = '\0';
if (f->f_type == F_WALL) {
- if ((p = ttymsg(iov, iovlen, line, TTYMSGTIME)) !=
- NULL) {
+ if ((p = ttymsg(iov, iovlen, ut->ut_line,
+ TTYMSGTIME)) != NULL) {
errno = 0; /* already in msg */
logerror(p);
}
@@ -1370,10 +1365,9 @@ wallmsg(struct filed *f, struct iovec *iov, const int iovlen)
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, iovlen, line, TTYMSGTIME))
- != NULL) {
+ if (!strcmp(f->f_un.f_uname[i], ut->ut_user)) {
+ if ((p = ttymsg(iov, iovlen, ut->ut_line,
+ TTYMSGTIME)) != NULL) {
errno = 0; /* already in msg */
logerror(p);
}
@@ -1381,7 +1375,7 @@ wallmsg(struct filed *f, struct iovec *iov, const int iovlen)
}
}
}
- (void)fclose(uf);
+ endutxent();
reenter = 0;
}
@@ -1998,9 +1992,9 @@ cfline(const char *line, struct filed *f, const char *prog, const char *host)
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';
+ (void)strncpy(f->f_un.f_uname[i], p, MAXLOGNAME - 1);
+ if ((q - p) >= MAXLOGNAME)
+ f->f_un.f_uname[i][MAXLOGNAME - 1] = '\0';
else
f->f_un.f_uname[i][q - p] = '\0';
while (*q == ',' || *q == ' ')
diff --git a/usr.sbin/tcpdchk/Makefile b/usr.sbin/tcpdchk/Makefile
index 2936984..a49ffc6 100644
--- a/usr.sbin/tcpdchk/Makefile
+++ b/usr.sbin/tcpdchk/Makefile
@@ -15,6 +15,8 @@ CFLAGS+=-DREAL_DAEMON_DIR=\"/usr/libexec\" \
CFLAGS+=-DINET6
.endif
+WARNS?= 0
+
DPADD= ${LIBWRAP}
LDADD= -lwrap
diff --git a/usr.sbin/tcpdmatch/Makefile b/usr.sbin/tcpdmatch/Makefile
index cbd61aa..caae746 100644
--- a/usr.sbin/tcpdmatch/Makefile
+++ b/usr.sbin/tcpdmatch/Makefile
@@ -14,6 +14,8 @@ CFLAGS+=-DREAL_DAEMON_DIR=\"/usr/libexec\" \
CFLAGS+=-DINET6
.endif
+WARNS?= 0
+
DPADD= ${LIBWRAP}
LDADD= -lwrap
diff --git a/usr.sbin/tcpdrop/Makefile b/usr.sbin/tcpdrop/Makefile
index 44766eb..2fc606a 100644
--- a/usr.sbin/tcpdrop/Makefile
+++ b/usr.sbin/tcpdrop/Makefile
@@ -3,6 +3,5 @@
PROG= tcpdrop
MAN= tcpdrop.8
-WARNS?= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/tcpdump/Makefile.inc b/usr.sbin/tcpdump/Makefile.inc
index 1e4d46f..6c4b6e2 100644
--- a/usr.sbin/tcpdump/Makefile.inc
+++ b/usr.sbin/tcpdump/Makefile.inc
@@ -2,3 +2,5 @@
# $FreeBSD$
BINDIR?= /usr/sbin
+
+WARNS?= 3
diff --git a/usr.sbin/timed/timed/master.c b/usr.sbin/timed/timed/master.c
index e36fbae..0537016 100644
--- a/usr.sbin/timed/timed/master.c
+++ b/usr.sbin/timed/timed/master.c
@@ -44,6 +44,7 @@ static const char rcsid[] =
#include <sys/types.h>
#include <sys/times.h>
#include <setjmp.h>
+#include <utmpx.h>
#include "pathnames.h"
extern int measure_delta;
@@ -56,8 +57,6 @@ static int slvcount; /* slaves listening to our clock */
static void mchgdate(struct tsp *);
-extern void logwtmp(char *, char *, char *);
-
/*
* The main function of `master' is to periodically compute the differences
* (deltas) between its clock and the clocks of the slaves, to compute the
@@ -350,6 +349,7 @@ mchgdate(msg)
char tname[MAXHOSTNAMELEN];
char olddate[32];
struct timeval otime, ntime, tmptv;
+ struct utmpx utx;
(void)strcpy(tname, msg->tsp_name);
@@ -371,9 +371,13 @@ mchgdate(msg)
dictate = 3;
synch(tvtomsround(ntime));
} else {
- logwtmp("|", "date", "");
+ utx.ut_type = OLD_TIME;
+ gettimeofday(&utx.ut_tv, NULL);
+ pututxline(&utx);
(void)settimeofday(&tmptv, 0);
- logwtmp("{", "date", "");
+ utx.ut_type = NEW_TIME;
+ gettimeofday(&utx.ut_tv, NULL);
+ pututxline(&utx);
spreadtime();
}
diff --git a/usr.sbin/timed/timed/slave.c b/usr.sbin/timed/timed/slave.c
index 217fd82..74a1723 100644
--- a/usr.sbin/timed/timed/slave.c
+++ b/usr.sbin/timed/timed/slave.c
@@ -41,6 +41,7 @@ static const char rcsid[] =
#include "globals.h"
#include <setjmp.h>
+#include <utmpx.h>
#include "pathnames.h"
extern jmp_buf jmpenv;
@@ -57,8 +58,6 @@ static void schgdate(struct tsp *, char *);
static void setmaster(struct tsp *);
static void answerdelay(void);
-extern void logwtmp(char *, char *, char *);
-
int
slave()
{
@@ -80,6 +79,7 @@ slave()
char newdate[32];
struct netinfo *ntp;
struct hosttbl *htp;
+ struct utmpx utx;
old_slavenet = 0;
@@ -280,9 +280,13 @@ loop:
*/
synch(tvtomsround(ntime));
} else {
- logwtmp("|", "date", "");
- (void)settimeofday(&tmptv, 0);
- logwtmp("{", "date", "");
+ utx.ut_type = OLD_TIME;
+ gettimeofday(&utx.ut_tv, NULL);
+ pututxline(&utx);
+ (void)settimeofday(&tmptv, 0);
+ utx.ut_type = NEW_TIME;
+ gettimeofday(&utx.ut_tv, NULL);
+ pututxline(&utx);
syslog(LOG_NOTICE,
"date changed by %s from %s",
msg->tsp_name, olddate);
diff --git a/usr.sbin/traceroute/Makefile b/usr.sbin/traceroute/Makefile
index 489c862..6d6752a 100644
--- a/usr.sbin/traceroute/Makefile
+++ b/usr.sbin/traceroute/Makefile
@@ -5,7 +5,7 @@ TRACEROUTE_DISTDIR?= ${.CURDIR}/../../contrib/traceroute
PROG= traceroute
MAN= traceroute.8
-SRCS= as.c version.c traceroute.c ifaddrlist.c findsaddr-socket.c
+SRCS= as.c version.c traceroute.c ifaddrlist.c findsaddr-udp.c
BINOWN= root
BINMODE=4555
CLEANFILES= version.c
@@ -29,7 +29,9 @@ DPADD= ${LIBIPSEC}
LDADD= -lipsec
.endif
-CFLAGS+= -I${TRACEROUTE_DISTDIR}/lbl
+CFLAGS+= -I${TRACEROUTE_DISTDIR}/lbl -I${TRACEROUTE_DISTDIR}
+
+WARNS?= 0
version.c: ${TRACEROUTE_DISTDIR}/VERSION
@rm -f ${.TARGET}
diff --git a/usr.sbin/traceroute/findsaddr-udp.c b/usr.sbin/traceroute/findsaddr-udp.c
new file mode 100644
index 0000000..3da72c7
--- /dev/null
+++ b/usr.sbin/traceroute/findsaddr-udp.c
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2010 Bjoern A. Zeeb <bz@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include "findsaddr.h"
+#include "traceroute.h"
+
+/*
+ * Return the source address for the given destination address.
+ *
+ * This makes use of proper source address selection in the FreeBSD kernel
+ * even taking jails into account (sys/netinet/in_pcb.c:in_pcbladdr()).
+ * We open a UDP socket, and connect to the destination, letting the kernel
+ * do the bind and then read the source IPv4 address using getsockname(2).
+ * This has multiple advantages: no need to do PF_ROUTE operations possibly
+ * needing special privileges, jails properly taken into account and most
+ * important - getting the result the kernel would give us rather than
+ * best-guessing ourselves.
+ */
+const char *
+findsaddr(register const struct sockaddr_in *to,
+ register struct sockaddr_in *from)
+{
+ const char *errstr;
+ struct sockaddr_in cto, cfrom;
+ int s;
+ socklen_t len;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s == -1)
+ return ("failed to open DGRAM socket for src addr selection.");
+
+ errstr = NULL;
+ len = sizeof(struct sockaddr_in);
+ memcpy(&cto, to, len);
+ cto.sin_port = htons(65535); /* Dummy port for connect(2). */
+ if (connect(s, (struct sockaddr *)&cto, len) == -1) {
+ errstr = "failed to connect to peer for src addr selection.";
+ goto err;
+ }
+
+ if (getsockname(s, (struct sockaddr *)&cfrom, &len) == -1) {
+ errstr = "failed to get socket name for src addr selection.";
+ goto err;
+ }
+
+ if (len != sizeof(struct sockaddr_in) || cfrom.sin_family != AF_INET) {
+ errstr = "unexpected address family in src addr selection.";
+ goto err;
+ }
+
+ /* Update source address for traceroute. */
+ setsin(from, cfrom.sin_addr.s_addr);
+
+err:
+ (void) close(s);
+
+ /* No error (string) to return. */
+ return (errstr);
+}
+
+/* end */
diff --git a/usr.sbin/traceroute6/Makefile b/usr.sbin/traceroute6/Makefile
index 60618a2..e0b72a1 100644
--- a/usr.sbin/traceroute6/Makefile
+++ b/usr.sbin/traceroute6/Makefile
@@ -25,6 +25,8 @@ BINMODE= 4555
CFLAGS+= -DIPSEC -DUSE_RFC2292BIS -DHAVE_POLL
CFLAGS+= -I${.CURDIR} -I${TRACEROUTE_DISTDIR} -I.
+WARNS?= 1
+
DPADD= ${LIBIPSEC}
LDADD= -lipsec
diff --git a/usr.sbin/tzsetup/Makefile b/usr.sbin/tzsetup/Makefile
index 0596967..a9da310 100644
--- a/usr.sbin/tzsetup/Makefile
+++ b/usr.sbin/tzsetup/Makefile
@@ -5,6 +5,8 @@ MAN= tzsetup.8
CFLAGS+= -I${.CURDIR}
+WARNS?= 3
+
DPADD= ${LIBDIALOG} ${LIBNCURSES}
LDADD= -ldialog -lncurses
diff --git a/usr.sbin/tzsetup/tzsetup.8 b/usr.sbin/tzsetup/tzsetup.8
index fd355b6..4d548fd 100644
--- a/usr.sbin/tzsetup/tzsetup.8
+++ b/usr.sbin/tzsetup/tzsetup.8
@@ -31,8 +31,9 @@
.Nd set local timezone
.Sh SYNOPSIS
.Nm
-.Op Fl ns
-.Op Ar default
+.Op Fl nrs
+.Op Fl C Ar chroot directory
+.Op Ar zoneinfo file | zoneinfo name
.Sh DESCRIPTION
The
.Nm
@@ -49,17 +50,26 @@ the hardware clock does not keep
.Pp
The following option is available:
.Bl -tag -offset indent -width Fl
+.It Fl C Ar chroot directory
+Open all files and directories relative to
+.Ar chroot directory .
.It Fl n
Do not create or copy files.
+.It Fl r
+Reinstall the zoneinfo file installed last time. The name is obtained from
+.Pa /var/db/zoneinfo .
.It Fl s
Skip the initial question about adjusting the clock if not set to
.Tn UTC .
.El
.Pp
-It is possible to short-circuit the menu system by specifying a
-.Ar default
-on the command line; this is intended mainly for pre-configured
-installation scripts.
+It is possible to short-circuit the menu system by specifying the
+location of a
+.Ar zoneinfo file
+or the name of the
+.Ar zoneinfo name
+on the command line; this is intended mainly for pre-configured installation
+scripts or people who know which zoneinfo they want to install.
.Sh TIMEZONE DATABASE
The contents of the timezone database are indexed by
.Pa /usr/share/zoneinfo/zone.tab .
@@ -93,19 +103,36 @@ historically minded.
.Sh FILES
.Bl -tag -width /usr/share/zoneinfo/zone.tab -compact
.It Pa /etc/localtime
-current time zone file
+current time zone file.
.It Pa /etc/wall_cmos_clock
see
.Xr adjkerntz 8 .
.It Pa /usr/share/misc/iso3166
mapping of
.Tn ISO
-3166 territory codes to names
+3166 territory codes to names.
.It Pa /usr/share/zoneinfo
-directory for zoneinfo files
+directory for zoneinfo files.
.It Pa /usr/share/zoneinfo/zone.tab
-mapping of timezone file to country and location
+mapping of timezone file to country and location.
+.It Pa /var/db/zoneinfo
+saved name of the timezone file installed last.
.El
+.Sh EXAMPLES
+Normal usage, to select the right zoneinfo file via the dialog-based
+user interface:
+.Dl # tzsetup
+Install the file
+.Pa /usr/share/zoneinfo/Australia/Sydney :
+.Dl # tzsetup /usr/share/zoneinfo/Australia/Sydney
+Install the zoneinfo file for Australia/Sydney, assumed to be located
+in
+.Pa /usr/share/zoneinfo :
+.Dl # tzsetup Australia/Sydney
+After a reinstall of the zoneinfo files, you can reinstall the
+latest installed zoneinfo file: (as specified in
+.Pa /var/db/zoneinfo )
+.Dl # tzsetup -r
.Sh SEE ALSO
.Xr date 1 ,
.Xr adjtime 2 ,
diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c
index 66a34c4..0ab7a2b 100644
--- a/usr.sbin/tzsetup/tzsetup.c
+++ b/usr.sbin/tzsetup/tzsetup.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include <sys/fcntl.h>
+#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
@@ -52,9 +53,17 @@ __FBSDID("$FreeBSD$");
#define _PATH_ISO3166 "/usr/share/misc/iso3166"
#define _PATH_ZONEINFO "/usr/share/zoneinfo"
#define _PATH_LOCALTIME "/etc/localtime"
+#define _PATH_DB "/var/db/zoneinfo"
#define _PATH_WALL_CMOS_CLOCK "/etc/wall_cmos_clock"
+static char path_zonetab[MAXPATHLEN], path_iso3166[MAXPATHLEN],
+ path_zoneinfo[MAXPATHLEN], path_localtime[MAXPATHLEN],
+ path_db[MAXPATHLEN], path_wall_cmos_clock[MAXPATHLEN];
+
static int reallydoit = 1;
+static int reinstall = 0;
+static int usedialog = 1;
+static char *chrootenv = NULL;
static void usage(void);
static int continent_country_menu(dialogMenuItem *);
@@ -193,15 +202,15 @@ read_iso3166_table(void)
char *s, *t, *name;
int lineno;
- fp = fopen(_PATH_ISO3166, "r");
+ fp = fopen(path_iso3166, "r");
if (!fp)
- err(1, _PATH_ISO3166);
+ err(1, path_iso3166);
lineno = 0;
while ((s = fgetln(fp, &len)) != 0) {
lineno++;
if (s[len - 1] != '\n')
- errx(1, _PATH_ISO3166 ":%d: invalid format", lineno);
+ errx(1, "%s:%d: invalid format", path_iso3166, lineno);
s[len - 1] = '\0';
if (s[0] == '#' || strspn(s, " \t") == len - 1)
continue;
@@ -209,26 +218,25 @@ read_iso3166_table(void)
/* Isolate the two-letter code. */
t = strsep(&s, "\t");
if (t == 0 || strlen(t) != 2)
- errx(1, _PATH_ISO3166 ":%d: invalid format", lineno);
+ errx(1, "%s:%d: invalid format", path_iso3166, lineno);
if (t[0] < 'A' || t[0] > 'Z' || t[1] < 'A' || t[1] > 'Z')
- errx(1, _PATH_ISO3166 ":%d: invalid code `%s'",
+ errx(1, "%s:%d: invalid code `%s'", path_iso3166,
lineno, t);
/* Now skip past the three-letter and numeric codes. */
name = strsep(&s, "\t"); /* 3-let */
if (name == 0 || strlen(name) != 3)
- errx(1, _PATH_ISO3166 ":%d: invalid format", lineno);
+ errx(1, "%s:%d: invalid format", path_iso3166, lineno);
name = strsep(&s, "\t"); /* numeric */
if (name == 0 || strlen(name) != 3)
- errx(1, _PATH_ISO3166 ":%d: invalid format", lineno);
+ errx(1, "%s:%d: invalid format", path_iso3166, lineno);
name = s;
cp = &countries[CODE2INT(t)];
if (cp->name)
- errx(1, _PATH_ISO3166
- ":%d: country code `%s' multiply defined: %s",
- lineno, t, cp->name);
+ errx(1, "%s:%d: country code `%s' multiply defined: %s",
+ path_iso3166, lineno, t, cp->name);
cp->name = strdup(name);
if (cp->name == NULL)
errx(1, "malloc failed");
@@ -248,18 +256,18 @@ add_zone_to_country(int lineno, const char *tlc, const char *descr,
struct country *cp;
if (tlc[0] < 'A' || tlc[0] > 'Z' || tlc[1] < 'A' || tlc[1] > 'Z')
- errx(1, _PATH_ZONETAB ":%d: country code `%s' invalid",
+ errx(1, "%s:%d: country code `%s' invalid", path_zonetab,
lineno, tlc);
cp = &countries[CODE2INT(tlc)];
if (cp->name == 0)
- errx(1, _PATH_ZONETAB ":%d: country code `%s' unknown",
+ errx(1, "%s:%d: country code `%s' unknown", path_zonetab,
lineno, tlc);
if (descr) {
if (cp->nzones < 0)
- errx(1, _PATH_ZONETAB
- ":%d: conflicting zone definition", lineno);
+ errx(1, "%s:%d: conflicting zone definition",
+ path_zonetab, lineno);
zp = malloc(sizeof(*zp));
if (zp == 0)
@@ -279,11 +287,11 @@ add_zone_to_country(int lineno, const char *tlc, const char *descr,
cp->nzones++;
} else {
if (cp->nzones > 0)
- errx(1, _PATH_ZONETAB
- ":%d: zone must have description", lineno);
+ errx(1, "%s:%d: zone must have description",
+ path_zonetab, lineno);
if (cp->nzones < 0)
- errx(1, _PATH_ZONETAB
- ":%d: zone multiply defined", lineno);
+ errx(1, "%s:%d: zone multiply defined",
+ path_zonetab, lineno);
cp->nzones = -1;
cp->filename = strdup(file);
if (cp->filename == NULL)
@@ -333,34 +341,34 @@ read_zones(void)
char *line, *tlc, *coord, *file, *descr, *p;
int lineno;
- fp = fopen(_PATH_ZONETAB, "r");
+ fp = fopen(path_zonetab, "r");
if (!fp)
- err(1, _PATH_ZONETAB);
+ err(1, path_zonetab);
lineno = 0;
while ((line = fgetln(fp, &len)) != 0) {
lineno++;
if (line[len - 1] != '\n')
- errx(1, _PATH_ZONETAB ":%d: invalid format", lineno);
+ errx(1, "%s:%d: invalid format", path_zonetab, lineno);
line[len - 1] = '\0';
if (line[0] == '#')
continue;
tlc = strsep(&line, "\t");
if (strlen(tlc) != 2)
- errx(1, _PATH_ZONETAB ":%d: invalid country code `%s'",
- lineno, tlc);
+ errx(1, "%s:%d: invalid country code `%s'",
+ path_zonetab, lineno, tlc);
coord = strsep(&line, "\t");
file = strsep(&line, "\t");
p = strchr(file, '/');
if (p == 0)
- errx(1, _PATH_ZONETAB ":%d: invalid zone name `%s'",
+ errx(1, "%s:%d: invalid zone name `%s'", path_zonetab,
lineno, file);
contbuf[0] = '\0';
strncat(contbuf, file, p - file);
cont = find_continent(contbuf);
if (!cont)
- errx(1, _PATH_ZONETAB ":%d: invalid region `%s'",
+ errx(1, "%s:%d: invalid region `%s'", path_zonetab,
lineno, contbuf);
descr = (line != NULL && *line != '\0') ? line : NULL;
@@ -495,7 +503,7 @@ set_zone_menu(dialogMenuItem *dmi)
}
static int
-install_zone_file(const char *filename)
+install_zoneinfo_file(const char *zoneinfo_file)
{
char buf[1024];
char title[64], prompt[64];
@@ -503,7 +511,7 @@ install_zone_file(const char *filename)
ssize_t len;
int fd1, fd2, copymode;
- if (lstat(_PATH_LOCALTIME, &sb) < 0) {
+ if (lstat(path_localtime, &sb) < 0) {
/* Nothing there yet... */
copymode = 1;
} else if (S_ISLNK(sb.st_mode))
@@ -514,35 +522,44 @@ install_zone_file(const char *filename)
#ifdef VERBOSE
if (copymode)
snprintf(prompt, sizeof(prompt),
- "Copying %s to " _PATH_LOCALTIME, filename);
+ "Copying %s to %s", zoneinfo_file, path_localtime);
else
snprintf(prompt, sizeof(prompt),
- "Creating symbolic link " _PATH_LOCALTIME " to %s",
- filename);
- dialog_notify(prompt);
+ "Creating symbolic link %s to %s",
+ path_localtime, zoneinfo_file);
+ if (usedialog)
+ dialog_notify(prompt);
+ else
+ fprintf(stderr, "%s\n", prompt);
#endif
if (reallydoit) {
if (copymode) {
- fd1 = open(filename, O_RDONLY, 0);
+ fd1 = open(zoneinfo_file, O_RDONLY, 0);
if (fd1 < 0) {
snprintf(title, sizeof(title), "Error");
snprintf(prompt, sizeof(prompt),
- "Could not open %s: %s", filename,
+ "Could not open %s: %s", zoneinfo_file,
strerror(errno));
- dialog_mesgbox(title, prompt, 8, 72);
+ if (usedialog)
+ dialog_mesgbox(title, prompt, 8, 72);
+ else
+ fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
- unlink(_PATH_LOCALTIME);
- fd2 = open(_PATH_LOCALTIME, O_CREAT | O_EXCL | O_WRONLY,
+ unlink(path_localtime);
+ fd2 = open(path_localtime, O_CREAT | O_EXCL | O_WRONLY,
S_IRUSR | S_IRGRP | S_IROTH);
if (fd2 < 0) {
snprintf(title, sizeof(title), "Error");
snprintf(prompt, sizeof(prompt),
- "Could not open " _PATH_LOCALTIME ": %s",
- strerror(errno));
- dialog_mesgbox(title, prompt, 8, 72);
+ "Could not open %s: %s",
+ path_localtime, strerror(errno));
+ if (usedialog)
+ dialog_mesgbox(title, prompt, 8, 72);
+ else
+ fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
@@ -552,32 +569,41 @@ install_zone_file(const char *filename)
if (len == -1) {
snprintf(title, sizeof(title), "Error");
snprintf(prompt, sizeof(prompt),
- "Error copying %s to " _PATH_LOCALTIME
- ": %s", filename, strerror(errno));
- dialog_mesgbox(title, prompt, 8, 72);
+ "Error copying %s to %s %s", zoneinfo_file,
+ path_localtime, strerror(errno));
+ if (usedialog)
+ dialog_mesgbox(title, prompt, 8, 72);
+ else
+ fprintf(stderr, "%s\n", prompt);
/* Better to leave none than a corrupt one. */
- unlink(_PATH_LOCALTIME);
+ unlink(path_localtime);
return (DITEM_FAILURE | DITEM_RECREATE);
}
close(fd1);
close(fd2);
} else {
- if (access(filename, R_OK) != 0) {
+ if (access(zoneinfo_file, R_OK) != 0) {
snprintf(title, sizeof(title), "Error");
snprintf(prompt, sizeof(prompt),
- "Cannot access %s: %s", filename,
+ "Cannot access %s: %s", zoneinfo_file,
strerror(errno));
- dialog_mesgbox(title, prompt, 8, 72);
+ if (usedialog)
+ dialog_mesgbox(title, prompt, 8, 72);
+ else
+ fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
- unlink(_PATH_LOCALTIME);
- if (symlink(filename, _PATH_LOCALTIME) < 0) {
+ unlink(path_localtime);
+ if (symlink(zoneinfo_file, path_localtime) < 0) {
snprintf(title, sizeof(title), "Error");
snprintf(prompt, sizeof(prompt),
- "Cannot create symbolic link "
- _PATH_LOCALTIME " to %s: %s", filename,
+ "Cannot create symbolic link %s to %s: %s",
+ path_localtime, zoneinfo_file,
strerror(errno));
- dialog_mesgbox(title, prompt, 8, 72);
+ if (usedialog)
+ dialog_mesgbox(title, prompt, 8, 72);
+ else
+ fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
}
@@ -587,17 +613,41 @@ install_zone_file(const char *filename)
snprintf(title, sizeof(title), "Done");
if (copymode)
snprintf(prompt, sizeof(prompt),
- "Copied timezone file from %s to " _PATH_LOCALTIME,
- filename);
+ "Copied timezone file from %s to %s", zoneinfo_file,
+ path_localtime);
+ else
+ snprintf(prompt, sizeof(prompt),
+ "Created symbolic link from %s to %s", zoneinfo_file,
+ path_localtime);
+ if (usedialog)
+ dialog_mesgbox(title, prompt, 8, 72);
else
- snprintf(prompt, sizeof(prompt), "Created symbolic link from "
- _PATH_LOCALTIME " to %s", filename);
- dialog_mesgbox(title, prompt, 8, 72);
+ fprintf(stderr, "%s\n", prompt);
#endif
+
return (DITEM_LEAVE_MENU);
}
static int
+install_zoneinfo(const char *zoneinfo)
+{
+ int rv;
+ FILE *f;
+ char path_zoneinfo_file[MAXPATHLEN];
+
+ sprintf(path_zoneinfo_file, "%s/%s", path_zoneinfo, zoneinfo);
+ rv = install_zoneinfo_file(path_zoneinfo_file);
+
+ /* Save knowledge for later */
+ if ((f = fopen(path_db, "w")) != NULL) {
+ fprintf(f, "%s\n", zoneinfo);
+ fclose(f);
+ }
+
+ return (rv);
+}
+
+static int
confirm_zone(const char *filename)
{
char title[64], prompt[64];
@@ -620,15 +670,12 @@ static int
set_zone_multi(dialogMenuItem *dmi)
{
struct zone *zp = dmi->data;
- char *fn;
int rv;
if (!confirm_zone(zp->filename))
return (DITEM_FAILURE | DITEM_RECREATE);
- asprintf(&fn, "%s/%s", _PATH_ZONEINFO, zp->filename);
- rv = install_zone_file(fn);
- free(fn);
+ rv = install_zoneinfo(zp->filename);
return (rv);
}
@@ -636,15 +683,12 @@ static int
set_zone_whole_country(dialogMenuItem *dmi)
{
struct country *cp = dmi->data;
- char *fn;
int rv;
if (!confirm_zone(cp->filename))
return (DITEM_FAILURE | DITEM_RECREATE);
- asprintf(&fn, "%s/%s", _PATH_ZONEINFO, cp->filename);
- rv = install_zone_file(fn);
- free(fn);
+ rv = install_zoneinfo(cp->filename);
return (rv);
}
@@ -652,7 +696,7 @@ static void
usage(void)
{
- fprintf(stderr, "usage: tzsetup [-ns]\n");
+ fprintf(stderr, "usage: tzsetup [-nrs] [zoneinfo file]\n");
exit(1);
}
@@ -666,14 +710,21 @@ int
main(int argc, char **argv)
{
char title[64], prompt[128];
- int c, fd, skiputc;
+ int c, fd, rv, skiputc;
skiputc = 0;
- while ((c = getopt(argc, argv, "ns")) != -1) {
+ while ((c = getopt(argc, argv, "C:nrs")) != -1) {
switch(c) {
+ case 'C':
+ chrootenv = optarg;
+ break;
case 'n':
reallydoit = 0;
break;
+ case 'r':
+ reinstall = 1;
+ usedialog = 0;
+ break;
case 's':
skiputc = 1;
break;
@@ -685,6 +736,24 @@ main(int argc, char **argv)
if (argc - optind > 1)
usage();
+ if (chrootenv == NULL) {
+ strcpy(path_zonetab, _PATH_ZONETAB);
+ strcpy(path_iso3166, _PATH_ISO3166);
+ strcpy(path_zoneinfo, _PATH_ZONEINFO);
+ strcpy(path_localtime, _PATH_LOCALTIME);
+ strcpy(path_db, _PATH_DB);
+ strcpy(path_wall_cmos_clock, _PATH_WALL_CMOS_CLOCK);
+ } else {
+ sprintf(path_zonetab, "%s/%s", chrootenv, _PATH_ZONETAB);
+ sprintf(path_iso3166, "%s/%s", chrootenv, _PATH_ISO3166);
+ sprintf(path_zoneinfo, "%s/%s", chrootenv, _PATH_ZONEINFO);
+ sprintf(path_localtime, "%s/%s", chrootenv, _PATH_LOCALTIME);
+ sprintf(path_db, "%s/%s", chrootenv, _PATH_DB);
+ sprintf(path_wall_cmos_clock, "%s/%s", chrootenv,
+ _PATH_WALL_CMOS_CLOCK);
+ }
+
+
/* Override the user-supplied umask. */
(void)umask(S_IWGRP | S_IWOTH);
@@ -693,6 +762,54 @@ main(int argc, char **argv)
sort_countries();
make_menus();
+ if (reinstall == 1) {
+ FILE *f;
+ char zonefile[MAXPATHLEN];
+ char path_db[MAXPATHLEN];
+
+ zonefile[0] = '\0';
+ path_db[0] = '\0';
+ if (chrootenv != NULL) {
+ sprintf(zonefile, "%s/", chrootenv);
+ sprintf(path_db, "%s/", chrootenv);
+ }
+ strcat(zonefile, _PATH_ZONEINFO);
+ strcat(zonefile, "/");
+ strcat(path_db, _PATH_DB);
+
+ if ((f = fopen(path_db, "r")) != NULL) {
+ if (fgets(zonefile, sizeof(zonefile), f) != NULL) {
+ zonefile[sizeof(zonefile) - 1] = 0;
+ if (strlen(zonefile) > 0) {
+ zonefile[strlen(zonefile) - 1] = 0;
+ rv = install_zoneinfo(zonefile);
+ exit(rv & ~DITEM_LEAVE_MENU);
+ }
+ errx(1, "Error reading %s.\n", path_db);
+ }
+ fclose(f);
+ errx(1,
+ "Unable to determine earlier installed zoneinfo "
+ "file. Check %s", path_db);
+ }
+ errx(1, "Cannot open %s for reading. Does it exist?", path_db);
+ }
+
+ /*
+ * If the arguments on the command-line do not specify a file,
+ * then interpret it as a zoneinfo name
+ */
+ if (optind == argc - 1) {
+ struct stat sb;
+
+ if (stat(argv[optind], &sb) != 0) {
+ usedialog = 0;
+ rv = install_zoneinfo(argv[optind]);
+ exit(rv & ~DITEM_LEAVE_MENU);
+ }
+ /* FALLTHROUGH */
+ }
+
init_dialog();
if (skiputc == 0) {
snprintf(title, sizeof(title),
@@ -709,9 +826,11 @@ main(int argc, char **argv)
fd = open(_PATH_WALL_CMOS_CLOCK,
O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IRGRP | S_IROTH);
- if (fd < 0)
+ if (fd < 0) {
+ end_dialog();
err(1, "create %s",
_PATH_WALL_CMOS_CLOCK);
+ }
close(fd);
}
}
@@ -722,10 +841,10 @@ main(int argc, char **argv)
snprintf(prompt, sizeof(prompt),
"\nUse the default `%s' zone?", argv[optind]);
if (!dialog_yesno(title, prompt, 7, 72)) {
- install_zone_file(argv[optind]);
+ rv = install_zoneinfo_file(argv[optind]);
dialog_clear();
end_dialog();
- return (0);
+ exit(rv & ~DITEM_LEAVE_MENU);
}
dialog_clear_norefresh();
}
diff --git a/usr.sbin/uathload/Makefile b/usr.sbin/uathload/Makefile
index 3083704..4f9b99d 100644
--- a/usr.sbin/uathload/Makefile
+++ b/usr.sbin/uathload/Makefile
@@ -5,8 +5,6 @@ MAN= uathload.8
SRCS= uathload.c ar5523.bin
-WARNS?= 4
-
CLEANFILES= ar5523.bin
ar5523.bin: ${.CURDIR}/../../sys/contrib/dev/uath/ar5523.bin.uu
diff --git a/usr.sbin/uhsoctl/Makefile b/usr.sbin/uhsoctl/Makefile
new file mode 100644
index 0000000..9704923
--- /dev/null
+++ b/usr.sbin/uhsoctl/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+PROG= uhsoctl
+MAN= uhsoctl.1
+WARNS= 1
+
+DPADD= ${LIBUTIL}
+LDADD= -lutil
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/uhsoctl/uhsoctl.1 b/usr.sbin/uhsoctl/uhsoctl.1
new file mode 100644
index 0000000..932cefa
--- /dev/null
+++ b/usr.sbin/uhsoctl/uhsoctl.1
@@ -0,0 +1,104 @@
+.\" Copyright (c) 2008-2009 Fredrik Lindberg
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd Aug 12, 2009
+.Os
+.Dt UHSOCTL 1
+.Sh NAME
+.Nm uhsoctl
+.Nd connection utility for Option based devices
+.Sh SYNOPSIS
+.Nm
+.Op Fl a Ar apn
+.Op Fl c Ar cid
+.Op Fl p Ar pin
+.Op Fl u Ar username
+.Op Fl k Ar password
+.Op Fl r Ar path
+.Op Fl f Ar path
+.Op Fl b | n
+.Ar interface
+.Nm
+.Fl d
+.Ar interface
+.Nm
+.Fl h
+.Sh DESCRIPTION
+.Nm
+is a small connection utility for Option N.V. devices that are based on Options
+packet interface and uses proprietary AT_* calls to establish connections.
+The utility (tries to) configure both default route and name servers
+(/etc/resolv.conf).
+.Pp
+By default
+.Nm
+detaches from the terminal upon on a successful connection, a few command-line
+options exists that allows this behavior to be changed.
+.Pp
+.Nm
+attempts to find a usable controlling serial port based on the provided network
+interface.
+If this fails you might specify a serial port manually.
+.Sh OPTIONS
+.Bl -tag -width XXXX
+.It Fl a Ar apn
+Specify APN to connect to.
+.It Fl c Ar cid
+Specify CID (Context ID) to use, by default CID 1 is used.
+If an APN has been configured once, it's enough to specify the CID used for
+further accesses.
+.It Fl p Ar pin
+Specify SIM PIN.
+.It Fl u Ar username
+Specify username.
+.It Fl k Ar password
+Specify username.
+.It Fl r Ar path
+Path to resolv.conf, default /etc/resolv.conf.
+Use /dev/null to disable updating of name servers.
+.It Fl f Ar path
+Explicitly set the serial port to use as controlling terminal.
+Might be needed if the automatic detection fails.
+.It Fl b
+Fork into background directly, before a connection has been established.
+.It Fl n
+Never fork into background, run entirely in foreground.
+.El
+.Sh EXAMPLES
+Connect to
+.Dq Li apn.example.com
+on interface
+.Dq Li uhso0
+and use PIN
+.Dq 1234
+to enable the SIM card.
+
+.Dl "uhsoctl -a apn.example.com -p 1234 uhso0"
+
+Disconnect from a previously established connection
+
+.Dl "uhsoctl -d uhso0"
+.Sh SEE ALSO
+.Xr uhso 4
diff --git a/usr.sbin/uhsoctl/uhsoctl.c b/usr.sbin/uhsoctl/uhsoctl.c
new file mode 100644
index 0000000..6ed5245
--- /dev/null
+++ b/usr.sbin/uhsoctl/uhsoctl.c
@@ -0,0 +1,1532 @@
+/*-
+ * Copyright (c) 2008-2009 Fredrik Lindberg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/select.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <signal.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <ifaddrs.h>
+#include <libutil.h>
+#include <time.h>
+
+/*
+ * Connection utility to ease connectivity using the raw IP packet interface
+ * available on uhso(4) devices.
+ */
+
+#define TTY_NAME "/dev/%s"
+#define SYSCTL_TEST "dev.uhso.%d.%%driver"
+#define SYSCTL_PORTS "dev.uhso.%d.ports"
+#define SYSCTL_NETIF "dev.uhso.%d.netif"
+#define SYSCTL_NAME_TTY "dev.uhso.%d.port.%s.tty"
+#define SYSCTL_NAME_DESC "dev.uhso.%d.port.%s.desc"
+#define RESOLV_PATH "/etc/resolv.conf"
+#define PIDFILE "/var/run/uhsoctl.%s.pid"
+
+static const char *network_access_type[] = {
+ "GSM",
+ "Compact GSM",
+ "UMTS",
+ "GSM (EGPRS)",
+ "HSDPA",
+ "HSUPA",
+ "HSDPA/HSUPA"
+};
+
+static const char *network_reg_status[] = {
+ "Not registered",
+ "Registered",
+ "Searching for network",
+ "Network registration denied",
+ "Unknown",
+ "Registered (roaming)"
+};
+
+struct ctx {
+ int fd;
+ int flags;
+#define IPASSIGNED 0x01
+#define FLG_NODAEMON 0x02 /* Don't detach from terminal */
+#define FLG_DAEMON 0x04 /* Running as daemon */
+#define FLG_DELAYED 0x08 /* Fork into background after connect */
+#define FLG_NEWDATA 0x10
+#define FLG_WATCHDOG 0x20 /* Watchdog enabled */
+#define FLG_WDEXP 0x40 /* Watchdog expired */
+ const char *ifnam;
+ const char *pin; /* device PIN */
+
+ char pidfile[128];
+ struct pidfh *pfh;
+
+ time_t watchdog;
+
+ /* PDP context settings */
+ int pdp_ctx;
+ const char *pdp_apn;
+ const char *pdp_user;
+ const char *pdp_pwd;
+
+ /* Connection status */
+ int con_status; /* Connected? */
+ char *con_apn; /* Connected APN */
+ char *con_oper; /* Operator name */
+ int con_net_stat; /* Network connection status */
+ int con_net_type; /* Network connection type */
+
+ /* Misc. status */
+ int dbm;
+
+ /* IP and nameserver settings */
+ struct in_addr ip;
+ char **ns;
+ const char *resolv_path;
+ char *resolv; /* Old resolv.conf */
+ size_t resolv_sz;
+};
+
+static int readline_buf(const char *, const char *, char *, size_t);
+static int readline(int, char *, size_t);
+static void daemonize(struct ctx *);
+
+static int at_cmd_async(int, const char *, ...);
+
+typedef union {
+ void *ptr;
+ uint32_t int32;
+} resp_data;
+typedef struct {
+ resp_data val[2];
+} resp_arg;
+typedef void (*resp_cb)(resp_arg *, const char *, const char *);
+
+typedef void (*async_cb)(void *, const char *);
+struct async_handle {
+ const char *cmd;
+ async_cb func;
+};
+
+static void at_async_creg(void *, const char *);
+static void at_async_cgreg(void *, const char *);
+static void at_async_cops(void *, const char *);
+static void at_async_owancall(void *, const char *);
+static void at_async_owandata(void *, const char *);
+static void at_async_csq(void *, const char *);
+
+static struct async_handle async_cmd[] = {
+ { "+CREG", at_async_creg },
+ { "+CGREG", at_async_cgreg },
+ { "+COPS", at_async_cops },
+ { "+CSQ", at_async_csq },
+ { "_OWANCALL", at_async_owancall },
+ { "_OWANDATA", at_async_owandata },
+ { NULL, NULL }
+};
+
+struct timer_entry;
+struct timers {
+ TAILQ_HEAD(, timer_entry) head;
+ int res;
+};
+
+typedef void (*tmr_cb)(int, void *);
+struct timer_entry {
+ TAILQ_ENTRY(timer_entry) next;
+ int id;
+ int timeout;
+ tmr_cb func;
+ void *arg;
+};
+
+
+static struct timers timers;
+static volatile int running = 1;
+static int syslog_open = 0;
+static char syslog_title[64];
+
+/* Periodic timer, runs ready timer tasks every tick */
+static void
+tmr_run(struct timers *tmrs)
+{
+ struct timer_entry *te, *te2;
+
+ te = TAILQ_FIRST(&tmrs->head);
+ if (te == NULL)
+ return;
+
+ te->timeout -= tmrs->res;
+ while (te->timeout <= 0) {
+ te2 = TAILQ_NEXT(te, next);
+ TAILQ_REMOVE(&tmrs->head, te, next);
+ if (te2 != NULL)
+ te2->timeout -= tmrs->res;
+
+ te->func(te->id, te->arg);
+ free(te);
+ te = te2;
+ if (te == NULL)
+ break;
+ }
+}
+
+/* Add a new timer */
+static void
+tmr_add(struct timers *tmrs, int id, int timeout, tmr_cb func, void *arg)
+{
+ struct timer_entry *te, *te2, *te3;
+
+ te = malloc(sizeof(struct timer_entry));
+ memset(te, 0, sizeof(struct timer_entry));
+
+ te->timeout = timeout;
+ te->func = func;
+ te->arg = arg;
+ te->id = id;
+
+ te2 = TAILQ_FIRST(&tmrs->head);
+
+ if (TAILQ_EMPTY(&tmrs->head)) {
+ TAILQ_INSERT_HEAD(&tmrs->head, te, next);
+ } else if (te->timeout < te2->timeout) {
+ te2->timeout -= te->timeout;
+ TAILQ_INSERT_HEAD(&tmrs->head, te, next);
+ } else {
+ while (te->timeout >= te2->timeout) {
+ te->timeout -= te2->timeout;
+ te3 = TAILQ_NEXT(te2, next);
+ if (te3 == NULL || te3->timeout > te->timeout)
+ break;
+ te2 = te3;
+ }
+ TAILQ_INSERT_AFTER(&tmrs->head, te2, te, next);
+ }
+}
+
+#define watchdog_enable(ctx) (ctx)->flags |= FLG_WATCHDOG
+#define watchdog_disable(ctx) (ctx)->flags &= ~FLG_WATCHDOG
+
+static void
+watchdog_reset(struct ctx *ctx, int timeout)
+{
+ struct timespec tp;
+
+ clock_gettime(CLOCK_MONOTONIC, &tp),
+ ctx->watchdog = tp.tv_sec + timeout;
+
+ watchdog_enable(ctx);
+}
+
+static void
+tmr_creg(int id, void *arg)
+{
+ struct ctx *ctx = arg;
+
+ at_cmd_async(ctx->fd, "AT+CREG?\r\n");
+ watchdog_reset(ctx, 10);
+}
+
+static void
+tmr_cgreg(int id, void *arg)
+{
+ struct ctx *ctx = arg;
+
+ at_cmd_async(ctx->fd, "AT+CGREG?\r\n");
+ watchdog_reset(ctx, 10);
+}
+
+static void
+tmr_status(int id, void *arg)
+{
+ struct ctx *ctx = arg;
+
+ at_cmd_async(ctx->fd, "AT+CSQ\r\n");
+ watchdog_reset(ctx, 10);
+}
+
+static void
+tmr_watchdog(int id, void *arg)
+{
+ struct ctx *ctx = arg;
+ pid_t self;
+ struct timespec tp;
+
+ tmr_add(&timers, 1, 5, tmr_watchdog, ctx);
+
+ if (!(ctx->flags & FLG_WATCHDOG))
+ return;
+
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+
+ if (tp.tv_sec >= ctx->watchdog) {
+#ifdef DEBUG
+ fprintf(stderr, "Watchdog expired\n");
+#endif
+ ctx->flags |= FLG_WDEXP;
+ self = getpid();
+ kill(self, SIGHUP);
+ }
+}
+
+static void
+sig_handle(int sig)
+{
+
+ switch (sig) {
+ case SIGHUP:
+ case SIGINT:
+ case SIGQUIT:
+ case SIGTERM:
+ running = 0;
+ break;
+ case SIGALRM:
+ tmr_run(&timers);
+ break;
+ }
+}
+
+static void
+logger(int pri, const char *fmt, ...)
+{
+ char *buf;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vasprintf(&buf, fmt, ap);
+ if (syslog_open)
+ syslog(pri, buf);
+ else {
+ switch (pri) {
+ case LOG_INFO:
+ case LOG_NOTICE:
+ printf("%s\n", buf);
+ break;
+ default:
+ fprintf(stderr, "%s: %s\n", getprogname(), buf);
+ break;
+ }
+ }
+
+ free(buf);
+ va_end(ap);
+}
+
+/* Add/remove IP address from an interface */
+static int
+ifaddr_ad(int d, const char *ifnam, struct sockaddr *sa, struct sockaddr *mask)
+{
+ struct ifaliasreq req;
+ int fd, error;
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0)
+ return (-1);
+
+ memset(&req, 0, sizeof(struct ifaliasreq));
+ strlcpy(req.ifra_name, ifnam, sizeof(req.ifra_name));
+ memcpy(&req.ifra_addr, sa, sa->sa_len);
+ memcpy(&req.ifra_mask, mask, mask->sa_len);
+
+ error = ioctl(fd, d, (char *)&req);
+ close(fd);
+ return (error);
+}
+
+#define if_ifup(ifnam) if_setflags(ifnam, IFF_UP)
+#define if_ifdown(ifnam) if_setflags(ifnam, -IFF_UP)
+
+static int
+if_setflags(const char *ifnam, int flags)
+{
+ struct ifreq ifr;
+ int fd, error;
+ unsigned int oflags = 0;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strlcpy(ifr.ifr_name, ifnam, sizeof(ifr.ifr_name));
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0)
+ return (-1);
+
+ error = ioctl(fd, SIOCGIFFLAGS, &ifr);
+ if (error == 0) {
+ oflags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
+ }
+
+ if (flags < 0)
+ oflags &= ~(-flags);
+ else
+ oflags |= flags;
+
+ ifr.ifr_flags = oflags & 0xffff;
+ ifr.ifr_flagshigh = oflags >> 16;
+
+ error = ioctl(fd, SIOCSIFFLAGS, &ifr);
+ if (error != 0)
+ warn("ioctl SIOCSIFFLAGS");
+
+ close(fd);
+ return (error);
+}
+
+static int
+ifaddr_add(const char *ifnam, struct sockaddr *sa, struct sockaddr *mask)
+{
+ int error;
+
+ error = ifaddr_ad(SIOCAIFADDR, ifnam, sa, mask);
+ if (error != 0)
+ warn("ioctl SIOCAIFADDR");
+ return (error);
+}
+
+static int
+ifaddr_del(const char *ifnam, struct sockaddr *sa, struct sockaddr *mask)
+{
+ int error;
+
+ error = ifaddr_ad(SIOCDIFADDR, ifnam, sa, mask);
+ if (error != 0)
+ warn("ioctl SIOCDIFADDR");
+ return (error);
+}
+
+static int
+set_nameservers(struct ctx *ctx, const char *respath, int ns, ...)
+{
+ int i, n, fd;
+ FILE *fp;
+ char *p;
+ va_list ap;
+ struct stat sb;
+ char buf[512];
+
+ if (ctx->ns != NULL) {
+ for (i = 0; ctx->ns[i] != NULL; i++) {
+ free(ctx->ns[i]);
+ }
+ free(ctx->ns);
+ }
+
+ fd = open(respath, O_RDWR | O_CREAT | O_NOFOLLOW);
+ if (fd < 0)
+ return (-1);
+
+ if (ns == 0) {
+ /* Attempt to restore old resolv.conf */
+ if (ctx->resolv != NULL) {
+ ftruncate(fd, 0);
+ lseek(fd, 0, SEEK_SET);
+ write(fd, ctx->resolv, ctx->resolv_sz);
+ free(ctx->resolv);
+ ctx->resolv = NULL;
+ ctx->resolv_sz = 0;
+ }
+ close(fd);
+ return (0);
+ }
+
+
+ ctx->ns = malloc(sizeof(char *) * (ns + 1));
+ if (ctx->ns == NULL) {
+ close(fd);
+ return (-1);
+ }
+
+ va_start(ap, ns);
+ for (i = 0; i < ns; i++) {
+ p = va_arg(ap, char *);
+ ctx->ns[i] = strdup(p);
+ }
+ ctx->ns[i] = NULL;
+ va_end(ap);
+
+ /* Attempt to backup the old resolv.conf */
+ if (ctx->resolv == NULL) {
+ i = fstat(fd, &sb);
+ if (i == 0 && sb.st_size != 0) {
+ ctx->resolv_sz = sb.st_size;
+ ctx->resolv = malloc(sb.st_size);
+ if (ctx->resolv != NULL) {
+ n = read(fd, ctx->resolv, sb.st_size);
+ if (n != sb.st_size) {
+ free(ctx->resolv);
+ ctx->resolv = NULL;
+ }
+ }
+ }
+ }
+
+
+ ftruncate(fd, 0);
+ lseek(fd, 0, SEEK_SET);
+ fp = fdopen(fd, "w");
+
+ /*
+ * Write back everything other than nameserver entries to the
+ * new resolv.conf
+ */
+ if (ctx->resolv != NULL) {
+ p = ctx->resolv;
+ while ((i = readline_buf(p, ctx->resolv + ctx->resolv_sz, buf,
+ sizeof(buf))) > 0) {
+ p += i;
+ if (strncasecmp(buf, "nameserver", 10) == 0)
+ continue;
+ fprintf(fp, "%s", buf);
+ }
+ }
+
+ for (i = 0; ctx->ns[i] != NULL; i++) {
+ fprintf(fp, "nameserver %s\n", ctx->ns[i]);
+ }
+ fclose(fp);
+ return (0);
+}
+
+/* Read a \n-terminated line from buffer */
+static int
+readline_buf(const char *s, const char *e, char *buf, size_t bufsz)
+{
+ int pos = 0;
+ char *p = buf;
+
+ for (; s < e; s++) {
+ *p = *s;
+ pos++;
+ if (pos >= (bufsz - 1))
+ break;
+ if (*p++ == '\n')
+ break;
+ }
+ *p = '\0';
+ return (pos);
+}
+
+/* Read a \n-terminated line from file */
+static int
+readline(int fd, char *buf, size_t bufsz)
+{
+ int n = 0, pos = 0;
+ char *p = buf;
+
+ for (;;) {
+ n = read(fd, p, 1);
+ if (n <= 0)
+ break;
+ pos++;
+ if (pos >= (bufsz - 1))
+ break;
+ if (*p++ == '\n')
+ break;
+ }
+ *p = '\0';
+ return (n <= 0 ? n : pos);
+}
+
+/*
+ * Synchronous AT command
+ */
+static int
+at_cmd(struct ctx *ctx, const char *resp, resp_cb cb, resp_arg *ra, const char *cf, ...)
+{
+ size_t l;
+ int n, error, retval = 0;
+ va_list ap;
+ fd_set set;
+ char buf[512];
+ char cmd[64];
+
+ va_start(ap, cf);
+ vsnprintf(cmd, sizeof(cmd), cf, ap);
+ va_end(ap);
+
+#ifdef DEBUG
+ fprintf(stderr, "SYNC_CMD: %s", cmd);
+#endif
+
+ l = strlen(cmd);
+ n = write(ctx->fd, cmd, l);
+ if (n <= 0)
+ return (-1);
+
+ if (resp != NULL) {
+ l = strlen(resp);
+#ifdef DEBUG
+ fprintf(stderr, "SYNC_EXP: %s (%d)\n", resp, l);
+#endif
+ }
+
+ for (;;) {
+ bzero(buf, sizeof(buf));
+
+ FD_ZERO(&set);
+ watchdog_reset(ctx, 5);
+ do {
+ FD_SET(ctx->fd, &set);
+ error = select(ctx->fd + 1, &set, NULL, NULL, NULL);
+ if (error < 0 && errno == EINTR && ctx->flags & FLG_WDEXP) {
+ watchdog_disable(ctx);
+ retval = -2;
+ break;
+ }
+ } while (error <= 0 && errno == EINTR);
+
+ if (error <= 0) {
+ retval = -2;
+ break;
+ }
+
+ n = readline(ctx->fd, buf, sizeof(buf));
+ if (n <= 0) {
+ retval = -2;
+ break;
+ }
+
+ if (strcmp(buf, "\r\n") == 0 || strcmp(buf, "\n") == 0)
+ continue;
+
+#ifdef DEBUG
+ fprintf(stderr, "SYNC_RESP: %s", buf);
+#endif
+
+ if (strncmp(buf, "OK", 2) == 0) {
+ break;
+ }
+ else if (strncmp(buf, "ERROR", 5) == 0) {
+ retval = -1;
+ break;
+ }
+
+ if (resp != NULL) {
+ retval = strncmp(resp, buf, l);
+ if (retval == 0 && cb != NULL) {
+ cb(ra, cmd, buf);
+ }
+ }
+ }
+#ifdef DEBUG
+ fprintf(stderr, "SYNC_RETVAL=%d\n", retval);
+#endif
+ return (retval);
+}
+
+static int
+at_cmd_async(int fd, const char *cf, ...)
+{
+ size_t l;
+ va_list ap;
+ char cmd[64];
+
+ va_start(ap, cf);
+ vsnprintf(cmd, sizeof(cmd), cf, ap);
+ va_end(ap);
+
+#ifdef DEBUG
+ fprintf(stderr, "CMD: %s", cmd);
+#endif
+ l = strlen(cmd);
+ return (write(fd, cmd, l));
+}
+
+static void
+saveresp(resp_arg *ra, const char *cmd, const char *resp)
+{
+ char **buf;
+ int i = ra->val[1].int32;
+
+ buf = realloc(ra->val[0].ptr, sizeof(char *) * (i + 1));
+ if (buf == NULL)
+ return;
+
+ buf[i] = strdup(resp);
+
+ ra->val[0].ptr = buf;
+ ra->val[1].int32 = i + 1;
+}
+
+static void
+at_async_creg(void *arg, const char *resp)
+{
+ struct ctx *ctx = arg;
+ int n, reg;
+
+ n = sscanf(resp, "+CREG: %*d,%d", &reg);
+ if (n != 1) {
+ n = sscanf(resp, "+CREG: %d", &reg);
+ if (n != 1)
+ return;
+ }
+
+ if (ctx->con_net_stat != 1 && ctx->con_net_stat != 5) {
+ tmr_add(&timers, 1, 1, tmr_creg, ctx);
+ }
+ else {
+ tmr_add(&timers, 1, 30, tmr_creg, ctx);
+ }
+
+ if (ctx->con_net_stat == reg)
+ return;
+
+ ctx->con_net_stat = reg;
+ at_cmd_async(ctx->fd, "AT+COPS?\r\n");
+}
+
+static void
+at_async_cgreg(void *arg, const char *resp)
+{
+ struct ctx *ctx = arg;
+ int n, reg;
+
+ n = sscanf(resp, "+CGREG: %*d,%d", &reg);
+ if (n != 1) {
+ n = sscanf(resp, "+CGREG: %d", &reg);
+ if (n != 1)
+ return;
+ }
+
+ if (ctx->con_net_stat != 1 && ctx->con_net_stat != 5) {
+ tmr_add(&timers, 1, 1, tmr_cgreg, ctx);
+ }
+ else {
+ tmr_add(&timers, 1, 30, tmr_cgreg, ctx);
+ }
+
+ if (ctx->con_net_stat == reg)
+ return;
+
+ ctx->con_net_stat = reg;
+ at_cmd_async(ctx->fd, "AT+COPS?\r\n");
+}
+
+
+static void
+at_async_cops(void *arg, const char *resp)
+{
+ struct ctx *ctx = arg;
+ int n, at;
+ char opr[64];
+
+ n = sscanf(resp, "+COPS: %*d,%*d,\"%[^\"]\",%d",
+ opr, &at);
+ if (n != 2)
+ return;
+
+ if (ctx->con_oper != NULL) {
+ if (ctx->con_net_type == at &&
+ strcasecmp(opr, ctx->con_oper) == 0)
+ return;
+ free(ctx->con_oper);
+ }
+
+ ctx->con_oper = strdup(opr);
+ ctx->con_net_type = at;
+
+ if (ctx->con_net_stat == 1 || ctx->con_net_stat == 5) {
+ logger(LOG_NOTICE, "%s to \"%s\" (%s)",
+ network_reg_status[ctx->con_net_stat],
+ ctx->con_oper, network_access_type[ctx->con_net_type]);
+ if (ctx->con_status != 1) {
+ at_cmd_async(ctx->fd, "AT_OWANCALL=%d,1,1\r\n",
+ ctx->pdp_ctx);
+ }
+ }
+ else {
+ logger(LOG_NOTICE, "%s (%s)",
+ network_reg_status[ctx->con_net_stat],
+ network_access_type[ctx->con_net_type]);
+ }
+}
+
+/*
+ * Signal strength for pretty console output
+ *
+ * From 3GPP TS 27.007 V8.3.0, Section 8.5
+ * 0 = -113 dBm or less
+ * 1 = -111 dBm
+ * 2...30 = -109...-53 dBm
+ * 31 = -51 dBm or greater
+ *
+ * So, dbm = (rssi * 2) - 113
+*/
+static void
+at_async_csq(void *arg, const char *resp)
+{
+ struct ctx *ctx = arg;
+ int n, rssi;
+
+ n = sscanf(resp, "+CSQ: %d,%*d", &rssi);
+ if (n != 1)
+ return;
+ if (rssi == 99)
+ ctx->dbm = 0;
+ else {
+ ctx->dbm = (rssi * 2) - 113;
+ tmr_add(&timers, 1, 15, tmr_status, ctx);
+ }
+
+ ctx->flags |= FLG_NEWDATA;
+}
+
+static void
+at_async_owancall(void *arg, const char *resp)
+{
+ struct ctx *ctx = arg;
+ int n, i;
+
+ n = sscanf(resp, "_OWANCALL: %*d,%d", &i);
+ if (n != 1)
+ return;
+
+ if (i == ctx->con_status)
+ return;
+
+ at_cmd_async(ctx->fd, "AT_OWANDATA=%d\r\n", ctx->pdp_ctx);
+
+ ctx->con_status = i;
+ if (ctx->con_status == 1) {
+ logger(LOG_NOTICE, "Connected to \"%s\" (%s), %s",
+ ctx->con_oper, ctx->con_apn,
+ network_access_type[ctx->con_net_type]);
+ }
+ else {
+ logger(LOG_NOTICE, "Disconnected from \"%s\" (%s)",
+ ctx->con_oper, ctx->con_apn);
+ }
+}
+
+static void
+at_async_owandata(void *arg, const char *resp)
+{
+ struct ctx *ctx = arg;
+ char ip[40], ns1[40], ns2[40];
+ int n, error, rs;
+ struct ifaddrs *ifap, *ifa;
+ struct sockaddr_in sin, mask;
+ struct sockaddr_dl sdl;
+ struct {
+ struct rt_msghdr rtm;
+ char buf[512];
+ } r;
+ char *cp = r.buf;
+
+ n = sscanf(resp, "_OWANDATA: %*d, %[^,], %*[^,], %[^,], %[^,]",
+ ip, ns1, ns2);
+ if (n != 3)
+ return;
+
+ /* XXX: AF_INET assumption */
+
+ logger(LOG_NOTICE, "IP address: %s, Nameservers: %s, %s", ip, ns1, ns2);
+
+ sin.sin_len = mask.sin_len = sizeof(struct sockaddr_in);
+ memset(&mask.sin_addr.s_addr, 0xff, sizeof(mask.sin_addr.s_addr));
+ sin.sin_family = mask.sin_family = AF_INET;
+
+ if (ctx->flags & IPASSIGNED) {
+ memcpy(&sin.sin_addr.s_addr, &ctx->ip.s_addr,
+ sizeof(sin.sin_addr.s_addr));
+ ifaddr_del(ctx->ifnam, (struct sockaddr *)&sin,
+ (struct sockaddr *)&mask);
+ }
+ inet_pton(AF_INET, ip, &ctx->ip.s_addr);
+ memcpy(&sin.sin_addr.s_addr, &ctx->ip.s_addr,
+ sizeof(sin.sin_addr.s_addr));
+
+ error = ifaddr_add(ctx->ifnam, (struct sockaddr *)&sin,
+ (struct sockaddr *)&mask);
+ if (error != 0) {
+ logger(LOG_ERR, "failed to set ip-address");
+ return;
+ }
+
+ if_ifup(ctx->ifnam);
+
+ ctx->flags |= IPASSIGNED;
+
+ set_nameservers(ctx, ctx->resolv_path, 0);
+ error = set_nameservers(ctx, ctx->resolv_path, 2, ns1, ns2);
+ if (error != 0) {
+ logger(LOG_ERR, "failed to set nameservers");
+ }
+
+ error = getifaddrs(&ifap);
+ if (error != 0) {
+ logger(LOG_ERR, "getifaddrs: %s", strerror(errno));
+ return;
+ }
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr->sa_family != AF_LINK)
+ continue;
+ if (strcmp(ctx->ifnam, ifa->ifa_name) == 0) {
+ memcpy(&sdl, (struct sockaddr_dl *)ifa->ifa_addr,
+ sizeof(struct sockaddr_dl));
+ break;
+ }
+ }
+ if (ifa == NULL)
+ return;
+
+ rs = socket(PF_ROUTE, SOCK_RAW, 0);
+ if (rs < 0) {
+ logger(LOG_ERR, "socket PF_ROUTE: %s", strerror(errno));
+ return;
+ }
+
+ memset(&r, 0, sizeof(r));
+
+ r.rtm.rtm_version = RTM_VERSION;
+ r.rtm.rtm_type = RTM_ADD;
+ r.rtm.rtm_flags = RTF_UP | RTF_STATIC;
+ r.rtm.rtm_pid = getpid();
+ memset(&sin, 0, sizeof(struct sockaddr_in));
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof(struct sockaddr_in);
+
+ memcpy(cp, &sin, sin.sin_len);
+ cp += SA_SIZE(&sin);
+ memcpy(cp, &sdl, sdl.sdl_len);
+ cp += SA_SIZE(&sdl);
+ memcpy(cp, &sin, sin.sin_len);
+ r.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
+ r.rtm.rtm_msglen = sizeof(r);
+
+ n = write(rs, &r, r.rtm.rtm_msglen);
+ if (n != r.rtm.rtm_msglen) {
+ r.rtm.rtm_type = RTM_DELETE;
+ n = write(rs, &r, r.rtm.rtm_msglen);
+ r.rtm.rtm_type = RTM_ADD;
+ n = write(rs, &r, r.rtm.rtm_msglen);
+ }
+
+ if (n != r.rtm.rtm_msglen) {
+ logger(LOG_ERR, "failed to set default route: %s",
+ strerror(errno));
+ }
+ close(rs);
+
+ /* Delayed daemonization */
+ if ((ctx->flags & FLG_DELAYED) && !(ctx->flags & FLG_NODAEMON))
+ daemonize(ctx);
+}
+
+static int
+at_async(struct ctx *ctx, void *arg)
+{
+ int n, i;
+ size_t l;
+ char buf[512];
+
+ watchdog_reset(ctx, 15);
+
+ bzero(buf, sizeof(buf));
+ n = readline(ctx->fd, buf, sizeof(buf));
+ if (n <= 0)
+ return (n <= 0 ? -1 : 0);
+
+#ifdef DEBUG
+ fprintf(stderr, "AT_ASYNC_RESP: %s", buf);
+#endif
+ for (i = 0; async_cmd[i].cmd != NULL; i++) {
+ l = strlen(async_cmd[i].cmd);
+ if (strncmp(buf, async_cmd[i].cmd, l) == 0) {
+ async_cmd[i].func(arg, buf);
+ }
+ }
+ return (0);
+}
+
+static const char *port_type_list[] = {
+ "control", "application", "application2", NULL
+};
+
+/*
+ * Attempts to find a list of control tty for the interface
+ * FreeBSD attaches USb devices per interface so we have to go through
+ * hoops to find which ttys that belong to our network interface.
+ */
+static char **
+get_tty(struct ctx *ctx)
+{
+ char buf[64];
+ char data[128];
+ size_t len;
+ int error;
+ unsigned int i;
+ char **list = NULL;
+ int list_size = 0;
+ const char **p;
+
+ for (i = 0; ; i++) {
+ /* Basic test to check if we're even in the right ballpark */
+ snprintf(buf, 64, SYSCTL_TEST, i);
+ len = 127;
+ error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+ fprintf(stderr, "sysctl %s returned(%d): %s\n",
+ buf, error, error == 0 ? data : "FAILED");
+#endif
+ if (error < 0)
+ return NULL;
+ if (strcasecmp(data, "uhso") != 0)
+ return NULL;
+
+ /* Check for interface */
+ snprintf(buf, 64, SYSCTL_NETIF, i);
+ len = 127;
+ error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+ fprintf(stderr, "sysctl %s returned(%d): %s\n",
+ buf, error, error == 0 ? data : "FAILED");
+#endif
+ if (error < 0)
+ continue;
+
+ if (strcasecmp(data, ctx->ifnam) != 0)
+ continue;
+#ifdef DEBUG
+ fprintf(stderr, "Found %s at %s\n", ctx->ifnam, buf);
+#endif
+ break;
+ }
+
+ /* Add multiplexed ports */
+ for (p = port_type_list; *p != NULL; p++) {
+ snprintf(buf, 64, SYSCTL_NAME_TTY, i, *p);
+ len = 127;
+ error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+ fprintf(stderr, "sysctl %s returned(%d): %s\n",
+ buf, error, error == 0 ? data : "FAILED");
+#endif
+ if (error == 0) {
+ list = realloc(list, (list_size + 1) * sizeof(char *));
+ list[list_size] = malloc(strlen(data) + strlen(TTY_NAME));
+ sprintf(list[list_size], TTY_NAME, data);
+ list_size++;
+ }
+ }
+
+ /*
+ * We can return directly if we found multiplexed serial ports because
+ * devices with these ports only have additional diagnostic ports (useless)
+ * and modem ports (for used with pppd).
+ */
+ if (list_size > 0) {
+ list = realloc(list, (list_size + 1) * sizeof(char *));
+ list[list_size] = NULL;
+ return list;
+ }
+
+ /*
+ * The network port is on a high numbered interface so we walk backwards until
+ * we hit anything other than application/control.
+ */
+
+ for (--i; i >= 0; i--) {
+ /* Basic test to check if we're even in the right ballpark */
+ snprintf(buf, 64, SYSCTL_TEST, i);
+ len = 127;
+ error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+ fprintf(stderr, "sysctl %s returned(%d): %s\n",
+ buf, error, error == 0 ? data : "FAILED");
+#endif
+ if (error < 0)
+ break;
+ if (strcasecmp(data, "uhso") != 0)
+ break;
+
+ /* Test for useable ports */
+ for (p = port_type_list; *p != NULL; p++) {
+ snprintf(buf, 64, SYSCTL_NAME_TTY, i, p);
+ len = 127;
+ error = sysctlbyname(buf, data, &len, NULL, 0);
+ if (error == 0) {
+ list = realloc(list, (list_size + 1) * sizeof(char *));
+ list[list_size] = malloc(strlen(data) + strlen(TTY_NAME));
+ sprintf(list[list_size], TTY_NAME, data);
+ list_size++;
+ }
+ }
+
+ /* HACK! first port is a diagnostic port, we abort here */
+ snprintf(buf, 64, SYSCTL_NAME_TTY, i, "diagnostic");
+ len = 127;
+ error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+ fprintf(stderr, "sysctl %s returned(%d): %s\n",
+ buf, error, error == 0 ? data : "FAILED");
+#endif
+ if (error == 0)
+ break;
+ }
+
+ list = realloc(list, (list_size + 1) * sizeof(char *));
+ list[list_size] = NULL;
+ return list;
+}
+
+static int
+do_connect(struct ctx *ctx, const char *tty)
+{
+ int i, error, needcfg;
+ resp_arg ra;
+ struct termios t;
+ char **buf;
+
+#ifdef DEBUG
+ fprintf(stderr, "Attempting to open %s\n", tty);
+#endif
+
+ ctx->fd = open(tty, O_RDWR);
+ if (ctx->fd < 0) {
+#ifdef DEBUG
+ fprintf(stderr, "Failed to open %s\n", tty);
+#endif
+ return (-1);
+ }
+
+ tcgetattr(ctx->fd, &t);
+ t.c_oflag = 0;
+ t.c_iflag = 0;
+ t.c_cflag = CLOCAL | CREAD;
+ t.c_lflag = 0;
+ tcsetattr(ctx->fd, TCSAFLUSH, &t);
+
+ error = at_cmd(ctx, NULL, NULL, NULL, "AT\r\n");
+ if (error == -2) {
+ warnx("failed to read from device");
+ return (-1);
+ }
+
+ /* Check for PIN */
+ error = at_cmd(ctx, "+CPIN: READY", NULL, NULL, "AT+CPIN?\r\n");
+ if (error != 0) {
+ if (ctx->pin == NULL) {
+ errx(1, "device requires PIN");
+ }
+
+ error = at_cmd(ctx, NULL, NULL, NULL, "AT+CPIN=\"%s\"\r\n",
+ ctx->pin);
+ if (error != 0) {
+ errx(1, "wrong PIN");
+ }
+ }
+
+ /*
+ * Check if a PDP context has been configured and configure one
+ * if needed.
+ */
+ ra.val[0].ptr = NULL;
+ ra.val[1].int32 = 0;
+ error = at_cmd(ctx, "+CGDCONT", saveresp, &ra, "AT+CGDCONT?\r\n");
+ buf = ra.val[0].ptr;
+ needcfg = 1;
+ for (i = 0; i < ra.val[1].int32; i++) {
+ char apn[256];
+ int cid;
+ error = sscanf(buf[i], "+CGDCONT: %d,\"%*[^\"]\",\"%[^\"]\"",
+ &cid, apn);
+ if (error != 2) {
+ free(buf[i]);
+ continue;
+ }
+
+ if (cid == ctx->pdp_ctx) {
+ ctx->con_apn = strdup(apn);
+ if (ctx->pdp_apn != NULL) {
+ if (strcmp(apn, ctx->pdp_apn) == 0)
+ needcfg = 0;
+ }
+ else {
+ needcfg = 0;
+ }
+ }
+ free(buf[i]);
+ }
+ free(buf);
+
+ if (needcfg) {
+ if (ctx->pdp_apn == NULL)
+ errx(1, "device is not configured and no APN given");
+
+ error = at_cmd(ctx, NULL, NULL, NULL,
+ "AT+CGDCONT=%d,,\"%s\"\r\n", ctx->pdp_ctx, ctx->pdp_apn);
+ if (error != 0) {
+ errx(1, "failed to configure device");
+ }
+ ctx->con_apn = strdup(ctx->pdp_apn);
+ }
+
+ if (ctx->pdp_user != NULL || ctx->pdp_pwd != NULL) {
+ at_cmd(ctx, NULL, NULL, NULL,
+ "AT$QCPDPP=%d,1,\"%s\",\"%s\"\r\n", ctx->pdp_ctx,
+ (ctx->pdp_user != NULL) ? ctx->pdp_user : "",
+ (ctx->pdp_pwd != NULL) ? ctx->pdp_pwd : "");
+ }
+
+ error = at_cmd(ctx, NULL, NULL, NULL, "AT_OWANCALL=%d,0,0\r\n",
+ ctx->pdp_ctx);
+ if (error != 0)
+ return (-1);
+
+ at_cmd_async(ctx->fd, "AT+CGREG?\r\n");
+ at_cmd_async(ctx->fd, "AT+CREG?\r\n");
+
+ tmr_add(&timers, 1, 5, tmr_status, ctx);
+ return (0);
+}
+
+static void
+do_disconnect(struct ctx *ctx)
+{
+ struct sockaddr_in sin, mask;
+
+ /* Disconnect */
+ at_cmd(ctx, NULL, NULL, NULL, "AT_OWANCALL=%d,0,0\r\n",
+ ctx->pdp_ctx);
+ close(ctx->fd);
+
+ /* Remove ip-address from interface */
+ if (ctx->flags & IPASSIGNED) {
+ sin.sin_len = mask.sin_len = sizeof(struct sockaddr_in);
+ memset(&mask.sin_addr.s_addr, 0xff,
+ sizeof(mask.sin_addr.s_addr));
+ sin.sin_family = mask.sin_family = AF_INET;
+ memcpy(&sin.sin_addr.s_addr, &ctx->ip.s_addr,
+ sizeof(sin.sin_addr.s_addr));
+ ifaddr_del(ctx->ifnam, (struct sockaddr *)&sin,
+ (struct sockaddr *)&mask);
+
+ if_ifdown(ctx->ifnam);
+ ctx->flags &= ~IPASSIGNED;
+ }
+
+ /* Attempt to reset resolv.conf */
+ set_nameservers(ctx, ctx->resolv_path, 0);
+}
+
+static void
+daemonize(struct ctx *ctx)
+{
+ struct pidfh *pfh;
+ pid_t opid;
+
+ snprintf(ctx->pidfile, 127, PIDFILE, ctx->ifnam);
+
+ pfh = pidfile_open(ctx->pidfile, 0600, &opid);
+ if (pfh == NULL) {
+ warn("Cannot create pidfile %s", ctx->pidfile);
+ return;
+ }
+
+ if (daemon(0, 0) == -1) {
+ warn("Cannot daemonize");
+ pidfile_remove(pfh);
+ return;
+ }
+
+ pidfile_write(pfh);
+ ctx->pfh = pfh;
+ ctx->flags |= FLG_DAEMON;
+
+ snprintf(syslog_title, 63, "%s:%s", getprogname(), ctx->ifnam);
+ openlog(syslog_title, LOG_PID, LOG_USER);
+ syslog_open = 1;
+}
+
+static void
+send_disconnect(const char *ifnam)
+{
+ char pidfile[128];
+ FILE *fp;
+ pid_t pid;
+ int n;
+
+ snprintf(pidfile, 127, PIDFILE, ifnam);
+ fp = fopen(pidfile, "r");
+ if (fp == NULL) {
+ warn("Cannot open %s", pidfile);
+ return;
+ }
+
+ n = fscanf(fp, "%d", &pid);
+ fclose(fp);
+ if (n != 1) {
+ warnx("unable to read daemon pid");
+ return;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "Sending SIGTERM to %d\n", pid);
+#endif
+ kill(pid, SIGTERM);
+}
+
+static void
+usage(const char *exec)
+{
+
+ printf("usage %s [-b] [-n] [-a apn] [-c cid] [-p pin] [-u username] "
+ "[-k password] [-r resolvpath] [-f tty] interface\n", exec);
+ printf("usage %s -d interface\n", exec);
+}
+
+enum {
+ MODE_CONN,
+ MODE_DISC
+};
+
+int
+main(int argc, char *argv[])
+{
+ int ch, error, mode;
+ const char *ifnam = NULL;
+ char *tty = NULL;
+ char **p, **tty_list;
+ fd_set set;
+ struct ctx ctx;
+ struct itimerval it;
+
+ TAILQ_INIT(&timers.head);
+ timers.res = 1;
+
+ ctx.pdp_ctx = 1;
+ ctx.pdp_apn = ctx.pdp_user = ctx.pdp_pwd = NULL;
+ ctx.pin = NULL;
+
+ ctx.con_status = 0;
+ ctx.con_apn = NULL;
+ ctx.con_oper = NULL;
+ ctx.con_net_stat = 0;
+ ctx.con_net_type = -1;
+ ctx.flags = 0;
+ ctx.resolv_path = RESOLV_PATH;
+ ctx.resolv = NULL;
+ ctx.ns = NULL;
+ ctx.dbm = 0;
+
+ mode = MODE_CONN;
+ ctx.flags |= FLG_DELAYED;
+
+ while ((ch = getopt(argc, argv, "?ha:p:c:u:k:r:f:dbn")) != -1) {
+ switch (ch) {
+ case 'a':
+ ctx.pdp_apn = argv[optind - 1];
+ break;
+ case 'c':
+ ctx.pdp_ctx = strtol(argv[optind - 1], NULL, 10);
+ if (ctx.pdp_ctx < 1) {
+ warnx("Invalid context ID, defaulting to 1");
+ ctx.pdp_ctx = 1;
+ }
+ break;
+ case 'p':
+ ctx.pin = argv[optind - 1];
+ break;
+ case 'u':
+ ctx.pdp_user = argv[optind - 1];
+ break;
+ case 'k':
+ ctx.pdp_pwd = argv[optind - 1];
+ break;
+ case 'r':
+ ctx.resolv_path = argv[optind - 1];
+ break;
+ case 'd':
+ mode = MODE_DISC;
+ break;
+ case 'b':
+ ctx.flags &= ~FLG_DELAYED;
+ break;
+ case 'n':
+ ctx.flags |= FLG_NODAEMON;
+ break;
+ case 'f':
+ tty = argv[optind - 1];
+ break;
+ case 'h':
+ case '?':
+ default:
+ usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1)
+ errx(1, "no interface given");
+
+ ifnam = argv[argc - 1];
+ ctx.ifnam = strdup(ifnam);
+
+ switch (mode) {
+ case MODE_DISC:
+ printf("Disconnecting %s\n", ifnam);
+ send_disconnect(ifnam);
+ exit(EXIT_SUCCESS);
+ default:
+ break;
+ }
+
+ signal(SIGHUP, sig_handle);
+ signal(SIGINT, sig_handle);
+ signal(SIGQUIT, sig_handle);
+ signal(SIGTERM, sig_handle);
+ signal(SIGALRM, sig_handle);
+
+ it.it_interval.tv_sec = 1;
+ it.it_interval.tv_usec = 0;
+ it.it_value.tv_sec = 1;
+ it.it_value.tv_usec = 0;
+ error = setitimer(ITIMER_REAL, &it, NULL);
+ if (error != 0)
+ errx(1, "setitimer");
+
+ tmr_add(&timers, 1, 5, &tmr_watchdog, &ctx);
+ watchdog_reset(&ctx, 15);
+
+ if (tty != NULL) {
+ error = do_connect(&ctx, tty);
+ if (error != 0)
+ errx(1, "Failed to open %s", tty);
+ }
+ else {
+ tty_list = get_tty(&ctx);
+#ifdef DEBUG
+ if (tty_list == NULL) {
+ fprintf(stderr, "get_tty returned empty list\n");
+ } else {
+ fprintf(stderr, "tty list:\n");
+ for (p = tty_list; *p != NULL; p++) {
+ fprintf(stderr, "\t %s\n", *p);
+ }
+ }
+#endif
+ for (p = tty_list; *p != NULL; p++) {
+ error = do_connect(&ctx, *p);
+ if (error == 0) {
+ tty = *p;
+ break;
+ }
+ }
+ if (*p == NULL)
+ errx(1, "Failed to obtain a control port, "
+ "try specifying one manually");
+ }
+
+ if (!(ctx.flags & FLG_DELAYED) && !(ctx.flags & FLG_NODAEMON))
+ daemonize(&ctx);
+
+
+ FD_ZERO(&set);
+ FD_SET(ctx.fd, &set);
+ for (;;) {
+
+ watchdog_disable(&ctx);
+ error = select(ctx.fd + 1, &set, NULL, NULL, NULL);
+ if (error <= 0) {
+ if (running && errno == EINTR)
+ continue;
+ if (ctx.flags & FLG_WDEXP) {
+ ctx.flags &= ~FLG_WDEXP;
+ watchdog_reset(&ctx, 5);
+ do_disconnect(&ctx);
+ watchdog_reset(&ctx, 15);
+ do_connect(&ctx, tty);
+ running = 1;
+ continue;
+ }
+
+ break;
+ }
+
+ if (FD_ISSET(ctx.fd, &set)) {
+ watchdog_reset(&ctx, 15);
+ error = at_async(&ctx, &ctx);
+ if (error != 0)
+ break;
+ }
+ FD_SET(ctx.fd, &set);
+
+ if (!(ctx.flags & FLG_DAEMON) && (ctx.flags & IPASSIGNED)) {
+ printf("Status: %s (%s)",
+ ctx.con_status ? "connected" : "disconnected",
+ network_access_type[ctx.con_net_type]);
+ if (ctx.dbm < 0)
+ printf(", signal: %d dBm", ctx.dbm);
+ printf("\r");
+ fflush(stdout);
+ }
+ }
+ if (!(ctx.flags & FLG_DAEMON) && (ctx.flags & IPASSIGNED))
+ printf("\n");
+
+ signal(SIGHUP, SIG_DFL);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGALRM, SIG_IGN);
+
+ do_disconnect(&ctx);
+
+ if (ctx.flags & FLG_DAEMON) {
+ pidfile_remove(ctx.pfh);
+ if (syslog_open)
+ closelog();
+ }
+
+ return (0);
+}
diff --git a/usr.sbin/usbconfig/Makefile b/usr.sbin/usbconfig/Makefile
index 1cd0928..0aa51fa 100644
--- a/usr.sbin/usbconfig/Makefile
+++ b/usr.sbin/usbconfig/Makefile
@@ -4,6 +4,7 @@
PROG= usbconfig
MAN= usbconfig.8
SRCS= usbconfig.c dump.c
+DPADD+= ${LIBUSB}
LDADD+= -lusb
.include <bsd.prog.mk>
diff --git a/usr.sbin/usbconfig/dump.c b/usr.sbin/usbconfig/dump.c
index 6a2fd02..4e527ea 100644
--- a/usr.sbin/usbconfig/dump.c
+++ b/usr.sbin/usbconfig/dump.c
@@ -100,21 +100,66 @@ dump_field(struct libusb20_device *pdev, const char *plevel,
printf("%s%s = 0x%04x ", plevel, field, value);
- if ((field[0] != 'i') || (field[1] == 'd')) {
- printf("\n");
- return;
- }
- if (value == 0) {
- printf(" <no string>\n");
- return;
+ if (strlen(plevel) == 8) {
+ /* Endpoint Descriptor */
+
+ if (strcmp(field, "bEndpointAddress") == 0) {
+ if (value & 0x80)
+ printf(" <IN>\n");
+ else
+ printf(" <OUT>\n");
+ return;
+ }
+
+ if (strcmp(field, "bmAttributes") == 0) {
+ switch (value & 0x03) {
+ case 0:
+ printf(" <CONTROL>\n");
+ break;
+ case 1:
+ switch (value & 0x0C) {
+ case 0x00:
+ printf(" <ISOCHRONOUS>\n");
+ break;
+ case 0x04:
+ printf(" <ASYNC-ISOCHRONOUS>\n");
+ break;
+ case 0x08:
+ printf(" <ADAPT-ISOCHRONOUS>\n");
+ break;
+ default:
+ printf(" <SYNC-ISOCHRONOUS>\n");
+ break;
+ }
+ break;
+ case 2:
+ printf(" <BULK>\n");
+ break;
+ default:
+ printf(" <INTERRUPT>\n");
+ break;
+ }
+ return;
+ }
}
- if (libusb20_dev_req_string_simple_sync(pdev, value,
- temp_string, sizeof(temp_string))) {
- printf(" <retrieving string failed>\n");
+
+ if ((field[0] == 'i') && (field[1] != 'd')) {
+ /* Indirect String Descriptor */
+ if (value == 0) {
+ printf(" <no string>\n");
+ return;
+ }
+ if (libusb20_dev_req_string_simple_sync(pdev, value,
+ temp_string, sizeof(temp_string))) {
+ printf(" <retrieving string failed>\n");
+ return;
+ }
+ printf(" <%s>\n", temp_string);
return;
}
- printf(" <%s>\n", temp_string);
- return;
+
+ /* No additional information */
+ printf("\n");
}
static void
@@ -320,3 +365,40 @@ dump_config(struct libusb20_device *pdev, uint8_t all_cfg)
}
return;
}
+
+void
+dump_string_by_index(struct libusb20_device *pdev, uint8_t str_index)
+{
+ char *pbuf;
+ uint8_t n;
+ uint8_t len;
+
+ pbuf = malloc(256);
+ if (pbuf == NULL)
+ err(1, "out of memory");
+
+ if (str_index == 0) {
+ /* language table */
+ if (libusb20_dev_req_string_sync(pdev,
+ str_index, 0, pbuf, 256)) {
+ printf("STRING_0x%02x = <read error>\n", str_index);
+ } else {
+ printf("STRING_0x%02x = ", str_index);
+ len = (uint8_t)pbuf[0];
+ for (n = 0; n != len; n++) {
+ printf("0x%02x%s", (uint8_t)pbuf[n],
+ (n != (len-1)) ? ", " : "");
+ }
+ printf("\n");
+ }
+ } else {
+ /* ordinary string */
+ if (libusb20_dev_req_string_simple_sync(pdev,
+ str_index, pbuf, 256)) {
+ printf("STRING_0x%02x = <read error>\n", str_index);
+ } else {
+ printf("STRING_0x%02x = <%s>\n", str_index, pbuf);
+ }
+ }
+ free(pbuf);
+}
diff --git a/usr.sbin/usbconfig/dump.h b/usr.sbin/usbconfig/dump.h
index 7fafdfd..581684a 100644
--- a/usr.sbin/usbconfig/dump.h
+++ b/usr.sbin/usbconfig/dump.h
@@ -24,11 +24,17 @@
* SUCH DAMAGE.
*/
+#ifndef _DUMP_H_
+#define _DUMP_H_
+
const char *dump_mode(uint8_t value);
const char *dump_speed(uint8_t value);
const char *dump_power_mode(uint8_t value);
+void dump_string_by_index(struct libusb20_device *pdev, uint8_t index);
void dump_device_info(struct libusb20_device *pdev, uint8_t show_drv);
void dump_be_quirk_names(struct libusb20_backend *pbe);
void dump_be_dev_quirks(struct libusb20_backend *pbe);
void dump_device_desc(struct libusb20_device *pdev);
void dump_config(struct libusb20_device *pdev, uint8_t all_cfg);
+
+#endif /* _DUMP_H_ */
diff --git a/usr.sbin/usbconfig/usbconfig.8 b/usr.sbin/usbconfig/usbconfig.8
index 07dbed2..971367d 100644
--- a/usr.sbin/usbconfig/usbconfig.8
+++ b/usr.sbin/usbconfig/usbconfig.8
@@ -1,6 +1,6 @@
.\" $FreeBSD$
.\"
-.\" Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+.\" Copyright (c) 2008-2010 Hans Petter Selasky. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Sep 28, 2008
+.Dd January 6, 2010
.Dt USBCONFIG 8
.Os
.Sh NAME
@@ -34,6 +34,9 @@
.Op Fl u Ar unit
.Op Fl a Ar addr
.Op cmds...
+.Nm
+.Op Fl d Ar [ugen]<unit>.<addr>
+.Op cmds...
.Sh DESCRIPTION
The
.Nm
@@ -46,8 +49,48 @@ Limit device range to USB devices connected to the given USBUS unit.
.It Fl a Ar addr
Limit device range to the given USB device index.
Should only be used in conjunction with the unit argument.
+.It Fl d Ar [ugen]<unit>.<addr>
+Limit device range to USB devices connected to the given unit and address.
+The unit and address coordinates may be prefixed by the lowercased word "ugen".
.It Fl h
Show help and available commands.
.El
+.Pp
+When called without options,
+.Nm
+prints a list of all available USB devices.
+.Sh EXAMPLES
+Show information about the device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_info
+.Pp
+Dump HID descriptor for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 do_request 0x81 0x06 0x2200 0 0x100
+.Pp
+Dump string descriptor at index Z for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_string Z
+.Pp
+Dump current configuration descriptor for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_curr_config_desc
+.Pp
+Dump device descriptor for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_device_desc
+.Pp
+Program the device on USB bus 1 at address 2 to suspend, resume, power off, go into power save, or power on:
+.Pp
+.Dl usbconfig -u 1 -a 2 suspend
+.Dl usbconfig -u 1 -a 2 resume
+.Dl usbconfig -u 1 -a 2 power_off
+.Dl usbconfig -u 1 -a 2 power_save
+.Dl usbconfig -u 1 -a 2 power_on
+.Pp
+Display a list of available quirk names:
+.Pp
+.Dl usbconfig dump_quirk_names
+.Pp
.Sh SEE ALSO
.Xr usb 4
diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c
index 810e183..2bd3668 100644
--- a/usr.sbin/usbconfig/usbconfig.c
+++ b/usr.sbin/usbconfig/usbconfig.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
/*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2008-2009 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -81,6 +81,8 @@ struct options {
uint8_t got_show_iface_driver:1;
uint8_t got_remove_device_quirk:1;
uint8_t got_add_device_quirk:1;
+ uint8_t got_remove_quirk:1;
+ uint8_t got_add_quirk:1;
uint8_t got_dump_string:1;
uint8_t got_do_request:1;
};
@@ -94,6 +96,7 @@ struct token {
enum {
T_UNIT,
T_ADDR,
+ T_UGEN,
T_IFACE,
T_SET_CONFIG,
T_SET_ALT,
@@ -101,6 +104,8 @@ enum {
T_GET_TEMPLATE,
T_ADD_DEVICE_QUIRK,
T_REMOVE_DEVICE_QUIRK,
+ T_ADD_QUIRK,
+ T_REMOVE_QUIRK,
T_SHOW_IFACE_DRIVER,
T_DUMP_QUIRK_NAMES,
T_DUMP_DEVICE_QUIRKS,
@@ -124,6 +129,7 @@ static struct options options;
static const struct token token[] = {
{"-u", T_UNIT, 1},
{"-a", T_ADDR, 1},
+ {"-d", T_UGEN, 1},
{"-i", T_IFACE, 1},
{"set_config", T_SET_CONFIG, 1},
{"set_alt", T_SET_ALT, 1},
@@ -131,6 +137,8 @@ static const struct token token[] = {
{"get_template", T_GET_TEMPLATE, 0},
{"add_dev_quirk_vplh", T_ADD_DEVICE_QUIRK, 5},
{"remove_dev_quirk_vplh", T_REMOVE_DEVICE_QUIRK, 5},
+ {"add_quirk", T_ADD_QUIRK, 1},
+ {"remove_quirk", T_REMOVE_QUIRK, 1},
{"dump_quirk_names", T_DUMP_QUIRK_NAMES, 0},
{"dump_device_quirks", T_DUMP_DEVICE_QUIRKS, 0},
{"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
@@ -167,7 +175,7 @@ be_dev_remove_quirk(struct libusb20_backend *pbe,
error = libusb20_be_remove_dev_quirk(pbe, &q);
if (error) {
- printf("Removing quirk '%s' failed, continuing.\n", str);
+ fprintf(stderr, "Removing quirk '%s' failed, continuing.\n", str);
}
return;
}
@@ -190,7 +198,7 @@ be_dev_add_quirk(struct libusb20_backend *pbe,
error = libusb20_be_add_dev_quirk(pbe, &q);
if (error) {
- printf("Adding quirk '%s' failed, continuing.\n", str);
+ fprintf(stderr, "Adding quirk '%s' failed, continuing.\n", str);
}
return;
}
@@ -247,11 +255,20 @@ get_int(const char *s)
}
static void
+duplicate_option(const char *ptr)
+{
+ fprintf(stderr, "Syntax error: "
+ "Duplicate option: '%s'\n", ptr);
+ exit(1);
+}
+
+static void
usage(void)
{
- printf(""
+ fprintf(stderr, ""
"usbconfig - configure the USB subsystem" "\n"
"usage: usbconfig -u <busnum> -a <devaddr> -i <ifaceindex> [cmds...]" "\n"
+ "usage: usbconfig -d [ugen]<busnum>.<devaddr> -i <ifaceindex> [cmds...]" "\n"
"commands:" "\n"
" set_config <cfg_index>" "\n"
" set_alt <alt_index>" "\n"
@@ -259,6 +276,8 @@ usage(void)
" get_template" "\n"
" add_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
" remove_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
+ " add_quirk <quirk>" "\n"
+ " remove_quirk <quirk>" "\n"
" dump_quirk_names" "\n"
" dump_device_quirks" "\n"
" dump_device_desc" "\n"
@@ -330,7 +349,7 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
if (opt->got_set_template) {
opt->got_any--;
if (libusb20_be_set_template(pbe, opt->template)) {
- printf("Setting USB template %u failed, "
+ fprintf(stderr, "Setting USB template %u failed, "
"continuing.\n", opt->template);
}
}
@@ -360,25 +379,33 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
}
matches++;
+ if (opt->got_remove_quirk) {
+ struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+
+ ddesc = libusb20_dev_get_device_desc(pdev);
+
+ be_dev_remove_quirk(pbe,
+ ddesc->idVendor, ddesc->idProduct,
+ ddesc->bcdDevice, ddesc->bcdDevice,
+ opt->quirkname);
+ }
+
+ if (opt->got_add_quirk) {
+ struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+
+ ddesc = libusb20_dev_get_device_desc(pdev);
+
+ be_dev_add_quirk(pbe,
+ ddesc->idVendor, ddesc->idProduct,
+ ddesc->bcdDevice, ddesc->bcdDevice,
+ opt->quirkname);
+ }
+
if (libusb20_dev_open(pdev, 0)) {
err(1, "could not open device");
}
if (opt->got_dump_string) {
- char *pbuf;
-
- pbuf = malloc(256);
- if (pbuf == NULL) {
- err(1, "out of memory");
- }
- if (libusb20_dev_req_string_simple_sync(pdev,
- opt->string_index, pbuf, 256)) {
- printf("STRING_0x%02x = <read error>\n",
- opt->string_index);
- } else {
- printf("STRING_0x%02x = <%s>\n",
- opt->string_index, pbuf);
- }
- free(pbuf);
+ dump_string_by_index(pdev, opt->string_index);
}
if (opt->got_do_request) {
uint16_t actlen;
@@ -501,6 +528,9 @@ main(int argc, char **argv)
{
struct libusb20_backend *pbe;
struct options *opt = &options;
+ const char *ptr;
+ int unit;
+ int addr;
int n;
int t;
@@ -518,6 +548,28 @@ main(int argc, char **argv)
if (t > 255)
t = 255;
switch (get_token(argv[n], t)) {
+ case T_ADD_QUIRK:
+ if (opt->got_add_quirk) {
+ flush_command(pbe, opt);
+ }
+ opt->quirkname = argv[n + 1];
+ n++;
+
+ opt->got_add_quirk = 1;
+ opt->got_any++;
+ break;
+
+ case T_REMOVE_QUIRK:
+ if (opt->got_remove_quirk) {
+ flush_command(pbe, opt);
+ }
+ opt->quirkname = argv[n + 1];
+ n++;
+
+ opt->got_remove_quirk = 1;
+ opt->got_any++;
+ break;
+
case T_ADD_DEVICE_QUIRK:
if (opt->got_add_device_quirk) {
flush_command(pbe, opt);
@@ -548,11 +600,15 @@ main(int argc, char **argv)
break;
case T_DUMP_QUIRK_NAMES:
+ if (opt->got_dump_quirk_names)
+ duplicate_option(argv[n]);
opt->got_dump_quirk_names = 1;
opt->got_any++;
break;
case T_DUMP_DEVICE_QUIRKS:
+ if (opt->got_dump_device_quirks)
+ duplicate_option(argv[n]);
opt->got_dump_device_quirks = 1;
opt->got_any++;
break;
@@ -561,6 +617,33 @@ main(int argc, char **argv)
opt->got_show_iface_driver = 1;
break;
+ case T_UGEN:
+ if (opt->got_any) {
+ /* allow multiple commands on the same line */
+ flush_command(pbe, opt);
+ }
+ ptr = argv[n + 1];
+
+ if ((ptr[0] == 'u') &&
+ (ptr[1] == 'g') &&
+ (ptr[2] == 'e') &&
+ (ptr[3] == 'n'))
+ ptr += 4;
+
+ if ((sscanf(ptr, "%d.%d",
+ &unit, &addr) != 2) ||
+ (unit < 0) || (unit > 65535) ||
+ (addr < 0) || (addr > 65535)) {
+ errx(1, "cannot "
+ "parse '%s'", argv[n + 1]);
+ }
+ opt->bus = unit;
+ opt->addr = addr;
+ opt->got_bus = 1;
+; opt->got_addr = 1;
+ n++;
+ break;
+
case T_UNIT:
if (opt->got_any) {
/* allow multiple commands on the same line */
@@ -581,84 +664,112 @@ main(int argc, char **argv)
n++;
break;
case T_SET_CONFIG:
+ if (opt->got_set_config)
+ duplicate_option(argv[n]);
opt->config_index = num_id(argv[n + 1], "cfg_index");
opt->got_set_config = 1;
opt->got_any++;
n++;
break;
case T_SET_ALT:
+ if (opt->got_set_alt)
+ duplicate_option(argv[n]);
opt->alt_index = num_id(argv[n + 1], "cfg_index");
opt->got_set_alt = 1;
opt->got_any++;
n++;
break;
case T_SET_TEMPLATE:
+ if (opt->got_set_template)
+ duplicate_option(argv[n]);
opt->template = get_int(argv[n + 1]);
opt->got_set_template = 1;
opt->got_any++;
n++;
break;
case T_GET_TEMPLATE:
+ if (opt->got_get_template)
+ duplicate_option(argv[n]);
opt->got_get_template = 1;
opt->got_any++;
break;
case T_DUMP_DEVICE_DESC:
+ if (opt->got_dump_device_desc)
+ duplicate_option(argv[n]);
opt->got_dump_device_desc = 1;
opt->got_any++;
break;
case T_DUMP_CURR_CONFIG_DESC:
+ if (opt->got_dump_curr_config)
+ duplicate_option(argv[n]);
opt->got_dump_curr_config = 1;
opt->got_any++;
break;
case T_DUMP_ALL_CONFIG_DESC:
+ if (opt->got_dump_all_config)
+ duplicate_option(argv[n]);
opt->got_dump_all_config = 1;
opt->got_any++;
break;
case T_DUMP_INFO:
+ if (opt->got_dump_info)
+ duplicate_option(argv[n]);
opt->got_dump_info = 1;
opt->got_any++;
break;
case T_DUMP_STRING:
- if (opt->got_dump_string) {
- flush_command(pbe, opt);
- }
+ if (opt->got_dump_string)
+ duplicate_option(argv[n]);
opt->string_index = num_id(argv[n + 1], "str_index");
opt->got_dump_string = 1;
opt->got_any++;
n++;
break;
case T_SUSPEND:
+ if (opt->got_suspend)
+ duplicate_option(argv[n]);
opt->got_suspend = 1;
opt->got_any++;
break;
case T_RESUME:
+ if (opt->got_resume)
+ duplicate_option(argv[n]);
opt->got_resume = 1;
opt->got_any++;
break;
case T_POWER_OFF:
+ if (opt->got_power_off)
+ duplicate_option(argv[n]);
opt->got_power_off = 1;
opt->got_any++;
break;
case T_POWER_SAVE:
+ if (opt->got_power_save)
+ duplicate_option(argv[n]);
opt->got_power_save = 1;
opt->got_any++;
break;
case T_POWER_ON:
+ if (opt->got_power_on)
+ duplicate_option(argv[n]);
opt->got_power_on = 1;
opt->got_any++;
break;
case T_RESET:
+ if (opt->got_reset)
+ duplicate_option(argv[n]);
opt->got_reset = 1;
opt->got_any++;
break;
case T_LIST:
+ if (opt->got_list)
+ duplicate_option(argv[n]);
opt->got_list = 1;
opt->got_any++;
break;
case T_DO_REQUEST:
- if (opt->got_do_request) {
- flush_command(pbe, opt);
- }
+ if (opt->got_do_request)
+ duplicate_option(argv[n]);
LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &opt->setup);
opt->setup.bmRequestType = num_id(argv[n + 1], "bmReqTyp");
opt->setup.bRequest = num_id(argv[n + 2], "bReq");
diff --git a/usr.sbin/usbdevs/Makefile b/usr.sbin/usbdevs/Makefile
index 985bc7a..3cfc8ef 100644
--- a/usr.sbin/usbdevs/Makefile
+++ b/usr.sbin/usbdevs/Makefile
@@ -4,6 +4,4 @@
PROG= usbdevs
MAN= usbdevs.8
-WARNS?= 2
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/usbdevs/usbdevs.8 b/usr.sbin/usbdevs/usbdevs.8
index 3226dd5..dd56fc8 100644
--- a/usr.sbin/usbdevs/usbdevs.8
+++ b/usr.sbin/usbdevs/usbdevs.8
@@ -12,13 +12,6 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with 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 NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/usr.sbin/usbdevs/usbdevs.c b/usr.sbin/usbdevs/usbdevs.c
index eea8167..b51e3c5 100644
--- a/usr.sbin/usbdevs/usbdevs.c
+++ b/usr.sbin/usbdevs/usbdevs.c
@@ -16,13 +16,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with 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 NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/usr.sbin/vidcontrol/Makefile b/usr.sbin/vidcontrol/Makefile
index 074f941..8c8f6bb 100644
--- a/usr.sbin/vidcontrol/Makefile
+++ b/usr.sbin/vidcontrol/Makefile
@@ -3,6 +3,4 @@
PROG= vidcontrol
SRCS= vidcontrol.c decode.c
-WARNS?= 6
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/vidcontrol/vidcontrol.1 b/usr.sbin/vidcontrol/vidcontrol.1
index 2abaa1e..cb545ee 100644
--- a/usr.sbin/vidcontrol/vidcontrol.1
+++ b/usr.sbin/vidcontrol/vidcontrol.1
@@ -38,6 +38,7 @@
.Op Fl r Ar foreground Ar background
.Op Fl S Cm on | off
.Op Fl s Ar number
+.Op Fl T Cm xterm | cons25
.Op Fl t Ar N | Cm off
.Op Ar mode
.Op Ar foreground Op Ar background
@@ -243,6 +244,8 @@ is supposed to be physically secure.
.It Fl s Ar number
Set the current vty to
.Ar number .
+.It Fl T Cm xterm | cons25
+Switch between xterm and cons25 style terminal emulation.
.It Fl t Ar N | Cm off
Set the screensaver timeout to
.Ar N
diff --git a/usr.sbin/vidcontrol/vidcontrol.c b/usr.sbin/vidcontrol/vidcontrol.c
index 847ff3e..06afe53 100644
--- a/usr.sbin/vidcontrol/vidcontrol.c
+++ b/usr.sbin/vidcontrol/vidcontrol.c
@@ -185,8 +185,8 @@ usage(void)
"usage: vidcontrol [-CdHLPpx] [-b color] [-c appearance] [-f [size] file]",
" [-g geometry] [-h size] [-i adapter | mode] [-l screen_map]",
" [-M char] [-m on | off] [-r foreground background]",
-" [-S on | off] [-s number] [-t N | off] [mode]",
-" [foreground [background]] [show]");
+" [-S on | off] [-s number] [-T xterm | cons25] [-t N | off]",
+" [mode] [foreground [background]] [show]");
exit(1);
}
@@ -1159,6 +1159,18 @@ clear_history(void)
}
}
+static void
+set_terminal_mode(char *arg)
+{
+
+ if (strcmp(arg, "xterm") == 0)
+ fprintf(stderr, "\033[=T");
+ else if (strcmp(arg, "cons25") == 0)
+ fprintf(stderr, "\033[=1T");
+ else
+ usage();
+}
+
int
main(int argc, char **argv)
@@ -1175,7 +1187,8 @@ main(int argc, char **argv)
err(1, "must be on a virtual console");
dumpmod = 0;
dumpopt = DUMP_FBF;
- while((opt = getopt(argc, argv, "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:t:x")) != -1)
+ while ((opt = getopt(argc, argv,
+ "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:T:t:x")) != -1)
switch(opt) {
case 'b':
set_border_color(optarg);
@@ -1244,6 +1257,9 @@ main(int argc, char **argv)
case 's':
set_console(optarg);
break;
+ case 'T':
+ set_terminal_mode(optarg);
+ break;
case 't':
set_screensaver_timeout(optarg);
break;
diff --git a/usr.sbin/vipw/Makefile b/usr.sbin/vipw/Makefile
index 69a9df9..d98e401 100644
--- a/usr.sbin/vipw/Makefile
+++ b/usr.sbin/vipw/Makefile
@@ -4,8 +4,6 @@
PROG= vipw
MAN= vipw.8
-WARNS?= 4
-
DPADD= ${LIBUTIL}
LDADD= -lutil
diff --git a/usr.sbin/wake/Makefile b/usr.sbin/wake/Makefile
index ee303af..f75d469 100644
--- a/usr.sbin/wake/Makefile
+++ b/usr.sbin/wake/Makefile
@@ -2,6 +2,7 @@
PROG= wake
MAN= wake.8
-WARNS?= 6
+
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/usr.sbin/wake/wake.8 b/usr.sbin/wake/wake.8
index 03a283b..ce30abf 100644
--- a/usr.sbin/wake/wake.8
+++ b/usr.sbin/wake/wake.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.\" Copyright (c) 2009 Marc Balmer <marc@msys.ch>
+.\" Copyright (c) 2009, 2010 Marc Balmer <marc@msys.ch>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd June 27 2009
+.Dd December 27, 2009
.Dt WAKE 8
.Os
.Sh NAME
@@ -23,7 +23,8 @@
.Nd send Wake on LAN frames to hosts on a local Ethernet network
.Sh SYNOPSIS
.Nm
-.Ar interface
+.Op Ar interface
+.Ar lladdr
.Op Ar lladdr ...
.Sh DESCRIPTION
The
@@ -36,21 +37,27 @@ and can be used to power on machines from a remote system without
having physical access to them.
.Pp
.Ar interface
-is the network interface of the local machine.
+is an Ethernet interface of the local machine and is used to send the
+Wake on LAN frames over it.
+If there is only one Ethernet device available that is up and running, then the
+.Ar interface
+argument can be omitted.
.Ar lladdr
-are the link layer addresses of the remote machines
-and can be specified as the actual hardware address
+is the link layer address of the remote machine.
+This can be specified as the actual hardware address
(six hexadecimal numbers separated by colons)
-or a hostname entry in
+or as a hostname entry in
.Pa /etc/ethers .
-Link layer addresses can be determined and set on
-.Fx
-machines using
+.Nm
+accepts multiple
+.Ar lladdr
+addresses.
+Link layer addresses can be determined and set using
.Xr ifconfig 8 .
.Sh FILES
.Bl -tag -width "/etc/ethers" -compact
.It /etc/ethers
-Ethernet host name database.
+Ethernet host name data base.
.El
.Sh SEE ALSO
.Xr ethers 5 ,
diff --git a/usr.sbin/wake/wake.c b/usr.sbin/wake/wake.c
index 1a3a65f..d6ba931 100644
--- a/usr.sbin/wake/wake.c
+++ b/usr.sbin/wake/wake.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Marc Balmer <marc@msys.ch>
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Marc Balmer <marc@msys.ch>
* Copyright (C) 2000 Eugene M. Kim. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,11 +32,14 @@ __FBSDID("$FreeBSD$");
#include <sys/time.h>
#include <net/bpf.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 <err.h>
#include <fcntl.h>
+#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -53,38 +56,29 @@ __FBSDID("$FreeBSD$");
#endif
static int bind_if_to_bpf(char const *ifname, int bpf);
+static int find_ether(char *dst, size_t len);
static int get_ether(char const *text, struct ether_addr *addr);
static int send_wakeup(int bpf, struct ether_addr const *addr);
static void usage(void);
-static int wake(const char *iface, const char *host);
+static int wake(int bpf, const char *host);
static void
usage(void)
{
- (void)fprintf(stderr, "usage: wake interface lladdr...\n");
+ (void)fprintf(stderr, "usage: wake [interface] lladdr [lladdr ...]\n");
exit(1);
}
static int
-wake(const char *iface, const char *host)
+wake(int bpf, const char *host)
{
struct ether_addr macaddr;
- int bpf, res;
- bpf = open(_PATH_BPF, O_RDWR);
- if (bpf == -1) {
- warn("no bpf");
+ if (get_ether(host, &macaddr) == -1)
return (-1);
- }
- if (bind_if_to_bpf(iface, bpf) == -1 ||
- get_ether(host, &macaddr) == -1) {
- (void)close(bpf);
- return (-1);
- }
- res = send_wakeup(bpf, &macaddr);
- (void)close(bpf);
- return (res);
+
+ return send_wakeup(bpf, &macaddr);
}
static int
@@ -94,26 +88,50 @@ bind_if_to_bpf(char const *ifname, int bpf)
u_int dlt;
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
- sizeof(ifr.ifr_name)) {
- warnx("interface name too long: %s", ifname);
+ sizeof(ifr.ifr_name))
return (-1);
- }
- if (ioctl(bpf, BIOCSETIF, &ifr) == -1) {
- warn("ioctl(%s)", "BIOCSETIF");
+
+ if (ioctl(bpf, BIOCSETIF, &ifr) == -1)
return (-1);
- }
- if (ioctl(bpf, BIOCGDLT, &dlt) == -1) {
- warn("ioctl(%s)", "BIOCGDLT");
+
+ if (ioctl(bpf, BIOCGDLT, &dlt) == -1)
return (-1);
- }
- if (dlt != DLT_EN10MB) {
- warnx("incompatible media");
+
+ if (dlt != DLT_EN10MB)
return (-1);
- }
+
return (0);
}
static int
+find_ether(char *dst, size_t len)
+{
+ struct ifaddrs *ifap, *ifa;
+ struct sockaddr_dl *sdl = NULL;
+ int nifs;
+
+ if (dst == NULL || len == 0)
+ return 0;
+
+ if (getifaddrs(&ifap) != 0)
+ return -1;
+
+ /* XXX also check the link state */
+ for (nifs = 0, ifa = ifap; ifa; ifa = ifa->ifa_next)
+ if (ifa->ifa_addr->sa_family == AF_LINK &&
+ ifa->ifa_flags & IFF_UP && ifa->ifa_flags & IFF_RUNNING) {
+ sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+ if (sdl->sdl_type == IFT_ETHER) {
+ strlcpy(dst, ifa->ifa_name, len);
+ nifs++;
+ }
+ }
+
+ freeifaddrs(ifap);
+ return nifs == 1 ? 0 : -1;
+}
+
+static int
get_ether(char const *text, struct ether_addr *addr)
{
struct ether_addr *paddr;
@@ -165,14 +183,31 @@ send_wakeup(int bpf, struct ether_addr const *addr)
int
main(int argc, char *argv[])
{
- int n;
+ int bpf, n;
+ char ifname[IF_NAMESIZE];
+
+ if (argc < 2)
+ usage();
+
+ if ((bpf = open(_PATH_BPF, O_RDWR)) == -1)
+ err(1, "Cannot open bpf interface");
+
+ n = 2;
+ if (bind_if_to_bpf(argv[1], bpf) == -1) {
+ if (find_ether(ifname, sizeof(ifname)))
+ err(1, "Failed to determine ethernet interface");
+ if (bind_if_to_bpf(ifname, bpf) == -1)
+ err(1, "Cannot bind to interface `%s'", ifname);
+ --n;
+ } else
+ strlcpy(ifname, argv[1], sizeof(ifname));
- if (argc < 3)
+ if (n >= argc)
usage();
+ for (; n < argc; n++)
+ if (wake(bpf, argv[n]))
+ warn("Cannot send Wake on LAN frame over `%s' to `%s'",
+ ifname, argv[n]);
- for (n = 2; n < argc; n++)
- if (wake(argv[1], argv[n]))
- warnx("error sending Wake on LAN frame over %s to %s",
- argv[1], argv[n]);
return (0);
}
diff --git a/usr.sbin/watchdogd/Makefile b/usr.sbin/watchdogd/Makefile
index 08880e1..be69d2b 100644
--- a/usr.sbin/watchdogd/Makefile
+++ b/usr.sbin/watchdogd/Makefile
@@ -3,7 +3,6 @@
PROG= watchdogd
LINKS= ${BINDIR}/watchdogd ${BINDIR}/watchdog
MAN= watchdogd.8 watchdog.8
-WARNS?= 6
LDADD= -lm -lutil
DPADD= ${LIBM} ${LIBUTIL}
diff --git a/usr.sbin/watchdogd/watchdogd.c b/usr.sbin/watchdogd/watchdogd.c
index 6f0e840..073affd71 100644
--- a/usr.sbin/watchdogd/watchdogd.c
+++ b/usr.sbin/watchdogd/watchdogd.c
@@ -95,7 +95,7 @@ main(int argc, char *argv[])
if (is_daemon) {
if (watchdog_onoff(1) == -1)
- exit(EX_SOFTWARE);
+ err(EX_OSERR, "patting the dog");
pfh = pidfile_open(pidfile, 0600, &otherpid);
if (pfh == NULL) {
@@ -149,7 +149,7 @@ sighandler(int signum)
* Open the watchdog device.
*/
static int
-watchdog_init()
+watchdog_init(void)
{
fd = open("/dev/" _PATH_WATCHDOG, O_RDWR);
@@ -220,7 +220,7 @@ watchdog_onoff(int onoff)
* Tell user how to use the program.
*/
static void
-usage()
+usage(void)
{
if (is_daemon)
fprintf(stderr, "usage: watchdogd [-d] [-e cmd] [-I file] [-s sleep] [-t timeout]\n");
diff --git a/usr.sbin/wlandebug/Makefile b/usr.sbin/wlandebug/Makefile
index 5284257..e916c23 100644
--- a/usr.sbin/wlandebug/Makefile
+++ b/usr.sbin/wlandebug/Makefile
@@ -3,4 +3,6 @@
PROG= wlandebug
MAN= wlandebug.8
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/wlconfig/Makefile b/usr.sbin/wlconfig/Makefile
index 8d3d0cc..8bc6262 100644
--- a/usr.sbin/wlconfig/Makefile
+++ b/usr.sbin/wlconfig/Makefile
@@ -4,4 +4,6 @@ PROG= wlconfig
MAN= wlconfig.8
MANSUBDIR= /i386
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/yp_mkdb/Makefile b/usr.sbin/yp_mkdb/Makefile
index 973da6e..1c41105 100644
--- a/usr.sbin/yp_mkdb/Makefile
+++ b/usr.sbin/yp_mkdb/Makefile
@@ -9,4 +9,6 @@ SRCS= yp_mkdb.c yp_dblookup.c yp_dbwrite.c
CFLAGS+= -Dyp_error=warnx
CFLAGS+= -I${.CURDIR}/../../libexec/ypxfr -I${.CURDIR}/../../usr.sbin/ypserv
+WARNS?= 1
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/ypbind/Makefile b/usr.sbin/ypbind/Makefile
index 915d001..8e9a231 100644
--- a/usr.sbin/ypbind/Makefile
+++ b/usr.sbin/ypbind/Makefile
@@ -7,4 +7,6 @@ SRCS= ypbind.c yp_ping.c
CFLAGS+= -DDAEMON
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/yppoll/Makefile b/usr.sbin/yppoll/Makefile
index 63763316..701633b 100644
--- a/usr.sbin/yppoll/Makefile
+++ b/usr.sbin/yppoll/Makefile
@@ -4,4 +4,6 @@
PROG= yppoll
MAN= yppoll.8
+WARNS?= 3
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/yppoll/yppoll.8 b/usr.sbin/yppoll/yppoll.8
index ad90d90..d466fd3 100644
--- a/usr.sbin/yppoll/yppoll.8
+++ b/usr.sbin/yppoll/yppoll.8
@@ -12,13 +12,6 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with 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 NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/usr.sbin/yppush/Makefile b/usr.sbin/yppush/Makefile
index 7ce1c61..887a80b 100644
--- a/usr.sbin/yppush/Makefile
+++ b/usr.sbin/yppush/Makefile
@@ -12,6 +12,8 @@ GENSRCS=yp.h yp_clnt.c yppush_svc.c
CFLAGS+= -I. -I${.CURDIR}/../../libexec/ypxfr
+WARNS?= 2
+
RPCGEN= rpcgen -C
CLEANFILES= ${GENSRCS}
diff --git a/usr.sbin/yppush/yppush_main.c b/usr.sbin/yppush/yppush_main.c
index ceb63bc..df1dbe4 100644
--- a/usr.sbin/yppush/yppush_main.c
+++ b/usr.sbin/yppush/yppush_main.c
@@ -487,7 +487,6 @@ main(int argc, char *argv[])
};
struct hostlist *yppush_hostlist = NULL;
struct hostlist *tmp;
- struct sigaction sa;
while ((ch = getopt(argc, argv, "d:j:p:h:t:v")) != -1) {
switch (ch) {
diff --git a/usr.sbin/ypserv/Makefile b/usr.sbin/ypserv/Makefile
index c1b2df3..73a6195 100644
--- a/usr.sbin/ypserv/Makefile
+++ b/usr.sbin/ypserv/Makefile
@@ -10,6 +10,8 @@ SRCS= yp_svc.c yp_server.c yp_dblookup.c yp_dnslookup.c \
CFLAGS+= -DDB_CACHE -DTCP_WRAPPER -I.
+WARNS?= 0
+
DPADD= ${LIBWRAP}
LDADD= -lwrap
diff --git a/usr.sbin/ypserv/yp_main.c b/usr.sbin/ypserv/yp_main.c
index 7ae15d9..ec39d1b 100644
--- a/usr.sbin/ypserv/yp_main.c
+++ b/usr.sbin/ypserv/yp_main.c
@@ -40,25 +40,30 @@ __FBSDID("$FreeBSD$");
* rpcgen.new, and later modified.
*/
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
#include "yp.h"
#include <err.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <signal.h>
+#include <stdarg.h>
#include <stdlib.h> /* getenv, exit */
#include <string.h> /* strcmp */
#include <syslog.h>
#include <unistd.h>
-#include <rpc/pmap_clnt.h> /* for pmap_unset */
#ifdef __cplusplus
#include <sysent.h> /* getdtablesize, open */
#endif /* __cplusplus */
-#include <sys/socket.h>
#include <netinet/in.h>
-#include <sys/wait.h>
+#include <netdb.h>
#include "yp_extern.h"
+#include <netconfig.h>
#include <rpc/rpc.h>
+#include <rpc/rpc_com.h>
#ifndef SIG_PF
#define SIG_PF void(*)(int)
@@ -68,14 +73,17 @@ __FBSDID("$FreeBSD$");
int _rpcpmstart; /* Started by a port monitor ? */
static int _rpcfdtype;
/* Whether Stream or Datagram ? */
+static int _rpcaf;
+static int _rpcfd;
+
/* States a server can be in wrt request */
#define _IDLE 0
#define _SERVED 1
#define _SERVING 2
-extern void ypprog_1(struct svc_req *, register SVCXPRT *);
-extern void ypprog_2(struct svc_req *, register SVCXPRT *);
+extern void ypprog_1(struct svc_req *, SVCXPRT *);
+extern void ypprog_2(struct svc_req *, SVCXPRT *);
extern int _rpc_dtablesize(void);
extern int _rpcsvcstate; /* Set when a request is serviced */
char *progname = "ypserv";
@@ -84,26 +92,37 @@ char *yp_dir = _PATH_YP;
int do_dns = 0;
int resfd;
-struct socktype {
- const char *st_name;
- int st_type;
+struct socklistent {
+ int sle_sock;
+ struct sockaddr_storage sle_ss;
+ SLIST_ENTRY(socklistent) sle_next;
};
-static struct socktype stlist[] = {
- { "tcp", SOCK_STREAM },
- { "udp", SOCK_DGRAM },
- { NULL, 0 }
+static SLIST_HEAD(, socklistent) sle_head =
+ SLIST_HEAD_INITIALIZER(sle_head);
+
+struct bindaddrlistent {
+ const char *ble_hostname;
+ SLIST_ENTRY(bindaddrlistent) ble_next;
};
+static SLIST_HEAD(, bindaddrlistent) ble_head =
+ SLIST_HEAD_INITIALIZER(ble_head);
+
+static char *servname = "0";
static
-void _msgout(char* msg)
+void _msgout(char* msg, ...)
{
+ va_list ap;
+
+ va_start(ap, msg);
if (debug) {
if (_rpcpmstart)
- syslog(LOG_ERR, "%s", msg);
+ vsyslog(LOG_ERR, msg, ap);
else
- warnx("%s", msg);
+ vwarnx(msg, ap);
} else
- syslog(LOG_ERR, "%s", msg);
+ vsyslog(LOG_ERR, msg, ap);
+ va_end(ap);
}
pid_t yp_pid;
@@ -162,8 +181,8 @@ yp_svc_run(void)
static void
unregister(void)
{
- (void) pmap_unset(YPPROG, YPVERS);
- (void) pmap_unset(YPPROG, YPOLDVERS);
+ (void)svc_unreg(YPPROG, YPVERS);
+ (void)svc_unreg(YPPROG, YPOLDVERS);
}
static void
@@ -231,24 +250,228 @@ closedown(int sig)
(void) alarm(_RPCSVC_CLOSEDOWN/2);
}
+static int
+create_service(const int sock, const struct netconfig *nconf,
+ const struct __rpc_sockinfo *si)
+{
+ int error;
+
+ SVCXPRT *transp;
+ struct addrinfo hints, *res, *res0;
+ struct socklistent *slep;
+ struct bindaddrlistent *blep;
+ struct netbuf svcaddr;
+
+ SLIST_INIT(&sle_head);
+ memset(&hints, 0, sizeof(hints));
+ memset(&svcaddr, 0, sizeof(svcaddr));
+
+ hints.ai_family = si->si_af;
+ hints.ai_socktype = si->si_socktype;
+ hints.ai_protocol = si->si_proto;
+
+ /*
+ * Build socketlist from bindaddrlist.
+ */
+ if (sock == RPC_ANYFD) {
+ SLIST_FOREACH(blep, &ble_head, ble_next) {
+ if (blep->ble_hostname == NULL)
+ hints.ai_flags = AI_PASSIVE;
+ else
+ hints.ai_flags = 0;
+ error = getaddrinfo(blep->ble_hostname, servname,
+ &hints, &res0);
+ if (error) {
+ _msgout("getaddrinfo(): %s",
+ gai_strerror(error));
+ return -1;
+ }
+ for (res = res0; res; res = res->ai_next) {
+ int s;
+
+ s = __rpc_nconf2fd(nconf);
+ if (s < 0) {
+ if (errno == EPROTONOSUPPORT)
+ _msgout("unsupported"
+ " transport: %s",
+ nconf->nc_netid);
+ else
+ _msgout("cannot create"
+ " %s socket: %s",
+ nconf->nc_netid,
+ strerror(errno));
+ freeaddrinfo(res0);
+ return -1;
+ }
+ if (bindresvport_sa(s, res->ai_addr) == -1) {
+ if ((errno != EPERM) ||
+ (bind(s, res->ai_addr,
+ res->ai_addrlen) == -1)) {
+ _msgout("cannot bind "
+ "%s socket: %s",
+ nconf->nc_netid,
+ strerror(errno));
+ freeaddrinfo(res0);
+ close(sock);
+ return -1;
+ }
+ }
+ if (nconf->nc_semantics != NC_TPI_CLTS)
+ listen(s, SOMAXCONN);
+
+ slep = malloc(sizeof(*slep));
+ if (slep == NULL) {
+ _msgout("malloc failed: %s",
+ strerror(errno));
+ freeaddrinfo(res0);
+ close(s);
+ return -1;
+ }
+ memset(slep, 0, sizeof(*slep));
+ memcpy(&slep->sle_ss,
+ (struct sockaddr *)(res->ai_addr),
+ sizeof(res->ai_addr));
+ slep->sle_sock = s;
+ SLIST_INSERT_HEAD(&sle_head, slep, sle_next);
+
+ /*
+ * If servname == "0", redefine it by using
+ * the bound socket.
+ */
+ if (strncmp("0", servname, 1) == 0) {
+ struct sockaddr *sap;
+ socklen_t slen;
+ char *sname;
+
+ sname = malloc(NI_MAXSERV);
+ if (sname == NULL) {
+ _msgout("malloc(): %s",
+ strerror(errno));
+ freeaddrinfo(res0);
+ close(s);
+ return -1;
+ }
+ memset(sname, 0, NI_MAXSERV);
+
+ sap = (struct sockaddr *)&slep->sle_ss;
+ slen = sizeof(*sap);
+ error = getsockname(s, sap, &slen);
+ if (error) {
+ _msgout("getsockname(): %s",
+ strerror(errno));
+ freeaddrinfo(res0);
+ close(s);
+ return -1;
+ }
+ error = getnameinfo(sap, slen,
+ NULL, 0,
+ sname, NI_MAXSERV,
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (error) {
+ _msgout("getnameinfo(): %s",
+ strerror(errno));
+ freeaddrinfo(res0);
+ close(s);
+ return -1;
+ }
+ servname = sname;
+ }
+ }
+ freeaddrinfo(res0);
+ }
+ } else {
+ slep = malloc(sizeof(*slep));
+ if (slep == NULL) {
+ _msgout("malloc failed: %s", strerror(errno));
+ return -1;
+ }
+ memset(slep, 0, sizeof(*slep));
+ slep->sle_sock = sock;
+ SLIST_INSERT_HEAD(&sle_head, slep, sle_next);
+ }
+
+ /*
+ * Traverse socketlist and create rpc service handles for each socket.
+ */
+ SLIST_FOREACH(slep, &sle_head, sle_next) {
+ if (nconf->nc_semantics == NC_TPI_CLTS)
+ transp = svc_dg_create(slep->sle_sock, 0, 0);
+ else
+ transp = svc_vc_create(slep->sle_sock, RPC_MAXDATASIZE,
+ RPC_MAXDATASIZE);
+ if (transp == NULL) {
+ _msgout("unable to create service: %s",
+ nconf->nc_netid);
+ continue;
+ }
+ if (!svc_reg(transp, YPPROG, YPOLDVERS, ypprog_1, NULL)) {
+ svc_destroy(transp);
+ close(slep->sle_sock);
+ _msgout("unable to register (YPPROG, YPOLDVERS, %s):"
+ " %s", nconf->nc_netid, strerror(errno));
+ continue;
+ }
+ if (!svc_reg(transp, YPPROG, YPVERS, ypprog_2, NULL)) {
+ svc_destroy(transp);
+ close(slep->sle_sock);
+ _msgout("unable to register (YPPROG, YPVERS, %s): %s",
+ nconf->nc_netid, strerror(errno));
+ continue;
+ }
+ }
+ while(!(SLIST_EMPTY(&sle_head)))
+ SLIST_REMOVE_HEAD(&sle_head, sle_next);
+
+ /*
+ * Register RPC service to rpcbind by using AI_PASSIVE address.
+ */
+ hints.ai_flags = AI_PASSIVE;
+ error = getaddrinfo(NULL, servname, &hints, &res0);
+ if (error) {
+ _msgout("getaddrinfo(): %s", gai_strerror(error));
+ return -1;
+ }
+ svcaddr.buf = res0->ai_addr;
+ svcaddr.len = res0->ai_addrlen;
+
+ if (si->si_af == AF_INET) {
+ /* XXX: ignore error intentionally */
+ rpcb_set(YPPROG, YPOLDVERS, nconf, &svcaddr);
+ }
+ /* XXX: ignore error intentionally */
+ rpcb_set(YPPROG, YPVERS, nconf, &svcaddr);
+
+ freeaddrinfo(res0);
+ return 0;
+}
+
int
main(int argc, char *argv[])
{
- register SVCXPRT *transp = NULL;
- int sock;
- int proto = 0;
- struct sockaddr_in saddr;
- socklen_t asize = sizeof (saddr);
int ch;
- in_port_t yp_port = 0;
- char *errstr;
- struct socktype *st;
-
- while ((ch = getopt(argc, argv, "hdnp:P:")) != -1) {
+ int error;
+ int ntrans;
+
+ void *nc_handle;
+ struct netconfig *nconf;
+ struct __rpc_sockinfo si;
+ struct bindaddrlistent *blep;
+
+ memset(&si, 0, sizeof(si));
+ SLIST_INIT(&ble_head);
+
+ while ((ch = getopt(argc, argv, "dh:np:P:")) != -1) {
switch (ch) {
case 'd':
debug = ypdb_debug = 1;
break;
+ case 'h':
+ blep = malloc(sizeof(*blep));
+ if (blep == NULL)
+ err(1, "malloc() failed: -h %s", optarg);
+ blep->ble_hostname = optarg;
+ SLIST_INSERT_HEAD(&ble_head, blep, ble_next);
+ break;
case 'n':
do_dns = 1;
break;
@@ -256,119 +479,82 @@ main(int argc, char *argv[])
yp_dir = optarg;
break;
case 'P':
- yp_port = (in_port_t)strtonum(optarg, 1, 65535,
- (const char **)&errstr);
- if (yp_port == 0 && errstr != NULL) {
- _msgout("invalid port number provided");
- exit(1);
- }
+ servname = optarg;
break;
- case 'h':
default:
usage();
}
}
+ /*
+ * Add "anyaddr" entry if no -h is specified.
+ */
+ if (SLIST_EMPTY(&ble_head)) {
+ blep = malloc(sizeof(*blep));
+ if (blep == NULL)
+ err(1, "malloc() failed");
+ memset(blep, 0, sizeof(*blep));
+ SLIST_INSERT_HEAD(&ble_head, blep, ble_next);
+ }
load_securenets();
yp_init_resolver();
#ifdef DB_CACHE
yp_init_dbs();
#endif
- 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;
+ nc_handle = setnetconfig();
+ if (nc_handle == NULL)
+ err(1, "cannot read %s", NETCONFIG);
+ if (__rpc_fd2sockinfo(0, &si) != 0) {
+ /* invoked from inetd */
_rpcpmstart = 1;
- proto = 0;
+ _rpcfdtype = si.si_socktype;
+ _rpcaf = si.si_af;
+ _rpcfd = 0;
openlog("ypserv", LOG_PID, LOG_DAEMON);
} else {
+ /* standalone mode */
if (!debug) {
if (daemon(0,0)) {
err(1,"cannot fork");
}
openlog("ypserv", LOG_PID, LOG_DAEMON);
}
- sock = RPC_ANYSOCK;
- (void) pmap_unset(YPPROG, YPVERS);
- (void) pmap_unset(YPPROG, 1);
+ _rpcpmstart = 0;
+ _rpcaf = AF_INET;
+ _rpcfd = RPC_ANYFD;
+ unregister();
}
/*
- * Initialize TCP/UDP sockets.
+ * Create RPC service for each transport.
*/
- memset((char *)&saddr, 0, sizeof(saddr));
- saddr.sin_family = AF_INET;
- saddr.sin_addr.s_addr = htonl(INADDR_ANY);
- saddr.sin_port = htons(yp_port);
- for (st = stlist; st->st_name != NULL; st++) {
- /* Do not bind the socket if the user didn't specify a port */
- if (yp_port == 0)
- break;
-
- sock = socket(AF_INET, st->st_type, 0);
- if (sock == -1) {
- if ((asprintf(&errstr, "cannot create a %s socket",
- st->st_name)) == -1)
- err(1, "unexpected failure in asprintf()");
- _msgout(errstr);
- free((void *)errstr);
- exit(1);
- }
- if (bind(sock, (struct sockaddr *) &saddr, sizeof(saddr))
- == -1) {
- if ((asprintf(&errstr, "cannot bind %s socket",
- st->st_name)) == -1)
- err(1, "unexpected failure in asprintf()");
- _msgout(errstr);
- free((void *)errstr);
- exit(1);
- }
- errstr = NULL;
- }
-
- if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) {
- transp = svcudp_create(sock);
- if (transp == NULL) {
- _msgout("cannot create udp service");
- exit(1);
- }
- if (!_rpcpmstart)
- proto = IPPROTO_UDP;
- 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)) {
- transp = svctcp_create(sock, 0, 0);
- if (transp == NULL) {
- _msgout("cannot create tcp service");
- exit(1);
- }
- if (!_rpcpmstart)
- proto = IPPROTO_TCP;
- 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);
+ ntrans = 0;
+ while((nconf = getnetconfig(nc_handle))) {
+ if ((nconf->nc_flag & NC_VISIBLE)) {
+ if (__rpc_nconf2sockinfo(nconf, &si) == 0) {
+ _msgout("cannot get information for %s. "
+ "Ignored.", nconf->nc_netid);
+ continue;
+ }
+ if (_rpcpmstart) {
+ if (si.si_socktype != _rpcfdtype ||
+ si.si_af != _rpcaf)
+ continue;
+ } else if (si.si_af != _rpcaf)
+ continue;
+ error = create_service(_rpcfd, nconf, &si);
+ if (error) {
+ endnetconfig(nc_handle);
+ exit(1);
+ }
+ ntrans++;
}
}
-
- if (transp == (SVCXPRT *)NULL) {
- _msgout("could not create a handle");
+ endnetconfig(nc_handle);
+ while(!(SLIST_EMPTY(&ble_head)))
+ SLIST_REMOVE_HEAD(&ble_head, ble_next);
+ if (ntrans == 0) {
+ _msgout("no transport is available. Aborted.");
exit(1);
}
if (_rpcpmstart) {
diff --git a/usr.sbin/ypserv/yp_server.c b/usr.sbin/ypserv/yp_server.c
index 86c7d00..ba20c3cd 100644
--- a/usr.sbin/ypserv/yp_server.c
+++ b/usr.sbin/ypserv/yp_server.c
@@ -563,7 +563,10 @@ ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
* Proper fix for PR #10970: exit here so that we don't risk
* having a child spawned from this sub-process.
*/
- _exit(0);
+ if (!debug)
+ _exit(0);
+
+ return &result;
}
ypresp_master *
diff --git a/usr.sbin/ypserv/ypinit.sh b/usr.sbin/ypserv/ypinit.sh
index 1be7e0e..374308e 100644
--- a/usr.sbin/ypserv/ypinit.sh
+++ b/usr.sbin/ypserv/ypinit.sh
@@ -298,7 +298,7 @@ do
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 "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}"
diff --git a/usr.sbin/ypserv/ypserv.8 b/usr.sbin/ypserv/ypserv.8
index c8746fd..9d88731 100644
--- a/usr.sbin/ypserv/ypserv.8
+++ b/usr.sbin/ypserv/ypserv.8
@@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 25, 2009
+.Dd December 13, 2009
.Dt YPSERV 8
.Os
.Sh NAME
@@ -408,6 +408,15 @@ in subprocesses, allowing the parent server process to go on handling
other requests.)
This makes it easier to trace the server with
a debugging tool.
+.It Fl h Ar addr
+Specify a specific address to bind to for requests. This option may be
+specified multiple times. If no
+.Fl h
+option is specified,
+.Nm
+will bind to default passive address
+.Pq e.g. INADDR_ANY for IPv4
+for each transport.
.It Fl P Ar port
Force ypserv to bind to a specific TCP/UDP port, rather than selecting
its own.
diff --git a/usr.sbin/ypset/Makefile b/usr.sbin/ypset/Makefile
index 10ed5f8..708ff87 100644
--- a/usr.sbin/ypset/Makefile
+++ b/usr.sbin/ypset/Makefile
@@ -4,4 +4,6 @@
PROG= ypset
MAN= ypset.8
+WARNS?= 2
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/zic/Theory b/usr.sbin/zic/Theory
deleted file mode 100644
index 8e93365..0000000
--- a/usr.sbin/zic/Theory
+++ /dev/null
@@ -1,570 +0,0 @@
-@(#)Theory 8.3
-This file is in the public domain, so clarified as of
-2009-05-17 by Arthur David Olson.
-$FreeBSD$
-
------ Outline -----
-
- Time and date functions
- Names of time zone regions
- Time zone abbreviations
- Calendrical issues
- Time and time zones on Mars
-
------ Time and date functions -----
-
-These time and date functions are upwards compatible with POSIX,
-an international standard for UNIX-like systems.
-As of this writing, the current edition of POSIX is:
-
- Standard for Information technology
- -- Portable Operating System Interface (POSIX (R))
- -- System Interfaces
- IEEE Std 1003.1, 2004 Edition
- <http://www.opengroup.org/online-pubs?DOC=7999959899>
- <http://www.opengroup.org/pubs/catalog/t041.htm>
-
-POSIX has the following properties and limitations.
-
-* In POSIX, time display in a process is controlled by the
- environment variable TZ. Unfortunately, the POSIX TZ string takes
- a form that is hard to describe and is error-prone in practice.
- Also, POSIX TZ strings can't deal with other (for example, Israeli)
- daylight saving time rules, or situations where more than two
- time zone abbreviations are used in an area.
-
- The POSIX TZ string takes the following form:
-
- stdoffset[dst[offset],date[/time],date[/time]]
-
- where:
-
- std and dst
- are 3 or more characters specifying the standard
- and daylight saving time (DST) zone names.
- Starting with POSIX.1-2001, std and dst may also be
- in a quoted form like "<UTC+10>"; this allows
- "+" and "-" in the names.
- offset
- is of the form `[-]hh:[mm[:ss]]' and specifies the
- offset west of UTC. The default DST offset is one hour
- ahead of standard time.
- date[/time],date[/time]
- specifies the beginning and end of DST. If this is absent,
- the system supplies its own rules for DST, and these can
- differ from year to year; typically US DST rules are used.
- time
- takes the form `hh:[mm[:ss]]' and defaults to 02:00.
- date
- takes one of the following forms:
- Jn (1<=n<=365)
- origin-1 day number not counting February 29
- n (0<=n<=365)
- origin-0 day number counting February 29 if present
- Mm.n.d (0[Sunday]<=d<=6[Saturday], 1<=n<=5, 1<=m<=12)
- for the dth day of week n of month m of the year,
- where week 1 is the first week in which day d appears,
- and `5' stands for the last week in which day d appears
- (which may be either the 4th or 5th week).
-
- Here is an example POSIX TZ string, for US Pacific time using rules
- appropriate from 1987 through 2006:
-
- TZ='PST8PDT,M4.1.0/02:00,M10.5.0/02:00'
-
- This POSIX TZ string is hard to remember, and mishandles time stamps
- before 1987 and after 2006. With this package you can use this
- instead:
-
- TZ='America/Los_Angeles'
-
-* POSIX does not define the exact meaning of TZ values like "EST5EDT".
- Typically the current US DST rules are used to interpret such values,
- but this means that the US DST rules are compiled into each program
- that does time conversion. This means that when US time conversion
- rules change (as in the United States in 1987), all programs that
- do time conversion must be recompiled to ensure proper results.
-
-* In POSIX, there's no tamper-proof way for a process to learn the
- system's best idea of local wall clock. (This is important for
- applications that an administrator wants used only at certain times--
- without regard to whether the user has fiddled the "TZ" environment
- variable. While an administrator can "do everything in UTC" to get
- around the problem, doing so is inconvenient and precludes handling
- daylight saving time shifts--as might be required to limit phone
- calls to off-peak hours.)
-
-* POSIX requires that systems ignore leap seconds.
-
-These are the extensions that have been made to the POSIX functions:
-
-* The "TZ" environment variable is used in generating the name of a file
- from which time zone information is read (or is interpreted a la
- POSIX); "TZ" is no longer constrained to be a three-letter time zone
- name followed by a number of hours and an optional three-letter
- daylight time zone name. The daylight saving time rules to be used
- for a particular time zone are encoded in the time zone file;
- the format of the file allows U.S., Australian, and other rules to be
- encoded, and allows for situations where more than two time zone
- abbreviations are used.
-
- It was recognized that allowing the "TZ" environment variable to
- take on values such as "America/New_York" might cause "old" programs
- (that expect "TZ" to have a certain form) to operate incorrectly;
- consideration was given to using some other environment variable
- (for example, "TIMEZONE") to hold the string used to generate the
- time zone information file name. In the end, however, it was decided
- to continue using "TZ": it is widely used for time zone purposes;
- separately maintaining both "TZ" and "TIMEZONE" seemed a nuisance;
- and systems where "new" forms of "TZ" might cause problems can simply
- use TZ values such as "EST5EDT" which can be used both by
- "new" programs (a la POSIX) and "old" programs (as zone names and
- offsets).
-
-* To handle places where more than two time zone abbreviations are used,
- the functions "localtime" and "gmtime" set tzname[tmp->tm_isdst]
- (where "tmp" is the value the function returns) to the time zone
- abbreviation to be used. This differs from POSIX, where the elements
- of tzname are only changed as a result of calls to tzset.
-
-* Since the "TZ" environment variable can now be used to control time
- conversion, the "daylight" and "timezone" variables are no longer
- needed. (These variables are defined and set by "tzset"; however, their
- values will not be used by "localtime.")
-
-* The "localtime" function has been set up to deliver correct results
- for near-minimum or near-maximum time_t values. (A comment in the
- source code tells how to get compatibly wrong results).
-
-* A function "tzsetwall" has been added to arrange for the system's
- best approximation to local wall clock time to be delivered by
- subsequent calls to "localtime." Source code for portable
- applications that "must" run on local wall clock time should call
- "tzsetwall();" if such code is moved to "old" systems that don't
- provide tzsetwall, you won't be able to generate an executable program.
- (These time zone functions also arrange for local wall clock time to be
- used if tzset is called--directly or indirectly--and there's no "TZ"
- environment variable; portable applications should not, however, rely
- on this behavior since it's not the way SVR2 systems behave.)
-
-* These functions can account for leap seconds, thanks to Bradley White.
-
-Points of interest to folks with other systems:
-
-* This package is already part of many POSIX-compliant hosts,
- including BSD, HP, Linux, Network Appliance, SCO, SGI, and Sun.
- On such hosts, the primary use of this package
- is to update obsolete time zone rule tables.
- To do this, you may need to compile the time zone compiler
- `zic' supplied with this package instead of using the system `zic',
- since the format of zic's input changed slightly in late 1994,
- and many vendors still do not support the new input format.
-
-* The UNIX Version 7 "timezone" function is not present in this package;
- it's impossible to reliably map timezone's arguments (a "minutes west
- of GMT" value and a "daylight saving time in effect" flag) to a
- time zone abbreviation, and we refuse to guess.
- Programs that in the past used the timezone function may now examine
- tzname[localtime(&clock)->tm_isdst] to learn the correct time
- zone abbreviation to use. Alternatively, use
- localtime(&clock)->tm_zone if this has been enabled.
-
-* The 4.2BSD gettimeofday function is not used in this package.
- This formerly let users obtain the current UTC offset and DST flag,
- but this functionality was removed in later versions of BSD.
-
-* In SVR2, time conversion fails for near-minimum or near-maximum
- time_t values when doing conversions for places that don't use UTC.
- This package takes care to do these conversions correctly.
-
-The functions that are conditionally compiled if STD_INSPIRED is defined
-should, at this point, be looked on primarily as food for thought. They are
-not in any sense "standard compatible"--some are not, in fact, specified in
-*any* standard. They do, however, represent responses of various authors to
-standardization proposals.
-
-Other time conversion proposals, in particular the one developed by folks at
-Hewlett Packard, offer a wider selection of functions that provide capabilities
-beyond those provided here. The absence of such functions from this package
-is not meant to discourage the development, standardization, or use of such
-functions. Rather, their absence reflects the decision to make this package
-contain valid extensions to POSIX, to ensure its broad acceptability. If
-more powerful time conversion functions can be standardized, so much the
-better.
-
-
------ Names of time zone rule files -----
-
-The time zone rule file naming conventions attempt to strike a balance
-among the following goals:
-
- * Uniquely identify every national region where clocks have all
- agreed since 1970. This is essential for the intended use: static
- clocks keeping local civil time.
-
- * Indicate to humans as to where that region is. This simplifes use.
-
- * Be robust in the presence of political changes. This reduces the
- number of updates and backward-compatibility hacks. For example,
- names of countries are ordinarily not used, to avoid
- incompatibilities when countries change their name
- (e.g. Zaire->Congo) or when locations change countries
- (e.g. Hong Kong from UK colony to China).
-
- * Be portable to a wide variety of implementations.
- This promotes use of the technology.
-
- * Use a consistent naming convention over the entire world.
- This simplifies both use and maintenance.
-
-This naming convention is not intended for use by inexperienced users
-to select TZ values by themselves (though they can of course examine
-and reuse existing settings). Distributors should provide
-documentation and/or a simple selection interface that explains the
-names; see the 'tzselect' program supplied with this distribution for
-one example.
-
-Names normally have the form AREA/LOCATION, where AREA is the name
-of a continent or ocean, and LOCATION is the name of a specific
-location within that region. North and South America share the same
-area, `America'. Typical names are `Africa/Cairo', `America/New_York',
-and `Pacific/Honolulu'.
-
-Here are the general rules used for choosing location names,
-in decreasing order of importance:
-
- Use only valid POSIX file name components (i.e., the parts of
- names other than `/'). Within a file name component,
- use only ASCII letters, `.', `-' and `_'. Do not use
- digits, as that might create an ambiguity with POSIX
- TZ strings. A file name component must not exceed 14
- characters or start with `-'. E.g., prefer `Brunei'
- to `Bandar_Seri_Begawan'.
- Include at least one location per time zone rule set per country.
- One such location is enough. Use ISO 3166 (see the file
- iso3166.tab) to help decide whether something is a country.
- However, uninhabited ISO 3166 regions like Bouvet Island
- do not need locations, since local time is not defined there.
- If all the clocks in a country's region have agreed since 1970,
- don't bother to include more than one location
- even if subregions' clocks disagreed before 1970.
- Otherwise these tables would become annoyingly large.
- If a name is ambiguous, use a less ambiguous alternative;
- e.g. many cities are named San Jose and Georgetown, so
- prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'.
- Keep locations compact. Use cities or small islands, not countries
- or regions, so that any future time zone changes do not split
- locations into different time zones. E.g. prefer `Paris'
- to `France', since France has had multiple time zones.
- Use mainstream English spelling, e.g. prefer `Rome' to `Roma', and
- prefer `Athens' to the true name (which uses Greek letters).
- The POSIX file name restrictions encourage this rule.
- Use the most populous among locations in a country's time zone,
- e.g. prefer `Shanghai' to `Beijing'. Among locations with
- similar populations, pick the best-known location,
- e.g. prefer `Rome' to `Milan'.
- Use the singular form, e.g. prefer `Canary' to `Canaries'.
- Omit common suffixes like `_Islands' and `_City', unless that
- would lead to ambiguity. E.g. prefer `Cayman' to
- `Cayman_Islands' and `Guatemala' to `Guatemala_City',
- but prefer `Mexico_City' to `Mexico' because the country
- of Mexico has several time zones.
- Use `_' to represent a space.
- Omit `.' from abbreviations in names, e.g. prefer `St_Helena'
- to `St._Helena'.
- Do not change established names if they only marginally
- violate the above rules. For example, don't change
- the existing name `Rome' to `Milan' merely because
- Milan's population has grown to be somewhat greater
- than Rome's.
- If a name is changed, put its old spelling in the `backward' file.
-
-The file `zone.tab' lists the geographical locations used to name
-time zone rule files. It is intended to be an exhaustive list
-of canonical names for geographic regions.
-
-Older versions of this package used a different naming scheme,
-and these older names are still supported.
-See the file `backward' for most of these older names
-(e.g. `US/Eastern' instead of `America/New_York').
-The other old-fashioned names still supported are
-`WET', `CET', `MET', `EET' (see the file `europe'),
-and `Factory' (see the file `factory').
-
-
------ Time zone abbreviations -----
-
-When this package is installed, it generates time zone abbreviations
-like `EST' to be compatible with human tradition and POSIX.
-Here are the general rules used for choosing time zone abbreviations,
-in decreasing order of importance:
-
- Use abbreviations that consist of three or more ASCII letters.
- Previous editions of this database also used characters like
- ' ' and '?', but these characters have a special meaning to
- the shell and cause commands like
- set `date`
- to have unexpected effects.
- Previous editions of this rule required upper-case letters,
- but the Congressman who introduced Chamorro Standard Time
- preferred "ChST", so the rule has been relaxed.
-
- This rule guarantees that all abbreviations could have
- been specified by a POSIX TZ string. POSIX
- requires at least three characters for an
- abbreviation. POSIX through 2000 says that an abbreviation
- cannot start with ':', and cannot contain ',', '-',
- '+', NUL, or a digit. POSIX from 2001 on changes this
- rule to say that an abbreviation can contain only '-', '+',
- and alphanumeric characters from the portable character set
- in the current locale. To be portable to both sets of
- rules, an abbreviation must therefore use only ASCII
- letters.
-
- Use abbreviations that are in common use among English-speakers,
- e.g. `EST' for Eastern Standard Time in North America.
- We assume that applications translate them to other languages
- as part of the normal localization process; for example,
- a French application might translate `EST' to `HNE'.
-
- For zones whose times are taken from a city's longitude, use the
- traditional xMT notation, e.g. `PMT' for Paris Mean Time.
- The only name like this in current use is `GMT'.
-
- If there is no common English abbreviation, abbreviate the English
- translation of the usual phrase used by native speakers.
- If this is not available or is a phrase mentioning the country
- (e.g. ``Cape Verde Time''), then:
-
- When a country has a single or principal time zone region,
- append `T' to the country's ISO code, e.g. `CVT' for
- Cape Verde Time. For summer time append `ST';
- for double summer time append `DST'; etc.
- When a country has multiple time zones, take the first three
- letters of an English place name identifying each zone
- and then append `T', `ST', etc. as before;
- e.g. `VLAST' for VLAdivostok Summer Time.
-
- Use UTC (with time zone abbreviation "zzz") for locations while
- uninhabited. The "zzz" mnemonic is that these locations are,
- in some sense, asleep.
-
-Application writers should note that these abbreviations are ambiguous
-in practice: e.g. `EST' has a different meaning in Australia than
-it does in the United States. In new applications, it's often better
-to use numeric UTC offsets like `-0500' instead of time zone
-abbreviations like `EST'; this avoids the ambiguity.
-
-
------ Calendrical issues -----
-
-Calendrical issues are a bit out of scope for a time zone database,
-but they indicate the sort of problems that we would run into if we
-extended the time zone database further into the past. An excellent
-resource in this area is Edward M. Reingold and Nachum Dershowitz,
-<a href="http://emr.cs.uiuc.edu/home/reingold/calendar-book/second-edition/">
-Calendrical Calculations: The Millennium Edition
-</a>, Cambridge University Press (2001). Other information and
-sources are given below. They sometimes disagree.
-
-
-France
-
-Gregorian calendar adopted 1582-12-20.
-French Revolutionary calendar used 1793-11-24 through 1805-12-31,
-and (in Paris only) 1871-05-06 through 1871-05-23.
-
-
-Russia
-
-From Chris Carrier (1996-12-02):
-On 1929-10-01 the Soviet Union instituted an ``Eternal Calendar''
-with 30-day months plus 5 holidays, with a 5-day week.
-On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the
-Gregorian calendar while retaining the 6-day week; on 1940-06-27 it
-reverted to the 7-day week. With the 6-day week the usual days
-off were the 6th, 12th, 18th, 24th and 30th of the month.
-(Source: Evitiar Zerubavel, _The Seven Day Circle_)
-
-
-Mark Brader reported a similar story in "The Book of Calendars", edited
-by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But:
-
-From: Petteri Sulonen (via Usenet)
-Date: 14 Jan 1999 00:00:00 GMT
-...
-
-If your source is correct, how come documents between 1929 -- 1940 were
-still dated using the conventional, Gregorian calendar?
-
-I can post a scan of a document dated December 1, 1934, signed by
-Yenukidze, the secretary, on behalf of Kalinin, the President of the
-Executive Committee of the Supreme Soviet, if you like.
-
-
-
-Sweden (and Finland)
-
-From: Mark Brader
-<a href="news:1996Jul6.012937.29190@sq.com">
-Subject: Re: Gregorian reform -- a part of locale?
-</a>
-Date: 1996-07-06
-
-In 1700, Denmark made the transition from Julian to Gregorian. Sweden
-decided to *start* a transition in 1700 as well, but rather than have one of
-those unsightly calendar gaps :-), they simply decreed that the next leap
-year after 1696 would be in 1744 -- putting the whole country on a calendar
-different from both Julian and Gregorian for a period of 40 years.
-
-However, in 1704 something went wrong and the plan was not carried through;
-they did, after all, have a leap year that year. And one in 1708. In 1712
-they gave it up and went back to Julian, putting 30 days in February that
-year!...
-
-Then in 1753, Sweden made the transition to Gregorian in the usual manner,
-getting there only 13 years behind the original schedule.
-
-(A previous posting of this story was challenged, and Swedish readers
-produced the following references to support it: "Tiderakning och historia"
-by Natanael Beckman (1924) and "Tid, en bok om tiderakning och
-kalendervasen" by Lars-Olof Lode'n (no date was given).)
-
-
-Grotefend's data
-
-From: "Michael Palmer" [with one obvious typo fixed]
-Subject: Re: Gregorian Calendar (was Re: Another FHC related question
-Newsgroups: soc.genealogy.german
-Date: Tue, 9 Feb 1999 02:32:48 -800
-...
-
-The following is a(n incomplete) listing, arranged chronologically, of
-European states, with the date they converted from the Julian to the
-Gregorian calendar:
-
-04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman
- Catholics and Danzig only)
-09/20 Dec 1582 - France, Lorraine
-
-21 Dec 1582/
- 01 Jan 1583 - Holland, Brabant, Flanders, Hennegau
-10/21 Feb 1583 - bishopric of Liege (L"uttich)
-13/24 Feb 1583 - bishopric of Augsburg
-04/15 Oct 1583 - electorate of Trier
-05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg,
- Salzburg, Brixen
-13/24 Oct 1583 - Austrian Oberelsass and Breisgau
-20/31 Oct 1583 - bishopric of Basel
-02/13 Nov 1583 - duchy of J"ulich-Berg
-02/13 Nov 1583 - electorate and city of K"oln
-04/15 Nov 1583 - bishopric of W"urzburg
-11/22 Nov 1583 - electorate of Mainz
-16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden
-17/28 Nov 1583 - bishopric of M"unster and duchy of Cleve
-14/25 Dec 1583 - Steiermark
-
-06/17 Jan 1584 - Austria and Bohemia
-11/22 Jan 1584 - Luzern, Uri, Schwyz, Zug, Freiburg, Solothurn
-12/23 Jan 1584 - Silesia and the Lausitz
-22 Jan/
- 02 Feb 1584 - Hungary (legally on 21 Oct 1587)
- Jun 1584 - Unterwalden
-01/12 Jul 1584 - duchy of Westfalen
-
-16/27 Jun 1585 - bishopric of Paderborn
-
-14/25 Dec 1590 - Transylvania
-
-22 Aug/
- 02 Sep 1612 - duchy of Prussia
-
-13/24 Dec 1614 - Pfalz-Neuburg
-
- 1617 - duchy of Kurland (reverted to the Julian calendar in
- 1796)
-
- 1624 - bishopric of Osnabr"uck
-
- 1630 - bishopric of Minden
-
-15/26 Mar 1631 - bishopric of Hildesheim
-
- 1655 - Kanton Wallis
-
-05/16 Feb 1682 - city of Strassburg
-
-18 Feb/
- 01 Mar 1700 - Protestant Germany (including Swedish possessions in
- Germany), Denmark, Norway
-30 Jun/
- 12 Jul 1700 - Gelderland, Zutphen
-10 Nov/
- 12 Dec 1700 - Utrecht, Overijssel
-
-31 Dec 1700/
- 12 Jan 1701 - Friesland, Groningen, Z"urich, Bern, Basel, Geneva,
- Turgau, and Schaffhausen
-
- 1724 - Glarus, Appenzell, and the city of St. Gallen
-
-01 Jan 1750 - Pisa and Florence
-
-02/14 Sep 1752 - Great Britain
-
-17 Feb/
- 01 Mar 1753 - Sweden
-
-1760-1812 - Graub"unden
-
-The Russian empire (including Finland and the Baltic states) did not
-convert to the Gregorian calendar until the Soviet revolution of 1917.
-
-Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen
-Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend
-(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28.
-
-
------ Time and time zones on Mars -----
-
-Some people have adjusted their work schedules to fit Mars time.
-Dozens of special Mars watches were built for Jet Propulsion
-Laboratory workers who kept Mars time during the Mars Exploration
-Rovers mission (2004). These timepieces look like normal Seikos and
-Citizens but use Mars seconds rather than terrestrial seconds.
-
-A Mars solar day is called a "sol" and has a mean period equal to
-about 24 hours 39 minutes 35.244 seconds in terrestrial time. It is
-divided into a conventional 24-hour clock, so each Mars second equals
-about 1.02749125 terrestrial seconds.
-
-The prime meridian of Mars goes through the center of the crater
-Airy-0, named in honor of the British astronomer who built the
-Greenwich telescope that defines Earth's prime meridian. Mean solar
-time on the Mars prime meridian is called Mars Coordinated Time (MTC).
-
-Each landed mission on Mars has adopted a different reference for
-solar time keeping, so there is no real standard for Mars time zones.
-For example, the Mars Exploration Rover project (2004) defined two
-time zones "Local Solar Time A" and "Local Solar Time B" for its two
-missions, each zone designed so that its time equals local true solar
-time at approximately the middle of the nominal mission. Such a "time
-zone" is not particularly suited for any application other than the
-mission itself.
-
-Many calendars have been proposed for Mars, but none have achieved
-wide acceptance. Astronomers often use Mars Sol Date (MSD) which is a
-sequential count of Mars solar days elapsed since about 1873-12-29
-12:00 GMT.
-
-The tz database does not currently support Mars time, but it is
-documented here in the hopes that support will be added eventually.
-
-Sources:
-
-Michael Allison and Robert Schmunk,
-"Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock"
-<http://www.giss.nasa.gov/tools/mars24/help/notes.html> (2004-07-30).
-
-Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times
-(2004-01-14), pp A1, A20-A21.
diff --git a/usr.sbin/zic/ialloc.c b/usr.sbin/zic/ialloc.c
deleted file mode 100644
index 1694c29..0000000
--- a/usr.sbin/zic/ialloc.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-** This file is in the public domain, so clarified as of
-** 2006-07-17 by Arthur David Olson.
-*/
-
-#ifndef lint
-#ifndef NOID
-static const char elsieid[] = "@(#)ialloc.c 8.30";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-/*LINTLIBRARY*/
-
-#include "private.h"
-
-#define nonzero(n) (((n) == 0) ? 1 : (n))
-
-char *
-imalloc(n)
-const int n;
-{
- return malloc((size_t) nonzero(n));
-}
-
-char *
-icalloc(nelem, elsize)
-int nelem;
-int elsize;
-{
- if (nelem == 0 || elsize == 0)
- nelem = elsize = 1;
- return calloc((size_t) nelem, (size_t) elsize);
-}
-
-void *
-irealloc(pointer, size)
-void * const pointer;
-const int size;
-{
- if (pointer == NULL)
- return imalloc(size);
- return realloc((void *) pointer, (size_t) nonzero(size));
-}
-
-char *
-icatalloc(old, new)
-char * const old;
-const char * const new;
-{
- register char * result;
- register int oldsize, newsize;
-
- newsize = (new == NULL) ? 0 : strlen(new);
- if (old == NULL)
- oldsize = 0;
- else if (newsize == 0)
- return old;
- else oldsize = strlen(old);
- if ((result = irealloc(old, oldsize + newsize + 1)) != NULL)
- if (new != NULL)
- (void) strcpy(result + oldsize, new);
- return result;
-}
-
-char *
-icpyalloc(string)
-const char * const string;
-{
- return icatalloc((char *) NULL, string);
-}
-
-void
-ifree(p)
-char * const p;
-{
- if (p != NULL)
- (void) free(p);
-}
-
-void
-icfree(p)
-char * const p;
-{
- if (p != NULL)
- (void) free(p);
-}
diff --git a/usr.sbin/zic/private.h b/usr.sbin/zic/private.h
deleted file mode 100644
index ecbf612..0000000
--- a/usr.sbin/zic/private.h
+++ /dev/null
@@ -1,272 +0,0 @@
-#ifndef PRIVATE_H
-
-#define PRIVATE_H
-
-/*
-** This file is in the public domain, so clarified as of
-** 1996-06-05 by Arthur David Olson.
-*/
-
-/*
- * FreeBSD modifications: separate libc's privates from zic's.
- * This makes it easier when we need to update one but not the other.
- * I have removed all of the ifdef spaghetti which is not relevant to
- * zic from this file.
- *
- * $FreeBSD$
- */
-
-/*
-** This header is for use ONLY with the time conversion code.
-** There is no guarantee that it will remain unchanged,
-** or that it will remain at all.
-** Do NOT copy it to any system include directory.
-** Thank you!
-*/
-
-/*
-** ID
-*/
-
-#ifndef lint
-#ifndef NOID
-static const char privatehid[] = "@(#)private.h 8.6";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-#define GRANDPARENTED "Local time zone must be set--see zic manual page"
-
-/*
-** Defaults for preprocessor symbols.
-** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
-*/
-
-#ifndef HAVE_GETTEXT
-#define HAVE_GETTEXT 0
-#endif /* !defined HAVE_GETTEXT */
-
-#ifndef HAVE_SYMLINK
-#define HAVE_SYMLINK 1
-#endif /* !defined HAVE_SYMLINK */
-
-#ifndef HAVE_SYS_STAT_H
-#define HAVE_SYS_STAT_H 1
-#endif /* !defined HAVE_SYS_STAT_H */
-
-#ifndef HAVE_SYS_WAIT_H
-#define HAVE_SYS_WAIT_H 1
-#endif /* !defined HAVE_SYS_WAIT_H */
-
-#ifndef HAVE_UNISTD_H
-#define HAVE_UNISTD_H 1
-#endif /* !defined HAVE_UNISTD_H */
-
-/*
-** Nested includes
-*/
-
-#include "sys/types.h" /* for time_t */
-#include "stdio.h"
-#include "errno.h"
-#include "string.h"
-#include "limits.h" /* for CHAR_BIT et al. */
-#include "time.h"
-#include "stdlib.h"
-
-#if HAVE_GETTEXT
-#include "libintl.h"
-#endif /* HAVE_GETTEXT */
-
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
-#endif /* HAVE_SYS_WAIT_H */
-
-#if HAVE_UNISTD_H
-#include "unistd.h" /* for F_OK and R_OK, and other POSIX goodness */
-#endif /* HAVE_UNISTD_H */
-
-#ifndef F_OK
-#define F_OK 0
-#endif /* !defined F_OK */
-#ifndef R_OK
-#define R_OK 4
-#endif /* !defined R_OK */
-
-/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
-#define is_digit(c) ((unsigned)(c) - '0' <= 9)
-
-/*
-** Define HAVE_STDINT_H's default value here, rather than at the
-** start, since __GLIBC__'s value depends on previously-included
-** files.
-** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
-*/
-#ifndef HAVE_STDINT_H
-#define HAVE_STDINT_H \
- (199901 <= __STDC_VERSION__ || \
- 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
-#endif /* !defined HAVE_STDINT_H */
-
-#if HAVE_STDINT_H
-#include "stdint.h"
-#endif /* !HAVE_STDINT_H */
-
-#ifndef INT_FAST64_MAX
-/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
-#if defined LLONG_MAX || defined __LONG_LONG_MAX__
-typedef long long int_fast64_t;
-#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#if (LONG_MAX >> 31) < 0xffffffff
-Please use a compiler that supports a 64-bit integer type (or wider);
-you may need to compile with "-DHAVE_STDINT_H".
-#endif /* (LONG_MAX >> 31) < 0xffffffff */
-typedef long int_fast64_t;
-#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#endif /* !defined INT_FAST64_MAX */
-
-#ifndef INT32_MAX
-#define INT32_MAX 0x7fffffff
-#endif /* !defined INT32_MAX */
-#ifndef INT32_MIN
-#define INT32_MIN (-1 - INT32_MAX)
-#endif /* !defined INT32_MIN */
-
-/*
-** Workarounds for compilers/systems.
- */
-
-/*
-** Some time.h implementations don't declare asctime_r.
-** Others might define it as a macro.
-** Fix the former without affecting the latter.
- */
-#ifndef asctime_r
-extern char * asctime_r(struct tm const *, char *);
-#endif
-
-
-
-/*
-** Private function declarations.
-*/
-char * icalloc (int nelem, int elsize);
-char * icatalloc (char * old, const char * new);
-char * icpyalloc (const char * string);
-char * imalloc (int n);
-void * irealloc (void * pointer, int size);
-void icfree (char * pointer);
-void ifree (char * pointer);
-const char * scheck (const char *string, const char *format);
-
-/*
-** Finally, some convenience items.
-*/
-
-#ifndef TRUE
-#define TRUE 1
-#endif /* !defined TRUE */
-
-#ifndef FALSE
-#define FALSE 0
-#endif /* !defined FALSE */
-
-#ifndef TYPE_BIT
-#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
-#endif /* !defined TYPE_BIT */
-
-#ifndef TYPE_SIGNED
-#define TYPE_SIGNED(type) (((type) -1) < 0)
-#endif /* !defined TYPE_SIGNED */
-
-/*
-** Since the definition of TYPE_INTEGRAL contains floating point numbers,
-** it cannot be used in preprocessor directives.
-*/
-
-#ifndef TYPE_INTEGRAL
-#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
-#endif /* !defined TYPE_INTEGRAL */
-
-#ifndef INT_STRLEN_MAXIMUM
-/*
-** 302 / 1000 is log10(2.0) rounded up.
-** Subtract one for the sign bit if the type is signed;
-** add one for integer division truncation;
-** add one more for a minus sign if the type is signed.
-*/
-#define INT_STRLEN_MAXIMUM(type) \
- ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
- 1 + TYPE_SIGNED(type))
-#endif /* !defined INT_STRLEN_MAXIMUM */
-
-/*
-** INITIALIZE(x)
-*/
-
-#ifndef GNUC_or_lint
-#ifdef lint
-#define GNUC_or_lint
-#endif /* defined lint */
-#ifndef lint
-#ifdef __GNUC__
-#define GNUC_or_lint
-#endif /* defined __GNUC__ */
-#endif /* !defined lint */
-#endif /* !defined GNUC_or_lint */
-
-#ifndef INITIALIZE
-#ifdef GNUC_or_lint
-#define INITIALIZE(x) ((x) = 0)
-#endif /* defined GNUC_or_lint */
-#ifndef GNUC_or_lint
-#define INITIALIZE(x)
-#endif /* !defined GNUC_or_lint */
-#endif /* !defined INITIALIZE */
-
-/*
-** For the benefit of GNU folk...
-** `_(MSGID)' uses the current locale's message library string for MSGID.
-** The default is to use gettext if available, and use MSGID otherwise.
-*/
-
-#ifndef _
-#if HAVE_GETTEXT
-#define _(msgid) gettext(msgid)
-#else /* !HAVE_GETTEXT */
-#define _(msgid) msgid
-#endif /* !HAVE_GETTEXT */
-#endif /* !defined _ */
-
-#ifndef TZ_DOMAIN
-#define TZ_DOMAIN "tz"
-#endif /* !defined TZ_DOMAIN */
-
-/*
-** UNIX was a registered trademark of The Open Group in 2003.
-*/
-
-#ifndef YEARSPERREPEAT
-#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
-#endif /* !defined YEARSPERREPEAT */
-
-/*
-** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
-*/
-
-#ifndef AVGSECSPERYEAR
-#define AVGSECSPERYEAR 31556952L
-#endif /* !defined AVGSECSPERYEAR */
-
-#ifndef SECSPERREPEAT
-#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
-#endif /* !defined SECSPERREPEAT */
-
-#ifndef SECSPERREPEAT_BITS
-#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
-#endif /* !defined SECSPERREPEAT_BITS */
-
- /*
- ** UNIX was a registered trademark of The Open Group in 2003.
- */
-
-#endif /* !defined PRIVATE_H */
diff --git a/usr.sbin/zic/scheck.c b/usr.sbin/zic/scheck.c
deleted file mode 100644
index abdb4ba..0000000
--- a/usr.sbin/zic/scheck.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-** This file is in the public domain, so clarified as of
-** 2006-07-17 by Arthur David Olson.
-*/
-
-#ifndef lint
-#ifndef NOID
-static const char elsieid[] = "@(#)scheck.c 8.19";
-#endif /* !defined lint */
-#endif /* !defined NOID */
-
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-/*LINTLIBRARY*/
-
-#include "private.h"
-
-const char *
-scheck(string, format)
-const char * const string;
-const char * const format;
-{
- register char * fbuf;
- register const char * fp;
- register char * tp;
- register int c;
- register const char * result;
- char dummy;
-
- result = "";
- if (string == NULL || format == NULL)
- return result;
- fbuf = imalloc((int) (2 * strlen(format) + 4));
- if (fbuf == NULL)
- return result;
- fp = format;
- tp = fbuf;
- while ((*tp++ = c = *fp++) != '\0') {
- if (c != '%')
- continue;
- if (*fp == '%') {
- *tp++ = *fp++;
- continue;
- }
- *tp++ = '*';
- if (*fp == '*')
- ++fp;
- while (is_digit(*fp))
- *tp++ = *fp++;
- if (*fp == 'l' || *fp == 'h')
- *tp++ = *fp++;
- else if (*fp == '[')
- do *tp++ = *fp++;
- while (*fp != '\0' && *fp != ']');
- if ((*tp++ = *fp++) == '\0')
- break;
- }
- *(tp - 1) = '%';
- *tp++ = 'c';
- *tp = '\0';
- if (sscanf(string, fbuf, &dummy) != 1)
- result = (char *) format;
- ifree(fbuf);
- return result;
-}
diff --git a/usr.sbin/zic/zdump.8 b/usr.sbin/zic/zdump.8
deleted file mode 100644
index 9ac0a03..0000000
--- a/usr.sbin/zic/zdump.8
+++ /dev/null
@@ -1,63 +0,0 @@
-.\"
-.\" @(#)zdump.8 8.2
-.\" This file is in the public domain, so clarified as of
-.\" 2009-05-17 by Arthur David Olson.
-.\" $FreeBSD$
-.\"
-.Dd June 20, 2004
-.Dt ZDUMP 8
-.Os
-.Sh NAME
-.Nm zdump
-.Nd timezone dumper
-.Sh SYNOPSIS
-.Nm
-.Op Fl -version
-.Op Fl v
-.Op Fl c Ar [loyear,]hiyear
-.Op Ar zonename ...
-.Sh DESCRIPTION
-The
-.Nm
-utility prints the current time in each
-.Ar zonename
-named on the command line.
-.Pp
-The following options are available:
-.Bl -tag -width indent
-.It Fl -version
-Output version information and exit.
-.It Fl v
-For each
-.Ar zonename
-on the command line,
-print the time at the lowest possible time value,
-the time one day after the lowest possible time value,
-the times both one second before and exactly at
-each detected time discontinuity,
-the time at one day less than the highest possible time value,
-and the time at the highest possible time value,
-Each line ends with
-.Em isdst=1
-if the given time is Daylight Saving Time or
-.Em isdst=0
-otherwise.
-.It Fl c Ar loyear,hiyear
-Cut off verbose output near the start of the given year(s).
-By default,
-the program cuts off verbose output near the starts of the years -500 and 2500.
-.El
-.Sh LIMITATIONS
-The
-.Fl v
-option may not be used on systems with floating-point time_t values
-that are neither float nor double.
-.Pp
-Time discontinuities are found by sampling the results returned by localtime
-at twelve-hour intervals.
-This works in all real-world cases;
-one can construct artificial time zones for which this fails.
-.Sh "SEE ALSO"
-.Xr ctime 3 ,
-.Xr tzfile 5 ,
-.Xr zic 8
diff --git a/usr.sbin/zic/zdump.c b/usr.sbin/zic/zdump.c
deleted file mode 100644
index 263a592..0000000
--- a/usr.sbin/zic/zdump.c
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
-** This file is in the public domain, so clarified as of
-** 2009-05-17 by Arthur David Olson.
-*/
-
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD$";
-static char elsieid[] = "@(#)zdump.c 8.9";
-#endif /* not lint */
-
-/*
-** This code has been made independent of the rest of the time
-** conversion package to increase confidence in the verification it provides.
-** You can use this code to help in verifying other implementations.
-*/
-
-#include <err.h>
-#include <stdio.h> /* for stdout, stderr */
-#include <stdlib.h> /* for exit, malloc, atoi */
-#include <string.h> /* for strcpy */
-#include <sys/types.h> /* for time_t */
-#include <time.h> /* for struct tm */
-#include <unistd.h>
-#include <float.h> /* for FLT_MAX and DBL_MAX */
-#include <ctype.h> /* for isalpha et al. */
-#ifndef isascii
-#define isascii(x) 1
-#endif /* !defined isascii */
-
-#ifndef ZDUMP_LO_YEAR
-#define ZDUMP_LO_YEAR (-500)
-#endif /* !defined ZDUMP_LO_YEAR */
-
-#ifndef ZDUMP_HI_YEAR
-#define ZDUMP_HI_YEAR 2500
-#endif /* !defined ZDUMP_HI_YEAR */
-
-#ifndef MAX_STRING_LENGTH
-#define MAX_STRING_LENGTH 1024
-#endif /* !defined MAX_STRING_LENGTH */
-
-#ifndef TRUE
-#define TRUE 1
-#endif /* !defined TRUE */
-
-#ifndef FALSE
-#define FALSE 0
-#endif /* !defined FALSE */
-
-#ifndef EXIT_SUCCESS
-#define EXIT_SUCCESS 0
-#endif /* !defined EXIT_SUCCESS */
-
-#ifndef EXIT_FAILURE
-#define EXIT_FAILURE 1
-#endif /* !defined EXIT_FAILURE */
-
-#ifndef SECSPERMIN
-#define SECSPERMIN 60
-#endif /* !defined SECSPERMIN */
-
-#ifndef MINSPERHOUR
-#define MINSPERHOUR 60
-#endif /* !defined MINSPERHOUR */
-
-#ifndef SECSPERHOUR
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#endif /* !defined SECSPERHOUR */
-
-#ifndef HOURSPERDAY
-#define HOURSPERDAY 24
-#endif /* !defined HOURSPERDAY */
-
-#ifndef EPOCH_YEAR
-#define EPOCH_YEAR 1970
-#endif /* !defined EPOCH_YEAR */
-
-#ifndef TM_YEAR_BASE
-#define TM_YEAR_BASE 1900
-#endif /* !defined TM_YEAR_BASE */
-
-#ifndef DAYSPERNYEAR
-#define DAYSPERNYEAR 365
-#endif /* !defined DAYSPERNYEAR */
-
-#ifndef isleap
-#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
-#endif /* !defined isleap */
-
-#ifndef isleap_sum
-/*
-** See tzfile.h for details on isleap_sum.
-*/
-#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
-#endif /* !defined isleap_sum */
-
-#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
-#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR)
-#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY)
-
-#ifndef HAVE_GETTEXT
-#define HAVE_GETTEXT 0
-#endif
-#if HAVE_GETTEXT
-#include "locale.h" /* for setlocale */
-#include "libintl.h"
-#endif /* HAVE_GETTEXT */
-
-#ifndef GNUC_or_lint
-#ifdef lint
-#define GNUC_or_lint
-#else /* !defined lint */
-#ifdef __GNUC__
-#define GNUC_or_lint
-#endif /* defined __GNUC__ */
-#endif /* !defined lint */
-#endif /* !defined GNUC_or_lint */
-
-#ifndef INITIALIZE
-#ifdef GNUC_or_lint
-#define INITIALIZE(x) ((x) = 0)
-#else /* !defined GNUC_or_lint */
-#define INITIALIZE(x)
-#endif /* !defined GNUC_or_lint */
-#endif /* !defined INITIALIZE */
-
-/*
-** For the benefit of GNU folk...
-** `_(MSGID)' uses the current locale's message library string for MSGID.
-** The default is to use gettext if available, and use MSGID otherwise.
-*/
-
-#ifndef _
-#if HAVE_GETTEXT
-#define _(msgid) gettext(msgid)
-#else /* !(HAVE_GETTEXT) */
-#define _(msgid) msgid
-#endif /* !(HAVE_GETTEXT) */
-#endif /* !defined _ */
-
-#ifndef TZ_DOMAIN
-#define TZ_DOMAIN "tz"
-#endif /* !defined TZ_DOMAIN */
-
-extern char ** environ;
-extern char * tzname[2];
-
-static time_t absolute_min_time;
-static time_t absolute_max_time;
-static size_t longest;
-static char * progname;
-static int warned;
-
-static void usage(const char *progname, FILE *stream, int status);
-static char * abbr(struct tm * tmp);
-static void abbrok(const char * abbrp, const char * zone);
-static long delta(struct tm * newp, struct tm * oldp);
-static void dumptime(const struct tm * tmp);
-static time_t hunt(char * name, time_t lot, time_t hit);
-static void setabsolutes(void);
-static void show(char * zone, time_t t, int v);
-static const char * tformat(void);
-static time_t yeartot(long y);
-
-#ifndef TYPECHECK
-#define my_localtime localtime
-#else /* !defined TYPECHECK */
-static struct tm *
-my_localtime(tp)
-time_t * tp;
-{
- register struct tm * tmp;
-
- tmp = localtime(tp);
- if (tp != NULL && tmp != NULL) {
- struct tm tm;
- register time_t t;
-
- tm = *tmp;
- t = mktime(&tm);
- if (t - *tp >= 1 || *tp - t >= 1) {
- (void) fflush(stdout);
- (void) fprintf(stderr, "\n%s: ", progname);
- (void) fprintf(stderr, tformat(), *tp);
- (void) fprintf(stderr, " ->");
- (void) fprintf(stderr, " year=%d", tmp->tm_year);
- (void) fprintf(stderr, " mon=%d", tmp->tm_mon);
- (void) fprintf(stderr, " mday=%d", tmp->tm_mday);
- (void) fprintf(stderr, " hour=%d", tmp->tm_hour);
- (void) fprintf(stderr, " min=%d", tmp->tm_min);
- (void) fprintf(stderr, " sec=%d", tmp->tm_sec);
- (void) fprintf(stderr, " isdst=%d", tmp->tm_isdst);
- (void) fprintf(stderr, " -> ");
- (void) fprintf(stderr, tformat(), t);
- (void) fprintf(stderr, "\n");
- }
- }
- return tmp;
-}
-#endif /* !defined TYPECHECK */
-
-static void
-abbrok(abbrp, zone)
-const char * const abbrp;
-const char * const zone;
-{
- register const char * cp;
- register char * wp;
-
- if (warned)
- return;
- cp = abbrp;
- wp = NULL;
- while (isascii((unsigned char) *cp) && isalpha((unsigned char) *cp))
- ++cp;
- if (cp - abbrp == 0)
- wp = _("lacks alphabetic at start");
- else if (cp - abbrp < 3)
- wp = _("has fewer than 3 alphabetics");
- else if (cp - abbrp > 6)
- wp = _("has more than 6 alphabetics");
- if (wp == NULL && (*cp == '+' || *cp == '-')) {
- ++cp;
- if (isascii((unsigned char) *cp) &&
- isdigit((unsigned char) *cp))
- if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
- ++cp;
- if (*cp != '\0')
- wp = _("differs from POSIX standard");
- }
- if (wp == NULL)
- return;
- (void) fflush(stdout);
- (void) fprintf(stderr,
- _("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"),
- progname, zone, abbrp, wp);
- warned = TRUE;
-}
-
-int
-main(argc, argv)
-int argc;
-char * argv[];
-{
- register int i;
- register int c;
- register int vflag;
- register char * cutarg;
- register long cutloyear = ZDUMP_LO_YEAR;
- register long cuthiyear = ZDUMP_HI_YEAR;
- register time_t cutlotime;
- register time_t cuthitime;
- register char ** fakeenv;
- time_t now;
- time_t t;
- time_t newt;
- struct tm tm;
- struct tm newtm;
- register struct tm * tmp;
- register struct tm * newtmp;
-
- INITIALIZE(cutlotime);
- INITIALIZE(cuthitime);
-#if HAVE_GETTEXT
- (void) setlocale(LC_MESSAGES, "");
-#ifdef TZ_DOMAINDIR
- (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
-#endif /* TEXTDOMAINDIR */
- (void) textdomain(TZ_DOMAIN);
-#endif /* HAVE_GETTEXT */
- for (i = 1; i < argc; ++i)
- if (strcmp(argv[i], "--version") == 0) {
- errx(EXIT_SUCCESS, "%s", elsieid);
- } else if (strcmp(argv[i], "--help") == 0) {
- usage(progname, stdout, EXIT_SUCCESS);
- }
- vflag = 0;
- cutarg = NULL;
- while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
- if (c == 'v')
- vflag = 1;
- else cutarg = optarg;
- if ((c != -1) ||
- (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
- usage(progname, stderr, EXIT_FAILURE);
- }
- if (vflag) {
- if (cutarg != NULL) {
- long lo;
- long hi;
- char dummy;
-
- if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) {
- cuthiyear = hi;
- } else if (sscanf(cutarg, "%ld,%ld%c",
- &lo, &hi, &dummy) == 2) {
- cutloyear = lo;
- cuthiyear = hi;
- } else {
-(void) fprintf(stderr, _("%s: wild -c argument %s\n"),
- progname, cutarg);
- exit(EXIT_FAILURE);
- }
- }
- setabsolutes();
- cutlotime = yeartot(cutloyear);
- cuthitime = yeartot(cuthiyear);
- }
- (void) time(&now);
- longest = 0;
- for (i = optind; i < argc; ++i)
- if (strlen(argv[i]) > longest)
- longest = strlen(argv[i]);
- {
- register int from;
- register int to;
-
- for (i = 0; environ[i] != NULL; ++i)
- continue;
- fakeenv = (char **) malloc((size_t) ((i + 2) *
- sizeof *fakeenv));
- if (fakeenv == NULL ||
- (fakeenv[0] = (char *) malloc((size_t) (longest +
- 4))) == NULL)
- errx(EXIT_FAILURE,
- _("malloc() failed"));
- to = 0;
- (void) strcpy(fakeenv[to++], "TZ=");
- for (from = 0; environ[from] != NULL; ++from)
- if (strncmp(environ[from], "TZ=", 3) != 0)
- fakeenv[to++] = environ[from];
- fakeenv[to] = NULL;
- environ = fakeenv;
- }
- for (i = optind; i < argc; ++i) {
- static char buf[MAX_STRING_LENGTH];
-
- (void) strcpy(&fakeenv[0][3], argv[i]);
- if (!vflag) {
- show(argv[i], now, FALSE);
- continue;
- }
- warned = FALSE;
- t = absolute_min_time;
- show(argv[i], t, TRUE);
- t += SECSPERHOUR * HOURSPERDAY;
- show(argv[i], t, TRUE);
- if (t < cutlotime)
- t = cutlotime;
- tmp = my_localtime(&t);
- if (tmp != NULL) {
- tm = *tmp;
- (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
- }
- for ( ; ; ) {
- if (t >= cuthitime || t >= cuthitime - SECSPERHOUR * 12)
- break;
- newt = t + SECSPERHOUR * 12;
- newtmp = localtime(&newt);
- if (newtmp != NULL)
- newtm = *newtmp;
- if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) :
- (delta(&newtm, &tm) != (newt - t) ||
- newtm.tm_isdst != tm.tm_isdst ||
- strcmp(abbr(&newtm), buf) != 0)) {
- newt = hunt(argv[i], t, newt);
- newtmp = localtime(&newt);
- if (newtmp != NULL) {
- newtm = *newtmp;
- (void) strncpy(buf,
- abbr(&newtm),
- (sizeof buf) - 1);
- }
- }
- t = newt;
- tm = newtm;
- tmp = newtmp;
- }
- t = absolute_max_time;
- t -= SECSPERHOUR * HOURSPERDAY;
- show(argv[i], t, TRUE);
- t += SECSPERHOUR * HOURSPERDAY;
- show(argv[i], t, TRUE);
- }
- if (fflush(stdout) || ferror(stdout))
- errx(EXIT_FAILURE, _("error writing standard output"));
- exit(EXIT_SUCCESS);
- /* If exit fails to exit... */
- return(EXIT_FAILURE);
-}
-
-static void
-setabsolutes(void)
-{
- if (0.5 == (time_t) 0.5) {
- /*
- ** time_t is floating.
- */
- if (sizeof (time_t) == sizeof (float)) {
- absolute_min_time = (time_t) -FLT_MAX;
- absolute_max_time = (time_t) FLT_MAX;
- } else if (sizeof (time_t) == sizeof (double)) {
- absolute_min_time = (time_t) -DBL_MAX;
- absolute_max_time = (time_t) DBL_MAX;
- } else {
- (void) fprintf(stderr,
-_("%s: use of -v on system with floating time_t other than float or double\n"),
- progname);
- exit(EXIT_FAILURE);
- }
- } else if (0 > (time_t) -1) {
- /*
- ** time_t is signed. Assume overflow wraps around.
- */
- time_t t = 0;
- time_t t1 = 1;
-
- while (t < t1) {
- t = t1;
- t1 = 2 * t1 + 1;
- }
-
- absolute_max_time = t;
- t = -t;
- absolute_min_time = t - 1;
- if (t < absolute_min_time)
- absolute_min_time = t;
- } else {
- /*
- ** time_t is unsigned.
- */
- absolute_min_time = 0;
- absolute_max_time = absolute_min_time - 1;
- }
-}
-
-static time_t
-yeartot(y)
-const long y;
-{
- register long myy;
- register long seconds;
- register time_t t;
-
- myy = EPOCH_YEAR;
- t = 0;
- while (myy != y) {
- if (myy < y) {
- seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
- ++myy;
- if (t > absolute_max_time - seconds) {
- t = absolute_max_time;
- break;
- }
- t += seconds;
- } else {
- --myy;
- seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
- if (t < absolute_min_time + seconds) {
- t = absolute_min_time;
- break;
- }
- t -= seconds;
- }
- }
- return t;
-}
-
-static void
-usage(const char *progname, FILE *stream, int status)
-{
- fprintf(stream,
-_("usage: %s [--version] [-v] [--help] [-c [loyear,]hiyear] zonename ...\n\
-\n\
-Report bugs to tz@elsie.nci.nih.gov.\n"), progname);
- exit(status);
-}
-
-static time_t
-hunt(char *name, time_t lot, time_t hit)
-{
- time_t t;
- long diff;
- struct tm lotm;
- register struct tm * lotmp;
- struct tm tm;
- register struct tm * tmp;
- char loab[MAX_STRING_LENGTH];
-
- lotmp = my_localtime(&lot);
- if (lotmp != NULL) {
- lotm = *lotmp;
- (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
- }
- for ( ; ; ) {
- diff = (long) (hit - lot);
- if (diff < 2)
- break;
- t = lot;
- t += diff / 2;
- if (t <= lot)
- ++t;
- else if (t >= hit)
- --t;
- tmp = my_localtime(&t);
- if (tmp != NULL)
- tm = *tmp;
- if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) :
- (delta(&tm, &lotm) == (t - lot) &&
- tm.tm_isdst == lotm.tm_isdst &&
- strcmp(abbr(&tm), loab) == 0)) {
- lot = t;
- lotm = tm;
- lotmp = tmp;
- } else hit = t;
- }
- show(name, lot, TRUE);
- show(name, hit, TRUE);
- return hit;
-}
-
-/*
-** Thanks to Paul Eggert for logic used in delta.
-*/
-
-static long
-delta(newp, oldp)
-struct tm * newp;
-struct tm * oldp;
-{
- register long result;
- register int tmy;
-
- if (newp->tm_year < oldp->tm_year)
- return -delta(oldp, newp);
- result = 0;
- for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
- result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE);
- result += newp->tm_yday - oldp->tm_yday;
- result *= HOURSPERDAY;
- result += newp->tm_hour - oldp->tm_hour;
- result *= MINSPERHOUR;
- result += newp->tm_min - oldp->tm_min;
- result *= SECSPERMIN;
- result += newp->tm_sec - oldp->tm_sec;
- return result;
-}
-
-static void
-show(char *zone, time_t t, int v)
-{
- register struct tm * tmp;
-
- (void) printf("%-*s ", (int) longest, zone);
- if (v) {
- tmp = gmtime(&t);
- if (tmp == NULL) {
- (void) printf(tformat(), t);
- } else {
- dumptime(tmp);
- (void) printf(" UTC");
- }
- (void) printf(" = ");
- }
- tmp = my_localtime(&t);
- dumptime(tmp);
- if (tmp != NULL) {
- if (*abbr(tmp) != '\0')
- (void) printf(" %s", abbr(tmp));
- if (v) {
- (void) printf(" isdst=%d", tmp->tm_isdst);
-#ifdef TM_GMTOFF
- (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
-#endif /* defined TM_GMTOFF */
- }
- }
- (void) printf("\n");
- if (tmp != NULL && *abbr(tmp) != '\0')
- abbrok(abbr(tmp), zone);
-}
-
-static char *
-abbr(tmp)
-struct tm * tmp;
-{
- register char * result;
- static char nada;
-
- if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
- return &nada;
- result = tzname[tmp->tm_isdst];
- return (result == NULL) ? &nada : result;
-}
-
-/*
-** The code below can fail on certain theoretical systems;
-** it works on all known real-world systems as of 2004-12-30.
-*/
-
-static const char *
-tformat(void)
-{
- if (0.5 == (time_t) 0.5) { /* floating */
- if (sizeof (time_t) > sizeof (double))
- return "%Lg";
- return "%g";
- }
- if (0 > (time_t) -1) { /* signed */
- if (sizeof (time_t) > sizeof (long))
- return "%lld";
- if (sizeof (time_t) > sizeof (int))
- return "%ld";
- return "%d";
- }
- if (sizeof (time_t) > sizeof (unsigned long))
- return "%llu";
- if (sizeof (time_t) > sizeof (unsigned int))
- return "%lu";
- return "%u";
-}
-
-static void
-dumptime(timeptr)
-register const struct tm * timeptr;
-{
- static const char wday_name[][3] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- };
- static const char mon_name[][3] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- register const char * wn;
- register const char * mn;
- register int lead;
- register int trail;
-
- if (timeptr == NULL) {
- (void) printf("NULL");
- return;
- }
- /*
- ** The packaged versions of localtime and gmtime never put out-of-range
- ** values in tm_wday or tm_mon, but since this code might be compiled
- ** with other (perhaps experimental) versions, paranoia is in order.
- */
- if (timeptr->tm_wday < 0 || timeptr->tm_wday >=
- (int) (sizeof wday_name / sizeof wday_name[0]))
- wn = "???";
- else wn = wday_name[timeptr->tm_wday];
- if (timeptr->tm_mon < 0 || timeptr->tm_mon >=
- (int) (sizeof mon_name / sizeof mon_name[0]))
- mn = "???";
- else mn = mon_name[timeptr->tm_mon];
- (void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d ",
- wn, mn,
- timeptr->tm_mday, timeptr->tm_hour,
- timeptr->tm_min, timeptr->tm_sec);
-#define DIVISOR 10
- trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR;
- lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR +
- trail / DIVISOR;
- trail %= DIVISOR;
- if (trail < 0 && lead > 0) {
- trail += DIVISOR;
- --lead;
- } else if (lead < 0 && trail > 0) {
- trail -= DIVISOR;
- ++lead;
- }
- if (lead == 0)
- (void) printf("%d", trail);
- else (void) printf("%d%d", lead, ((trail < 0) ? -trail : trail));
-}
diff --git a/usr.sbin/zic/zdump/Makefile b/usr.sbin/zic/zdump/Makefile
index 3443b15..d654dee 100644
--- a/usr.sbin/zic/zdump/Makefile
+++ b/usr.sbin/zic/zdump/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/..
+.PATH: ${.CURDIR}/../../../contrib/tzcode/zic
PROG= zdump
MAN= zdump.8
@@ -8,6 +8,8 @@ SRCS= zdump.c ialloc.c scheck.c
CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS
CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"/usr/share/zoneinfo\" -Demkdir=mkdir
-CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../lib/libc/stdtime
+CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../contrib/tzcode/stdtime
+
+WARNS?= 2
.include <bsd.prog.mk>
diff --git a/usr.sbin/zic/zic.8 b/usr.sbin/zic/zic.8
deleted file mode 100644
index 082ff25..0000000
--- a/usr.sbin/zic/zic.8
+++ /dev/null
@@ -1,465 +0,0 @@
-.\" $FreeBSD$
-.Dd June 20, 2004
-.Dt ZIC 8
-.Os
-.Sh NAME
-.Nm zic
-.Nd timezone compiler
-.Sh SYNOPSIS
-.Nm
-.Op Fl -version
-.Op Fl Dsv
-.Op Fl d Ar directory
-.Op Fl g Ar group
-.Op Fl L Ar leapsecondfilename
-.Op Fl l Ar localtime
-.Op Fl m Ar mode
-.Op Fl p Ar posixrules
-.Op Fl u Ar user
-.Op Fl y Ar command
-.Op Ar filename ...
-.Sh DESCRIPTION
-The
-.Nm
-utility reads text from the file(s) named on the command line
-and creates the time conversion information files specified in this input.
-If a
-.Ar filename
-is
-.Em - ,
-the standard input is read.
-.Pp
-The following options are available:
-.Bl -tag -width indent
-.It Fl -version
-Output version information and exit.
-.It Fl D
-Do not automatically create directories.
-If the input file(s) specify
-an output file in a directory which does not already exist, the
-default behavior is to attempt to create the directory.
-If
-.Fl D
-is specified,
-.Nm
-will instead error out immediately.
-.It Fl d Ar directory
-Create time conversion information files in the named directory rather than
-in the standard directory named below.
-.It Fl g Ar group
-After creating each output file, change its group ownership to the
-specified
-.Ar group
-(which can be either a name or a numeric group ID).
-.It Fl L Ar leapsecondfilename
-Read leap second information from the file with the given name.
-If this option is not used,
-no leap second information appears in output files.
-.It Fl l Ar timezone
-Use the given
-.Ar time zone
-as local time.
-The
-.Nm
-utility will act as if the input contained a link line of the form
-.Pp
-.D1 No "Link timezone localtime"
-.Pp
-(Note that this action has no effect on
-.Fx ,
-since the local time zone is specified in
-.Pa /etc/localtime
-and not
-.Pa /usr/share/zoneinfo/localtime . )
-.It Fl m Ar mode
-After creating each output file, change its access mode to
-.Ar mode .
-Both numeric and alphabetic modes are accepted
-(see
-.Xr chmod 1 ) .
-.It Fl p Ar timezone
-Use the given
-.Ar "time zone" Ns 's
-rules when handling POSIX-format
-time zone environment variables.
-The
-.Nm
-utility will act as if the input contained a link line of the form
-.Pp
-.D1 No "Link timezone posixrules"
-.It Fl u Ar user
-After creating each output file, change its owner to
-.Ar user
-(which can be either a name or a numeric user ID).
-.It Fl v
-Complain if a year that appears in a data file is outside the range
-of years representable by
-.Xr time 3
-values.
-.It Fl s
-Limit time values stored in output files to values that are the same
-whether they are taken to be signed or unsigned.
-You can use this option to generate SVVS-compatible files.
-.It Fl y Ar command
-Use the given
-.Ar command
-rather than
-.Em yearistype
-when checking year types (see below).
-.El
-.Pp
-Input lines are made up of fields.
-Fields are separated from one another by any number of white space characters.
-Leading and trailing white space on input lines is ignored.
-An unquoted sharp character (#) in the input introduces a comment which extends
-to the end of the line the sharp character appears on.
-White space characters and sharp characters may be enclosed in double quotes
-(") if they are to be used as part of a field.
-Any line that is blank (after comment stripping) is ignored.
-Non-blank lines are expected to be of one of three types:
-rule lines, zone lines, and link lines.
-.Pp
-A rule line has the form:
-.Dl "Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-For example:
-.Dl "Rule US 1967 1973 \- Apr lastSun 2:00 1:00 D
-.Pp
-The fields that make up a rule line are:
-.Bl -tag -width "LETTER/S" -offset indent
-.It NAME
-Give the (arbitrary) name of the set of rules this rule is part of.
-.It FROM
-Give the first year in which the rule applies.
-Any integer year can be supplied; the Gregorian calendar is assumed.
-The word
-.Em minimum
-(or an abbreviation) means the minimum year representable as an integer.
-The word
-.Em maximum
-(or an abbreviation) means the maximum year representable as an integer.
-Rules can describe times that are not representable as time values,
-with the unrepresentable times ignored; this allows rules to be portable
-among hosts with differing time value types.
-.It TO
-Give the final year in which the rule applies.
-In addition to
-.Em minimum
-and
-.Em maximum
-(as above),
-the word
-.Em only
-(or an abbreviation)
-may be used to repeat the value of the
-.Em FROM
-field.
-.It TYPE
-Give the type of year in which the rule applies.
-If
-.Em TYPE
-is
-.Em \-
-then the rule applies in all years between
-.Em FROM
-and
-.Em TO
-inclusive.
-If
-.Em TYPE
-is something else, then
-.Nm
-executes the command
-.Li yearistype Ar year Ar type
-to check the type of a year:
-an exit status of zero is taken to mean that the year is of the given type;
-an exit status of one is taken to mean that the year is not of the given type.
-.It IN
-Name the month in which the rule takes effect.
-Month names may be abbreviated.
-.It ON
-Give the day on which the rule takes effect.
-Recognized forms include:
-.Pp
-.Bl -tag -width lastSun -compact -offset indent
-.It \&5
-the fifth of the month
-.It lastSun
-the last Sunday in the month
-.It lastMon
-the last Monday in the month
-.It Sun>=8
-first Sunday on or after the eighth
-.It Sun<=25
-last Sunday on or before the 25th
-.El
-.Pp
-Names of days of the week may be abbreviated or spelled out in full.
-Note that there must be no spaces within the
-.Em ON
-field.
-.It AT
-Give the time of day at which the rule takes effect.
-Recognized forms include:
-.Pp
-.Bl -tag -width "\&1:28:14" -offset indent -compact
-.It 2
-time in hours
-.It 2:00
-time in hours and minutes
-.It 15:00
-24-hour format time (for times after noon)
-.It 1:28:14
-time in hours, minutes, and seconds
-.El
-.Pp
-where hour 0 is midnight at the start of the day,
-and hour 24 is midnight at the end of the day.
-Any of these forms may be followed by the letter
-.Sq Li w
-if the given time is local
-.Dq "wall clock"
-time,
-.Sq Li s
-if the given time is local
-.Dq standard
-time, or
-.Sq Li u
-(or
-.Sq Li g
-or
-.Sq Li z )
-if the given time is universal time;
-in the absence of an indicator,
-wall clock time is assumed.
-.It SAVE
-Give the amount of time to be added to local standard time when the rule is in
-effect.
-This field has the same format as the
-.Em AT
-field
-(although, of course, the
-.Sq Li w
-and
-.Sq Li s
-suffixes are not used).
-.It LETTER/S
-Give the
-.Dq "variable part"
-(for example, the
-.Dq S
-or
-.Dq D
-in
-.Dq EST
-or
-.Dq EDT )
-of time zone abbreviations to be used when this rule is in effect.
-If this field is
-.Em \- ,
-the variable part is null.
-.El
-.Pp
-A zone line has the form:
-.Dl "Zone NAME GMTOFF RULES/SAVE FORMAT [UNTILYEAR [MONTH [DAY [TIME]]]]
-For example:
-.Dl "Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00
-The fields that make up a zone line are:
-.Bl -tag -width indent
-.It NAME
-The name of the time zone.
-This is the name used in creating the time conversion information file for the
-zone.
-.It GMTOFF
-The amount of time to add to UTC to get standard time in this zone.
-This field has the same format as the
-.Em AT
-and
-.Em SAVE
-fields of rule lines;
-begin the field with a minus sign if time must be subtracted from UTC.
-.It RULES/SAVE
-The name of the rule(s) that apply in the time zone or,
-alternately, an amount of time to add to local standard time.
-If this field is
-.Em \-
-then standard time always applies in the time zone.
-.It FORMAT
-The format for time zone abbreviations in this time zone.
-The pair of characters
-.Em %s
-is used to show where the
-.Dq "variable part"
-of the time zone abbreviation goes.
-Alternately,
-a slash (/)
-separates standard and daylight abbreviations.
-.It UNTILYEAR [MONTH [DAY [TIME]]]
-The time at which the UTC offset or the rule(s) change for a location.
-It is specified as a year, a month, a day, and a time of day.
-If this is specified,
-the time zone information is generated from the given UTC offset
-and rule change until the time specified.
-The month, day, and time of day have the same format as the IN, ON, and AT
-fields of a rule; trailing fields can be omitted, and default to the
-earliest possible value for the missing fields.
-.Pp
-The next line must be a
-.Dq continuation
-line; this has the same form as a zone line except that the
-string
-.Dq Zone
-and the name are omitted, as the continuation line will
-place information starting at the time specified as the
-.Em until
-information in the previous line in the file used by the previous line.
-Continuation lines may contain
-.Em until
-information, just as zone lines do, indicating that the next line is a further
-continuation.
-.El
-.Pp
-A link line has the form
-.Dl "Link LINK-FROM LINK-TO
-For example:
-.Dl "Link Europe/Istanbul Asia/Istanbul
-The
-.Em LINK-FROM
-field should appear as the
-.Em NAME
-field in some zone line;
-the
-.Em LINK-TO
-field is used as an alternate name for that zone.
-.Pp
-Except for continuation lines,
-lines may appear in any order in the input.
-.Pp
-Lines in the file that describes leap seconds have the following form:
-.Dl "Leap YEAR MONTH DAY HH:MM:SS CORR R/S
-For example:
-.Dl "Leap 1974 Dec 31 23:59:60 + S
-The
-.Em YEAR ,
-.Em MONTH ,
-.Em DAY ,
-and
-.Em HH:MM:SS
-fields tell when the leap second happened.
-The
-.Em CORR
-field
-should be
-.Dq +
-if a second was added
-or
-.Dq -
-if a second was skipped.
-.\" There's no need to document the following, since it's impossible for more
-.\" than one leap second to be inserted or deleted at a time.
-.\" The C Standard is in error in suggesting the possibility.
-.\" See Terry J Quinn, The BIPM and the accurate measure of time,
-.\" Proc IEEE 79, 7 (July 1991), 894-905.
-.\" or
-.\" .q ++
-.\" if two seconds were added
-.\" or
-.\" .q --
-.\" if two seconds were skipped.
-The
-.Em R/S
-field
-should be (an abbreviation of)
-.Dq Stationary
-if the leap second time given by the other fields should be interpreted as UTC
-or
-(an abbreviation of)
-.Dq Rolling
-if the leap second time given by the other fields should be interpreted as
-local wall clock time.
-.Sh "EXTENDED EXAMPLE"
-Here is an extended example of
-.Nm
-input, intended to illustrate many of its features.
-.br
-.ne 22
-.nf
-.in +2m
-.ta \w'# Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'TYPE\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00\0\0'u +\w'SAVE\0\0'u
-.sp
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule Swiss 1940 only - Nov 2 0:00 1:00 S
-Rule Swiss 1940 only - Dec 31 0:00 0 -
-Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S
-Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0
-.sp .5
-Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S
-Rule EU 1977 only - Sep lastSun 1:00u 0 -
-Rule EU 1978 only - Oct 1 1:00u 0 -
-Rule EU 1979 1995 - Sep lastSun 1:00u 0 -
-Rule EU 1981 max - Mar lastSun 1:00u 1:00 S
-Rule EU 1996 max - Oct lastSun 1:00u 0 -
-.sp
-.ta \w'# Zone\0\0'u +\w'Europe/Zurich\0\0'u +\w'0:34:08\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u
-# Zone NAME GMTOFF RULES FORMAT UNTIL
-Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12
- 0:29:44 - BMT 1894 Jun
- 1:00 Swiss CE%sT 1981
- 1:00 EU CE%sT
-.sp
-Link Europe/Zurich Switzerland
-.sp
-.in
-.fi
-In this example, the zone is named Europe/Zurich but it has an alias
-as Switzerland.
-Zurich was 34 minutes and 8 seconds west of GMT until 1848-09-12
-at 00:00, when the offset changed to 29 minutes and 44 seconds.
-After 1894-06-01 at 00:00 Swiss daylight saving rules (defined with
-lines beginning with "Rule Swiss") apply, and the GMT offset became
-one hour.
-From 1981 to the present, EU daylight saving rules have applied,
-and the UTC offset has remained at one hour.
-.Pp
-In 1940, daylight saving time applied from November 2 at 00:00 to
-December 31 at 00:00.
-In 1941 and 1942, daylight saving time applied from the first Sunday
-in May at 02:00 to the first Sunday in October at 00:00.
-The pre-1981 EU daylight-saving rules have no effect here, but are
-included for completeness.
-Since 1981, daylight saving has begun on the last Sunday in March
-at 01:00 UTC.
-Until 1995 it ended the last Sunday in September at 01:00 UTC, but
-this changed to the last Sunday in October starting in 1996.
-.Pp
-For purposes of display, "LMT" and "BMT" were initially used,
-respectively.
-Since Swiss rules and later EU rules were applied, the display name
-for the timezone has been CET for standard time and CEST for daylight
-saving time.
-.Sh NOTES
-For areas with more than two types of local time,
-you may need to use local standard time in the
-.Em AT
-field of the earliest transition time's rule to ensure that
-the earliest transition time recorded in the compiled file is correct.
-.Pp
-If, for a particular zone, a clock advance caused by the start of
-daylight saving coincides with and is equal to a clock retreat
-caused by a change in UTC offset,
-.Nm
-produces a single transition to daylight saving at the new UTC offset
-(without any change in wall clock time).
-To get separate transitions use multiple zone continuation lines
-specifying transition instants using universal time.
-.Sh FILES
-.Bl -tag -width /usr/share/zoneinfo -compact
-.It /usr/share/zoneinfo
-standard directory used for created files
-.El
-.Sh "SEE ALSO"
-.Xr ctime 3 ,
-.Xr tzfile 5 ,
-.Xr zdump 8
-.\" @(#)zic.8 8.5
-.\" This file is in the public domain, so clarified as of
-.\" 2009-05-17 by Arthur David Olson.
diff --git a/usr.sbin/zic/zic.c b/usr.sbin/zic/zic.c
deleted file mode 100644
index 7670056..0000000
--- a/usr.sbin/zic/zic.c
+++ /dev/null
@@ -1,2723 +0,0 @@
-/*
-** This file is in the public domain, so clarified as of
-** 2006-07-17 by Arthur David Olson.
-*/
-
-static const char elsieid[] = "@(#)zic.c 8.20";
-
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include "private.h"
-#include "tzfile.h"
-#include <err.h>
-#include <locale.h>
-#include <sys/stat.h> /* for umask manifest constants */
-#include <sys/types.h>
-#include <unistd.h>
-
-#define ZIC_VERSION '2'
-
-typedef int_fast64_t zic_t;
-
-#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
-#define ZIC_MAX_ABBR_LEN_WO_WARN 6
-#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
-
-#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
-
-/*
-** On some ancient hosts, predicates like `isspace(C)' are defined
-** only if isascii(C) || C == EOF. Modern hosts obey the C Standard,
-** which says they are defined only if C == ((unsigned char) C) || C == EOF.
-** Neither the C Standard nor POSIX require that `isascii' exist.
-** For portability, we check both ancient and modern requirements.
-** If isascii is not defined, the isascii check succeeds trivially.
-*/
-#include "ctype.h"
-#ifndef isascii
-#define isascii(x) 1
-#endif
-
-#define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long))
-#define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */
-
-#define end(cp) (strchr((cp), '\0'))
-
-struct rule {
- const char * r_filename;
- int r_linenum;
- const char * r_name;
-
- int r_loyear; /* for example, 1986 */
- int r_hiyear; /* for example, 1986 */
- const char * r_yrtype;
- int r_lowasnum;
- int r_hiwasnum;
-
- int r_month; /* 0..11 */
-
- int r_dycode; /* see below */
- int r_dayofmonth;
- int r_wday;
-
- long r_tod; /* time from midnight */
- int r_todisstd; /* above is standard time if TRUE */
- /* or wall clock time if FALSE */
- int r_todisgmt; /* above is GMT if TRUE */
- /* or local time if FALSE */
- long r_stdoff; /* offset from standard time */
- const char * r_abbrvar; /* variable part of abbreviation */
-
- int r_todo; /* a rule to do (used in outzone) */
- zic_t r_temp; /* used in outzone */
-};
-
-/*
-** r_dycode r_dayofmonth r_wday
-*/
-
-#define DC_DOM 0 /* 1..31 */ /* unused */
-#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */
-#define DC_DOWLEQ 2 /* 1..31 */ /* 0..6 (Sun..Sat) */
-
-struct zone {
- const char * z_filename;
- int z_linenum;
-
- const char * z_name;
- long z_gmtoff;
- const char * z_rule;
- const char * z_format;
-
- long z_stdoff;
-
- struct rule * z_rules;
- int z_nrules;
-
- struct rule z_untilrule;
- zic_t z_untiltime;
-};
-
-static void addtt(zic_t starttime, int type);
-static int addtype(long gmtoff, const char * abbr, int isdst,
- int ttisstd, int ttisgmt);
-static void leapadd(zic_t t, int positive, int rolling, int count);
-static void adjleap(void);
-static void associate(void);
-static int ciequal(const char * ap, const char * bp);
-static void convert(long val, char * buf);
-static void convert64(zic_t val, char * buf);
-static void dolink(const char * fromfield, const char * tofield);
-static void doabbr(char * abbr, const char * format,
- const char * letters, int isdst, int doquotes);
-static void eat(const char * name, int num);
-static void eats(const char * name, int num,
- const char * rname, int rnum);
-static long eitol(int i);
-static void error(const char * message);
-static char ** getfields(char * buf);
-static long gethms(const char * string, const char * errstrng,
- int signable);
-static void infile(const char * filename);
-static void inleap(char ** fields, int nfields);
-static void inlink(char ** fields, int nfields);
-static void inrule(char ** fields, int nfields);
-static int inzcont(char ** fields, int nfields);
-static int inzone(char ** fields, int nfields);
-static int inzsub(char ** fields, int nfields, int iscont);
-static int is32(zic_t x);
-static int itsabbr(const char * abbr, const char * word);
-static int itsdir(const char * name);
-static int lowerit(int c);
-static char * memcheck(char * tocheck);
-static int mkdirs(char * filename);
-static void newabbr(const char * abbr);
-static long oadd(long t1, long t2);
-static void outzone(const struct zone * zp, int ntzones);
-static void puttzcode(long code, FILE * fp);
-static void puttzcode64(zic_t code, FILE * fp);
-static int rcomp(const void * leftp, const void * rightp);
-static zic_t rpytime(const struct rule * rp, int wantedy);
-static void rulesub(struct rule * rp,
- const char * loyearp, const char * hiyearp,
- const char * typep, const char * monthp,
- const char * dayp, const char * timep);
-static int stringoffset(char * result, long offset);
-static int stringrule(char * result, const struct rule * rp,
- long dstoff, long gmtoff);
-static void stringzone(char * result,
- const struct zone * zp, int ntzones);
-static void setboundaries(void);
-static void setgroup(gid_t *flag, const char *name);
-static void setuser(uid_t *flag, const char *name);
-static zic_t tadd(zic_t t1, long t2);
-static void usage(FILE *stream, int status);
-static void writezone(const char * name, const char * string);
-static int yearistype(int year, const char * type);
-
-static int charcnt;
-static int errors;
-static const char * filename;
-static int leapcnt;
-static int leapseen;
-static int leapminyear;
-static int leapmaxyear;
-static int linenum;
-static int max_abbrvar_len;
-static int max_format_len;
-static zic_t max_time;
-static int max_year;
-static zic_t min_time;
-static int min_year;
-static zic_t min_time;
-static int noise;
-static const char * rfilename;
-static int rlinenum;
-static int timecnt;
-static int typecnt;
-
-/*
-** Line codes.
-*/
-
-#define LC_RULE 0
-#define LC_ZONE 1
-#define LC_LINK 2
-#define LC_LEAP 3
-
-/*
-** Which fields are which on a Zone line.
-*/
-
-#define ZF_NAME 1
-#define ZF_GMTOFF 2
-#define ZF_RULE 3
-#define ZF_FORMAT 4
-#define ZF_TILYEAR 5
-#define ZF_TILMONTH 6
-#define ZF_TILDAY 7
-#define ZF_TILTIME 8
-#define ZONE_MINFIELDS 5
-#define ZONE_MAXFIELDS 9
-
-/*
-** Which fields are which on a Zone continuation line.
-*/
-
-#define ZFC_GMTOFF 0
-#define ZFC_RULE 1
-#define ZFC_FORMAT 2
-#define ZFC_TILYEAR 3
-#define ZFC_TILMONTH 4
-#define ZFC_TILDAY 5
-#define ZFC_TILTIME 6
-#define ZONEC_MINFIELDS 3
-#define ZONEC_MAXFIELDS 7
-
-/*
-** Which files are which on a Rule line.
-*/
-
-#define RF_NAME 1
-#define RF_LOYEAR 2
-#define RF_HIYEAR 3
-#define RF_COMMAND 4
-#define RF_MONTH 5
-#define RF_DAY 6
-#define RF_TOD 7
-#define RF_STDOFF 8
-#define RF_ABBRVAR 9
-#define RULE_FIELDS 10
-
-/*
-** Which fields are which on a Link line.
-*/
-
-#define LF_FROM 1
-#define LF_TO 2
-#define LINK_FIELDS 3
-
-/*
-** Which fields are which on a Leap line.
-*/
-
-#define LP_YEAR 1
-#define LP_MONTH 2
-#define LP_DAY 3
-#define LP_TIME 4
-#define LP_CORR 5
-#define LP_ROLL 6
-#define LEAP_FIELDS 7
-
-/*
-** Year synonyms.
-*/
-
-#define YR_MINIMUM 0
-#define YR_MAXIMUM 1
-#define YR_ONLY 2
-
-static struct rule * rules;
-static int nrules; /* number of rules */
-
-static struct zone * zones;
-static int nzones; /* number of zones */
-
-struct link {
- const char * l_filename;
- int l_linenum;
- const char * l_from;
- const char * l_to;
-};
-
-static struct link * links;
-static int nlinks;
-
-struct lookup {
- const char * l_word;
- const int l_value;
-};
-
-static struct lookup const * byword(const char * string,
- const struct lookup * lp);
-
-static struct lookup const line_codes[] = {
- { "Rule", LC_RULE },
- { "Zone", LC_ZONE },
- { "Link", LC_LINK },
- { "Leap", LC_LEAP },
- { NULL, 0}
-};
-
-static struct lookup const mon_names[] = {
- { "January", TM_JANUARY },
- { "February", TM_FEBRUARY },
- { "March", TM_MARCH },
- { "April", TM_APRIL },
- { "May", TM_MAY },
- { "June", TM_JUNE },
- { "July", TM_JULY },
- { "August", TM_AUGUST },
- { "September", TM_SEPTEMBER },
- { "October", TM_OCTOBER },
- { "November", TM_NOVEMBER },
- { "December", TM_DECEMBER },
- { NULL, 0 }
-};
-
-static struct lookup const wday_names[] = {
- { "Sunday", TM_SUNDAY },
- { "Monday", TM_MONDAY },
- { "Tuesday", TM_TUESDAY },
- { "Wednesday", TM_WEDNESDAY },
- { "Thursday", TM_THURSDAY },
- { "Friday", TM_FRIDAY },
- { "Saturday", TM_SATURDAY },
- { NULL, 0 }
-};
-
-static struct lookup const lasts[] = {
- { "last-Sunday", TM_SUNDAY },
- { "last-Monday", TM_MONDAY },
- { "last-Tuesday", TM_TUESDAY },
- { "last-Wednesday", TM_WEDNESDAY },
- { "last-Thursday", TM_THURSDAY },
- { "last-Friday", TM_FRIDAY },
- { "last-Saturday", TM_SATURDAY },
- { NULL, 0 }
-};
-
-static struct lookup const begin_years[] = {
- { "minimum", YR_MINIMUM },
- { "maximum", YR_MAXIMUM },
- { NULL, 0 }
-};
-
-static struct lookup const end_years[] = {
- { "minimum", YR_MINIMUM },
- { "maximum", YR_MAXIMUM },
- { "only", YR_ONLY },
- { NULL, 0 }
-};
-
-static struct lookup const leap_types[] = {
- { "Rolling", TRUE },
- { "Stationary", FALSE },
- { NULL, 0 }
-};
-
-static const int len_months[2][MONSPERYEAR] = {
- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
- { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
-};
-
-static const int len_years[2] = {
- DAYSPERNYEAR, DAYSPERLYEAR
-};
-
-static struct attype {
- zic_t at;
- unsigned char type;
-} attypes[TZ_MAX_TIMES];
-static long gmtoffs[TZ_MAX_TYPES];
-static char isdsts[TZ_MAX_TYPES];
-static unsigned char abbrinds[TZ_MAX_TYPES];
-static char ttisstds[TZ_MAX_TYPES];
-static char ttisgmts[TZ_MAX_TYPES];
-static char chars[TZ_MAX_CHARS];
-static zic_t trans[TZ_MAX_LEAPS];
-static long corr[TZ_MAX_LEAPS];
-static char roll[TZ_MAX_LEAPS];
-
-/*
-** Memory allocation.
-*/
-
-static char *
-memcheck(ptr)
-char * const ptr;
-{
- if (ptr == NULL)
- errx(EXIT_FAILURE, _("memory exhausted"));
- return ptr;
-}
-
-#define emalloc(size) memcheck(imalloc(size))
-#define erealloc(ptr, size) memcheck(irealloc((ptr), (size)))
-#define ecpyalloc(ptr) memcheck(icpyalloc(ptr))
-#define ecatalloc(oldp, newp) memcheck(icatalloc((oldp), (newp)))
-
-/*
-** Error handling.
-*/
-
-static void
-eats(name, num, rname, rnum)
-const char * const name;
-const int num;
-const char * const rname;
-const int rnum;
-{
- filename = name;
- linenum = num;
- rfilename = rname;
- rlinenum = rnum;
-}
-
-static void
-eat(name, num)
-const char * const name;
-const int num;
-{
- eats(name, num, (char *) NULL, -1);
-}
-
-static void
-error(string)
-const char * const string;
-{
- /*
- ** Match the format of "cc" to allow sh users to
- ** zic ... 2>&1 | error -t "*" -v
- ** on BSD systems.
- */
- (void) fprintf(stderr, _("\"%s\", line %d: %s"),
- filename, linenum, string);
- if (rfilename != NULL)
- (void) fprintf(stderr, _(" (rule from \"%s\", line %d)"),
- rfilename, rlinenum);
- (void) fprintf(stderr, "\n");
- ++errors;
-}
-
-static void
-warning(string)
-const char * const string;
-{
- char * cp;
-
- cp = ecpyalloc(_("warning: "));
- cp = ecatalloc(cp, string);
- error(cp);
- ifree(cp);
- --errors;
-}
-
-static void
-usage(FILE *stream, int status)
- {
- (void) fprintf(stream, _("usage is zic \
-[ --version ] [--help] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
-\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\
-\n\
-Report bugs to tz@elsie.nci.nih.gov.\n"));
- exit(status);
-}
-
-static const char * psxrules;
-static const char * lcltime;
-static const char * directory;
-static const char * leapsec;
-static const char * yitcommand;
-static int Dflag;
-static uid_t uflag = (uid_t)-1;
-static gid_t gflag = (gid_t)-1;
-static mode_t mflag = (S_IRUSR | S_IRGRP | S_IROTH
- | S_IWUSR);
-
-int
-main(argc, argv)
-int argc;
-char * argv[];
-{
- register int i;
- register int j;
- register int c;
-
-#ifdef unix
- (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
-#endif /* defined unix */
-#if HAVE_GETTEXT
- (void) setlocale(LC_ALL, "");
-#ifdef TZ_DOMAINDIR
- (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
-#endif /* defined TEXTDOMAINDIR */
- (void) textdomain(TZ_DOMAIN);
-#endif /* HAVE_GETTEXT */
- if (TYPE_BIT(zic_t) < 64) {
- (void) fprintf(stderr, "zic: %s\n",
- _("wild compilation-time specification of zic_t"));
- exit(EXIT_FAILURE);
- }
- for (i = 1; i < argc; ++i)
- if (strcmp(argv[i], "--version") == 0) {
- errx(EXIT_SUCCESS, "%s", elsieid);
- } else if (strcmp(argv[i], "--help") == 0) {
- usage(stdout, EXIT_SUCCESS);
- }
- while ((c = getopt(argc, argv, "Dd:g:l:m:p:L:u:vsy:")) != -1)
- switch (c) {
- default:
- usage(stderr, EXIT_FAILURE);
- case 'D':
- Dflag = 1;
- break;
- case 'd':
- if (directory == NULL)
- directory = optarg;
- else
- errx(EXIT_FAILURE,
-_("more than one -d option specified"));
- break;
- case 'g':
- setgroup(&gflag, optarg);
- break;
- case 'l':
- if (lcltime == NULL)
- lcltime = optarg;
- else
- errx(EXIT_FAILURE,
-_("more than one -l option specified"));
- break;
- case 'm':
- {
- void *set = setmode(optarg);
- if (set == NULL)
- errx(EXIT_FAILURE,
-_("invalid file mode"));
- mflag = getmode(set, mflag);
- free(set);
- break;
- }
- case 'p':
- if (psxrules == NULL)
- psxrules = optarg;
- else
- errx(EXIT_FAILURE,
-_("more than one -p option specified"));
- break;
- case 'u':
- setuser(&uflag, optarg);
- break;
- case 'y':
- if (yitcommand == NULL)
- yitcommand = optarg;
- else
- errx(EXIT_FAILURE,
-_("more than one -y option specified"));
- break;
- case 'L':
- if (leapsec == NULL)
- leapsec = optarg;
- else
- errx(EXIT_FAILURE,
-_("more than one -L option specified"));
- break;
- case 'v':
- noise = TRUE;
- break;
- case 's':
- (void) printf("zic: -s ignored\n");
- break;
- }
- if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
- usage(stderr, EXIT_FAILURE); /* usage message by request */
- if (directory == NULL)
- directory = TZDIR;
- if (yitcommand == NULL)
- yitcommand = "yearistype";
-
- setboundaries();
-
- if (optind < argc && leapsec != NULL) {
- infile(leapsec);
- adjleap();
- }
-
- for (i = optind; i < argc; ++i)
- infile(argv[i]);
- if (errors)
- exit(EXIT_FAILURE);
- associate();
- for (i = 0; i < nzones; i = j) {
- /*
- ** Find the next non-continuation zone entry.
- */
- for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
- continue;
- outzone(&zones[i], j - i);
- }
- /*
- ** Make links.
- */
- for (i = 0; i < nlinks; ++i) {
- eat(links[i].l_filename, links[i].l_linenum);
- dolink(links[i].l_from, links[i].l_to);
- if (noise)
- for (j = 0; j < nlinks; ++j)
- if (strcmp(links[i].l_to,
- links[j].l_from) == 0)
- warning(_("link to link"));
- }
- if (lcltime != NULL) {
- eat("command line", 1);
- dolink(lcltime, TZDEFAULT);
- }
- if (psxrules != NULL) {
- eat("command line", 1);
- dolink(psxrules, TZDEFRULES);
- }
- return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
-
-static void
-dolink(fromfield, tofield)
-const char * const fromfield;
-const char * const tofield;
-{
- register char * fromname;
- register char * toname;
-
- if (fromfield[0] == '/')
- fromname = ecpyalloc(fromfield);
- else {
- fromname = ecpyalloc(directory);
- fromname = ecatalloc(fromname, "/");
- fromname = ecatalloc(fromname, fromfield);
- }
- if (tofield[0] == '/')
- toname = ecpyalloc(tofield);
- else {
- toname = ecpyalloc(directory);
- toname = ecatalloc(toname, "/");
- toname = ecatalloc(toname, tofield);
- }
- /*
- ** We get to be careful here since
- ** there's a fair chance of root running us.
- */
- if (!itsdir(toname))
- (void) remove(toname);
- if (link(fromname, toname) != 0) {
- int result;
-
- if (mkdirs(toname) != 0)
- exit(EXIT_FAILURE);
-
- result = link(fromname, toname);
-#if HAVE_SYMLINK
- if (result != 0 &&
- access(fromname, F_OK) == 0 &&
- !itsdir(fromname)) {
- const char *s = tofield;
- register char * symlinkcontents = NULL;
- while ((s = strchr(s+1, '/')) != NULL)
- symlinkcontents =
- ecatalloc(symlinkcontents,
- "../");
- symlinkcontents =
- ecatalloc(symlinkcontents,
- fromname);
- result =
- symlink(symlinkcontents,
- toname);
- if (result == 0)
-warning(_("hard link failed, symbolic link used"));
- ifree(symlinkcontents);
- }
-#endif /* HAVE_SYMLINK */
- if (result != 0) {
- err(EXIT_FAILURE, _("can't link from %s to %s"),
- fromname, toname);
- }
- }
- ifree(fromname);
- ifree(toname);
-}
-
-#define TIME_T_BITS_IN_FILE 64
-
-static void
-setboundaries (void)
-{
- register int i;
-
- min_time = -1;
- for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
- min_time *= 2;
- max_time = -(min_time + 1);
-}
-
-static int
-itsdir(name)
-const char * const name;
-{
- register char * myname;
- register int accres;
-
- myname = ecpyalloc(name);
- myname = ecatalloc(myname, "/.");
- accres = access(myname, F_OK);
- ifree(myname);
- return accres == 0;
-}
-
-/*
-** Associate sets of rules with zones.
-*/
-
-/*
-** Sort by rule name.
-*/
-
-static int
-rcomp(cp1, cp2)
-const void * cp1;
-const void * cp2;
-{
- return strcmp(((const struct rule *) cp1)->r_name,
- ((const struct rule *) cp2)->r_name);
-}
-
-static void
-associate(void)
-{
- register struct zone * zp;
- register struct rule * rp;
- register int base, out;
- register int i, j;
-
- if (nrules != 0) {
- (void) qsort((void *) rules, (size_t) nrules,
- (size_t) sizeof *rules, rcomp);
- for (i = 0; i < nrules - 1; ++i) {
- if (strcmp(rules[i].r_name,
- rules[i + 1].r_name) != 0)
- continue;
- if (strcmp(rules[i].r_filename,
- rules[i + 1].r_filename) == 0)
- continue;
- eat(rules[i].r_filename, rules[i].r_linenum);
- warning(_("same rule name in multiple files"));
- eat(rules[i + 1].r_filename, rules[i + 1].r_linenum);
- warning(_("same rule name in multiple files"));
- for (j = i + 2; j < nrules; ++j) {
- if (strcmp(rules[i].r_name,
- rules[j].r_name) != 0)
- break;
- if (strcmp(rules[i].r_filename,
- rules[j].r_filename) == 0)
- continue;
- if (strcmp(rules[i + 1].r_filename,
- rules[j].r_filename) == 0)
- continue;
- break;
- }
- i = j - 1;
- }
- }
- for (i = 0; i < nzones; ++i) {
- zp = &zones[i];
- zp->z_rules = NULL;
- zp->z_nrules = 0;
- }
- for (base = 0; base < nrules; base = out) {
- rp = &rules[base];
- for (out = base + 1; out < nrules; ++out)
- if (strcmp(rp->r_name, rules[out].r_name) != 0)
- break;
- for (i = 0; i < nzones; ++i) {
- zp = &zones[i];
- if (strcmp(zp->z_rule, rp->r_name) != 0)
- continue;
- zp->z_rules = rp;
- zp->z_nrules = out - base;
- }
- }
- for (i = 0; i < nzones; ++i) {
- zp = &zones[i];
- if (zp->z_nrules == 0) {
- /*
- ** Maybe we have a local standard time offset.
- */
- eat(zp->z_filename, zp->z_linenum);
- zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"),
- TRUE);
- /*
- ** Note, though, that if there's no rule,
- ** a '%s' in the format is a bad thing.
- */
- if (strchr(zp->z_format, '%') != 0)
- error(_("%s in ruleless zone"));
- }
- }
- if (errors)
- exit(EXIT_FAILURE);
-}
-
-static void
-infile(name)
-const char * name;
-{
- register FILE * fp;
- register char ** fields;
- register char * cp;
- register const struct lookup * lp;
- register int nfields;
- register int wantcont;
- register int num;
- char buf[BUFSIZ];
-
- if (strcmp(name, "-") == 0) {
- name = _("standard input");
- fp = stdin;
- } else if ((fp = fopen(name, "r")) == NULL)
- err(EXIT_FAILURE, _("can't open %s"), name);
- wantcont = FALSE;
- for (num = 1; ; ++num) {
- eat(name, num);
- if (fgets(buf, (int) sizeof buf, fp) != buf)
- break;
- cp = strchr(buf, '\n');
- if (cp == NULL) {
- error(_("line too long"));
- exit(EXIT_FAILURE);
- }
- *cp = '\0';
- fields = getfields(buf);
- nfields = 0;
- while (fields[nfields] != NULL) {
- static char nada;
-
- if (strcmp(fields[nfields], "-") == 0)
- fields[nfields] = &nada;
- ++nfields;
- }
- if (nfields == 0) {
- /* nothing to do */
- } else if (wantcont) {
- wantcont = inzcont(fields, nfields);
- } else {
- lp = byword(fields[0], line_codes);
- if (lp == NULL)
- error(_("input line of unknown type"));
- else switch ((int) (lp->l_value)) {
- case LC_RULE:
- inrule(fields, nfields);
- wantcont = FALSE;
- break;
- case LC_ZONE:
- wantcont = inzone(fields, nfields);
- break;
- case LC_LINK:
- inlink(fields, nfields);
- wantcont = FALSE;
- break;
- case LC_LEAP:
- if (name != leapsec)
- warnx(
-_("leap line in non leap seconds file %s"), name);
- else inleap(fields, nfields);
- wantcont = FALSE;
- break;
- default: /* "cannot happen" */
- errx(EXIT_FAILURE,
-_("panic: invalid l_value %d"), lp->l_value);
- }
- }
- ifree((char *) fields);
- }
- if (ferror(fp))
- errx(EXIT_FAILURE, _("error reading %s"), filename);
- if (fp != stdin && fclose(fp))
- err(EXIT_FAILURE, _("error closing %s"), filename);
- if (wantcont)
- error(_("expected continuation line not found"));
-}
-
-/*
-** Convert a string of one of the forms
-** h -h hh:mm -hh:mm hh:mm:ss -hh:mm:ss
-** into a number of seconds.
-** A null string maps to zero.
-** Call error with errstring and return zero on errors.
-*/
-
-static long
-gethms(string, errstring, signable)
-const char * string;
-const char * const errstring;
-const int signable;
-{
- long hh;
- int mm, ss, sign;
-
- if (string == NULL || *string == '\0')
- return 0;
- if (!signable)
- sign = 1;
- else if (*string == '-') {
- sign = -1;
- ++string;
- } else sign = 1;
- if (sscanf(string, scheck(string, "%ld"), &hh) == 1)
- mm = ss = 0;
- else if (sscanf(string, scheck(string, "%ld:%d"), &hh, &mm) == 2)
- ss = 0;
- else if (sscanf(string, scheck(string, "%ld:%d:%d"),
- &hh, &mm, &ss) != 3) {
- error(errstring);
- return 0;
- }
- if (hh < 0 ||
- mm < 0 || mm >= MINSPERHOUR ||
- ss < 0 || ss > SECSPERMIN) {
- error(errstring);
- return 0;
- }
- if (LONG_MAX / SECSPERHOUR < hh) {
- error(_("time overflow"));
- return 0;
- }
- if (noise && hh == HOURSPERDAY && mm == 0 && ss == 0)
- warning(_("24:00 not handled by pre-1998 versions of zic"));
- if (noise && (hh > HOURSPERDAY ||
- (hh == HOURSPERDAY && (mm != 0 || ss != 0))))
-warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
- return oadd(eitol(sign) * hh * eitol(SECSPERHOUR),
- eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss)));
-}
-
-static void
-inrule(fields, nfields)
-register char ** const fields;
-const int nfields;
-{
- static struct rule r;
-
- if (nfields != RULE_FIELDS) {
- error(_("wrong number of fields on Rule line"));
- return;
- }
- if (*fields[RF_NAME] == '\0') {
- error(_("nameless rule"));
- return;
- }
- r.r_filename = filename;
- r.r_linenum = linenum;
- r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), TRUE);
- rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
- fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
- r.r_name = ecpyalloc(fields[RF_NAME]);
- r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
- if (max_abbrvar_len < strlen(r.r_abbrvar))
- max_abbrvar_len = strlen(r.r_abbrvar);
- rules = (struct rule *) (void *) erealloc((char *) rules,
- (int) ((nrules + 1) * sizeof *rules));
- rules[nrules++] = r;
-}
-
-static int
-inzone(fields, nfields)
-register char ** const fields;
-const int nfields;
-{
- register int i;
- static char * buf;
-
- if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) {
- error(_("wrong number of fields on Zone line"));
- return FALSE;
- }
- if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) {
- buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT)));
- (void) sprintf(buf,
-_("\"Zone %s\" line and -l option are mutually exclusive"),
- TZDEFAULT);
- error(buf);
- return FALSE;
- }
- if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) {
- buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES)));
- (void) sprintf(buf,
-_("\"Zone %s\" line and -p option are mutually exclusive"),
- TZDEFRULES);
- error(buf);
- return FALSE;
- }
- for (i = 0; i < nzones; ++i)
- if (zones[i].z_name != NULL &&
- strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) {
- buf = erealloc(buf, (int) (132 +
- strlen(fields[ZF_NAME]) +
- strlen(zones[i].z_filename)));
- (void) sprintf(buf,
-_("duplicate zone name %s (file \"%s\", line %d)"),
- fields[ZF_NAME],
- zones[i].z_filename,
- zones[i].z_linenum);
- error(buf);
- return FALSE;
- }
- return inzsub(fields, nfields, FALSE);
-}
-
-static int
-inzcont(fields, nfields)
-register char ** const fields;
-const int nfields;
-{
- if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
- error(_("wrong number of fields on Zone continuation line"));
- return FALSE;
- }
- return inzsub(fields, nfields, TRUE);
-}
-
-static int
-inzsub(fields, nfields, iscont)
-register char ** const fields;
-const int nfields;
-const int iscont;
-{
- register char * cp;
- static struct zone z;
- register int i_gmtoff, i_rule, i_format;
- register int i_untilyear, i_untilmonth;
- register int i_untilday, i_untiltime;
- register int hasuntil;
-
- if (iscont) {
- i_gmtoff = ZFC_GMTOFF;
- i_rule = ZFC_RULE;
- i_format = ZFC_FORMAT;
- i_untilyear = ZFC_TILYEAR;
- i_untilmonth = ZFC_TILMONTH;
- i_untilday = ZFC_TILDAY;
- i_untiltime = ZFC_TILTIME;
- z.z_name = NULL;
- } else {
- i_gmtoff = ZF_GMTOFF;
- i_rule = ZF_RULE;
- i_format = ZF_FORMAT;
- i_untilyear = ZF_TILYEAR;
- i_untilmonth = ZF_TILMONTH;
- i_untilday = ZF_TILDAY;
- i_untiltime = ZF_TILTIME;
- z.z_name = ecpyalloc(fields[ZF_NAME]);
- }
- z.z_filename = filename;
- z.z_linenum = linenum;
- z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UTC offset"), TRUE);
- if ((cp = strchr(fields[i_format], '%')) != 0) {
- if (*++cp != 's' || strchr(cp, '%') != 0) {
- error(_("invalid abbreviation format"));
- return FALSE;
- }
- }
- z.z_rule = ecpyalloc(fields[i_rule]);
- z.z_format = ecpyalloc(fields[i_format]);
- if (max_format_len < strlen(z.z_format))
- max_format_len = strlen(z.z_format);
- hasuntil = nfields > i_untilyear;
- if (hasuntil) {
- z.z_untilrule.r_filename = filename;
- z.z_untilrule.r_linenum = linenum;
- rulesub(&z.z_untilrule,
- fields[i_untilyear],
- "only",
- "",
- (nfields > i_untilmonth) ?
- fields[i_untilmonth] : "Jan",
- (nfields > i_untilday) ? fields[i_untilday] : "1",
- (nfields > i_untiltime) ? fields[i_untiltime] : "0");
- z.z_untiltime = rpytime(&z.z_untilrule,
- z.z_untilrule.r_loyear);
- if (iscont && nzones > 0 &&
- z.z_untiltime > min_time &&
- z.z_untiltime < max_time &&
- zones[nzones - 1].z_untiltime > min_time &&
- zones[nzones - 1].z_untiltime < max_time &&
- zones[nzones - 1].z_untiltime >= z.z_untiltime) {
- error(_(
-"Zone continuation line end time is not after end time of previous line"
- ));
- return FALSE;
- }
- }
- zones = (struct zone *) (void *) erealloc((char *) zones,
- (int) ((nzones + 1) * sizeof *zones));
- zones[nzones++] = z;
- /*
- ** If there was an UNTIL field on this line,
- ** there's more information about the zone on the next line.
- */
- return hasuntil;
-}
-
-static void
-inleap(fields, nfields)
-register char ** const fields;
-const int nfields;
-{
- register const char * cp;
- register const struct lookup * lp;
- register int i, j;
- int year, month, day;
- long dayoff, tod;
- zic_t t;
-
- if (nfields != LEAP_FIELDS) {
- error(_("wrong number of fields on Leap line"));
- return;
- }
- dayoff = 0;
- cp = fields[LP_YEAR];
- if (sscanf(cp, scheck(cp, "%d"), &year) != 1) {
- /*
- ** Leapin' Lizards!
- */
- error(_("invalid leaping year"));
- return;
- }
- if (!leapseen || leapmaxyear < year)
- leapmaxyear = year;
- if (!leapseen || leapminyear > year)
- leapminyear = year;
- leapseen = TRUE;
- j = EPOCH_YEAR;
- while (j != year) {
- if (year > j) {
- i = len_years[isleap(j)];
- ++j;
- } else {
- --j;
- i = -len_years[isleap(j)];
- }
- dayoff = oadd(dayoff, eitol(i));
- }
- if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) {
- error(_("invalid month name"));
- return;
- }
- month = lp->l_value;
- j = TM_JANUARY;
- while (j != month) {
- i = len_months[isleap(year)][j];
- dayoff = oadd(dayoff, eitol(i));
- ++j;
- }
- cp = fields[LP_DAY];
- if (sscanf(cp, scheck(cp, "%d"), &day) != 1 ||
- day <= 0 || day > len_months[isleap(year)][month]) {
- error(_("invalid day of month"));
- return;
- }
- dayoff = oadd(dayoff, eitol(day - 1));
- if (dayoff < 0 && !TYPE_SIGNED(zic_t)) {
- error(_("time before zero"));
- return;
- }
- if (dayoff < min_time / SECSPERDAY) {
- error(_("time too small"));
- return;
- }
- if (dayoff > max_time / SECSPERDAY) {
- error(_("time too large"));
- return;
- }
- t = (zic_t) dayoff * SECSPERDAY;
- tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE);
- cp = fields[LP_CORR];
- {
- register int positive;
- int count;
-
- if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */
- positive = FALSE;
- count = 1;
- } else if (strcmp(cp, "--") == 0) {
- positive = FALSE;
- count = 2;
- } else if (strcmp(cp, "+") == 0) {
- positive = TRUE;
- count = 1;
- } else if (strcmp(cp, "++") == 0) {
- positive = TRUE;
- count = 2;
- } else {
- error(_("illegal CORRECTION field on Leap line"));
- return;
- }
- if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) {
- error(_(
- "illegal Rolling/Stationary field on Leap line"
- ));
- return;
- }
- leapadd(tadd(t, tod), positive, lp->l_value, count);
- }
-}
-
-static void
-inlink(fields, nfields)
-register char ** const fields;
-const int nfields;
-{
- struct link l;
-
- if (nfields != LINK_FIELDS) {
- error(_("wrong number of fields on Link line"));
- return;
- }
- if (*fields[LF_FROM] == '\0') {
- error(_("blank FROM field on Link line"));
- return;
- }
- if (*fields[LF_TO] == '\0') {
- error(_("blank TO field on Link line"));
- return;
- }
- l.l_filename = filename;
- l.l_linenum = linenum;
- l.l_from = ecpyalloc(fields[LF_FROM]);
- l.l_to = ecpyalloc(fields[LF_TO]);
- links = (struct link *) (void *) erealloc((char *) links,
- (int) ((nlinks + 1) * sizeof *links));
- links[nlinks++] = l;
-}
-
-static void
-rulesub(rp, loyearp, hiyearp, typep, monthp, dayp, timep)
-register struct rule * const rp;
-const char * const loyearp;
-const char * const hiyearp;
-const char * const typep;
-const char * const monthp;
-const char * const dayp;
-const char * const timep;
-{
- register const struct lookup * lp;
- register const char * cp;
- register char * dp;
- register char * ep;
-
- if ((lp = byword(monthp, mon_names)) == NULL) {
- error(_("invalid month name"));
- return;
- }
- rp->r_month = lp->l_value;
- rp->r_todisstd = FALSE;
- rp->r_todisgmt = FALSE;
- dp = ecpyalloc(timep);
- if (*dp != '\0') {
- ep = dp + strlen(dp) - 1;
- switch (lowerit(*ep)) {
- case 's': /* Standard */
- rp->r_todisstd = TRUE;
- rp->r_todisgmt = FALSE;
- *ep = '\0';
- break;
- case 'w': /* Wall */
- rp->r_todisstd = FALSE;
- rp->r_todisgmt = FALSE;
- *ep = '\0';
- break;
- case 'g': /* Greenwich */
- case 'u': /* Universal */
- case 'z': /* Zulu */
- rp->r_todisstd = TRUE;
- rp->r_todisgmt = TRUE;
- *ep = '\0';
- break;
- }
- }
- rp->r_tod = gethms(dp, _("invalid time of day"), FALSE);
- ifree(dp);
- /*
- ** Year work.
- */
- cp = loyearp;
- lp = byword(cp, begin_years);
- rp->r_lowasnum = lp == NULL;
- if (!rp->r_lowasnum) switch ((int) lp->l_value) {
- case YR_MINIMUM:
- rp->r_loyear = INT_MIN;
- break;
- case YR_MAXIMUM:
- rp->r_loyear = INT_MAX;
- break;
- default: /* "cannot happen" */
- errx(EXIT_FAILURE,
- _("panic: invalid l_value %d"), lp->l_value);
- } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) {
- error(_("invalid starting year"));
- return;
- }
- cp = hiyearp;
- lp = byword(cp, end_years);
- rp->r_hiwasnum = lp == NULL;
- if (!rp->r_hiwasnum) switch ((int) lp->l_value) {
- case YR_MINIMUM:
- rp->r_hiyear = INT_MIN;
- break;
- case YR_MAXIMUM:
- rp->r_hiyear = INT_MAX;
- break;
- case YR_ONLY:
- rp->r_hiyear = rp->r_loyear;
- break;
- default: /* "cannot happen" */
- errx(EXIT_FAILURE,
- _("panic: invalid l_value %d"), lp->l_value);
- } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) {
- error(_("invalid ending year"));
- return;
- }
- if (rp->r_loyear > rp->r_hiyear) {
- error(_("starting year greater than ending year"));
- return;
- }
- if (*typep == '\0')
- rp->r_yrtype = NULL;
- else {
- if (rp->r_loyear == rp->r_hiyear) {
- error(_("typed single year"));
- return;
- }
- rp->r_yrtype = ecpyalloc(typep);
- }
- /*
- ** Day work.
- ** Accept things such as:
- ** 1
- ** last-Sunday
- ** Sun<=20
- ** Sun>=7
- */
- dp = ecpyalloc(dayp);
- if ((lp = byword(dp, lasts)) != NULL) {
- rp->r_dycode = DC_DOWLEQ;
- rp->r_wday = lp->l_value;
- rp->r_dayofmonth = len_months[1][rp->r_month];
- } else {
- if ((ep = strchr(dp, '<')) != 0)
- rp->r_dycode = DC_DOWLEQ;
- else if ((ep = strchr(dp, '>')) != 0)
- rp->r_dycode = DC_DOWGEQ;
- else {
- ep = dp;
- rp->r_dycode = DC_DOM;
- }
- if (rp->r_dycode != DC_DOM) {
- *ep++ = 0;
- if (*ep++ != '=') {
- error(_("invalid day of month"));
- ifree(dp);
- return;
- }
- if ((lp = byword(dp, wday_names)) == NULL) {
- error(_("invalid weekday name"));
- ifree(dp);
- return;
- }
- rp->r_wday = lp->l_value;
- }
- if (sscanf(ep, scheck(ep, "%d"), &rp->r_dayofmonth) != 1 ||
- rp->r_dayofmonth <= 0 ||
- (rp->r_dayofmonth > len_months[1][rp->r_month])) {
- error(_("invalid day of month"));
- ifree(dp);
- return;
- }
- }
- ifree(dp);
-}
-
-static void
-convert(val, buf)
-const long val;
-char * const buf;
-{
- register int i;
- register int shift;
-
- for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
- buf[i] = val >> shift;
-}
-
-static void
-convert64(val, buf)
-const zic_t val;
-char * const buf;
-{
- register int i;
- register int shift;
-
- for (i = 0, shift = 56; i < 8; ++i, shift -= 8)
- buf[i] = val >> shift;
-}
-
-static void
-puttzcode(val, fp)
-const long val;
-FILE * const fp;
-{
- char buf[4];
-
- convert(val, buf);
- (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
-}
-
-static void
-puttzcode64(val, fp)
-const zic_t val;
-FILE * const fp;
-{
- char buf[8];
-
- convert64(val, buf);
- (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
-}
-
-static int
-atcomp(avp, bvp)
-const void * avp;
-const void * bvp;
-{
- const zic_t a = ((const struct attype *) avp)->at;
- const zic_t b = ((const struct attype *) bvp)->at;
-
- return (a < b) ? -1 : (a > b);
-}
-
-static int
-is32(x)
-const zic_t x;
-{
- return INT32_MIN <= x && x <= INT32_MAX;
-}
-
-static void
-writezone(name, string)
-const char * const name;
-const char * const string;
-{
- register FILE * fp;
- register int i, j;
- register int leapcnt32, leapi32;
- register int timecnt32, timei32;
- register int pass;
- static char * fullname;
- static const struct tzhead tzh0;
- static struct tzhead tzh;
- zic_t ats[TZ_MAX_TIMES];
- unsigned char types[TZ_MAX_TIMES];
-
- /*
- ** Sort.
- */
- if (timecnt > 1)
- (void) qsort((void *) attypes, (size_t) timecnt,
- (size_t) sizeof *attypes, atcomp);
- /*
- ** Optimize.
- */
- {
- int fromi;
- int toi;
-
- toi = 0;
- fromi = 0;
- while (fromi < timecnt && attypes[fromi].at < min_time)
- ++fromi;
- if (isdsts[0] == 0)
- while (fromi < timecnt && attypes[fromi].type == 0)
- ++fromi; /* handled by default rule */
- for ( ; fromi < timecnt; ++fromi) {
- if (toi != 0 && ((attypes[fromi].at +
- gmtoffs[attypes[toi - 1].type]) <=
- (attypes[toi - 1].at + gmtoffs[toi == 1 ? 0
- : attypes[toi - 2].type]))) {
- attypes[toi - 1].type =
- attypes[fromi].type;
- continue;
- }
- if (toi == 0 ||
- attypes[toi - 1].type != attypes[fromi].type)
- attypes[toi++] = attypes[fromi];
- }
- timecnt = toi;
- }
- /*
- ** Transfer.
- */
- for (i = 0; i < timecnt; ++i) {
- ats[i] = attypes[i].at;
- types[i] = attypes[i].type;
- }
- /*
- ** Correct for leap seconds.
- */
- for (i = 0; i < timecnt; ++i) {
- j = leapcnt;
- while (--j >= 0)
- if (ats[i] > trans[j] - corr[j]) {
- ats[i] = tadd(ats[i], corr[j]);
- break;
- }
- }
- /*
- ** Figure out 32-bit-limited starts and counts.
- */
- timecnt32 = timecnt;
- timei32 = 0;
- leapcnt32 = leapcnt;
- leapi32 = 0;
- while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
- --timecnt32;
- while (timecnt32 > 0 && !is32(ats[timei32])) {
- --timecnt32;
- ++timei32;
- }
- while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
- --leapcnt32;
- while (leapcnt32 > 0 && !is32(trans[leapi32])) {
- --leapcnt32;
- ++leapi32;
- }
- fullname = erealloc(fullname,
- (int) (strlen(directory) + 1 + strlen(name) + 1));
- (void) sprintf(fullname, "%s/%s", directory, name);
-
- /*
- * Remove old file, if any, to snap links.
- */
- if (!itsdir(fullname) && remove(fullname) != 0 && errno != ENOENT)
- err(EXIT_FAILURE, _("can't remove %s"), fullname);
-
- if ((fp = fopen(fullname, "wb")) == NULL) {
- if (mkdirs(fullname) != 0)
- exit(EXIT_FAILURE);
- if ((fp = fopen(fullname, "wb")) == NULL)
- err(EXIT_FAILURE, _("can't create %s"), fullname);
- }
- for (pass = 1; pass <= 2; ++pass) {
- register int thistimei, thistimecnt;
- register int thisleapi, thisleapcnt;
- register int thistimelim, thisleaplim;
- int writetype[TZ_MAX_TIMES];
- int typemap[TZ_MAX_TYPES];
- register int thistypecnt;
- char thischars[TZ_MAX_CHARS];
- char thischarcnt;
- int indmap[TZ_MAX_CHARS];
-
- if (pass == 1) {
- thistimei = timei32;
- thistimecnt = timecnt32;
- thisleapi = leapi32;
- thisleapcnt = leapcnt32;
- } else {
- thistimei = 0;
- thistimecnt = timecnt;
- thisleapi = 0;
- thisleapcnt = leapcnt;
- }
- thistimelim = thistimei + thistimecnt;
- thisleaplim = thisleapi + thisleapcnt;
- for (i = 0; i < typecnt; ++i)
- writetype[i] = thistimecnt == timecnt;
- if (thistimecnt == 0) {
- /*
- ** No transition times fall in the current
- ** (32- or 64-bit) window.
- */
- if (typecnt != 0)
- writetype[typecnt - 1] = TRUE;
- } else {
- for (i = thistimei - 1; i < thistimelim; ++i)
- if (i >= 0)
- writetype[types[i]] = TRUE;
- /*
- ** For America/Godthab and Antarctica/Palmer
- */
- if (thistimei == 0)
- writetype[0] = TRUE;
- }
- thistypecnt = 0;
- for (i = 0; i < typecnt; ++i)
- typemap[i] = writetype[i] ? thistypecnt++ : -1;
- for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i)
- indmap[i] = -1;
- thischarcnt = 0;
- for (i = 0; i < typecnt; ++i) {
- register char * thisabbr;
-
- if (!writetype[i])
- continue;
- if (indmap[abbrinds[i]] >= 0)
- continue;
- thisabbr = &chars[abbrinds[i]];
- for (j = 0; j < thischarcnt; ++j)
- if (strcmp(&thischars[j], thisabbr) == 0)
- break;
- if (j == thischarcnt) {
- (void) strcpy(&thischars[(int) thischarcnt],
- thisabbr);
- thischarcnt += strlen(thisabbr) + 1;
- }
- indmap[abbrinds[i]] = j;
- }
-#define DO(field) (void) fwrite((void *) tzh.field, \
- (size_t) sizeof tzh.field, (size_t) 1, fp)
- tzh = tzh0;
- (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
- tzh.tzh_version[0] = ZIC_VERSION;
- convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt);
- convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt);
- convert(eitol(thisleapcnt), tzh.tzh_leapcnt);
- convert(eitol(thistimecnt), tzh.tzh_timecnt);
- convert(eitol(thistypecnt), tzh.tzh_typecnt);
- convert(eitol(thischarcnt), tzh.tzh_charcnt);
- DO(tzh_magic);
- DO(tzh_version);
- DO(tzh_reserved);
- DO(tzh_ttisgmtcnt);
- DO(tzh_ttisstdcnt);
- DO(tzh_leapcnt);
- DO(tzh_timecnt);
- DO(tzh_typecnt);
- DO(tzh_charcnt);
-#undef DO
- for (i = thistimei; i < thistimelim; ++i)
- if (pass == 1)
- puttzcode((long) ats[i], fp);
- else puttzcode64(ats[i], fp);
- for (i = thistimei; i < thistimelim; ++i) {
- unsigned char uc;
-
- uc = typemap[types[i]];
- (void) fwrite((void *) &uc,
- (size_t) sizeof uc,
- (size_t) 1,
- fp);
- }
- for (i = 0; i < typecnt; ++i)
- if (writetype[i]) {
- puttzcode(gmtoffs[i], fp);
- (void) putc(isdsts[i], fp);
- (void) putc((unsigned char) indmap[abbrinds[i]], fp);
- }
- if (thischarcnt != 0)
- (void) fwrite((void *) thischars,
- (size_t) sizeof thischars[0],
- (size_t) thischarcnt, fp);
- for (i = thisleapi; i < thisleaplim; ++i) {
- register zic_t todo;
-
- if (roll[i]) {
- if (timecnt == 0 || trans[i] < ats[0]) {
- j = 0;
- while (isdsts[j])
- if (++j >= typecnt) {
- j = 0;
- break;
- }
- } else {
- j = 1;
- while (j < timecnt &&
- trans[i] >= ats[j])
- ++j;
- j = types[j - 1];
- }
- todo = tadd(trans[i], -gmtoffs[j]);
- } else todo = trans[i];
- if (pass == 1)
- puttzcode((long) todo, fp);
- else puttzcode64(todo, fp);
- puttzcode(corr[i], fp);
- }
- for (i = 0; i < typecnt; ++i)
- if (writetype[i])
- (void) putc(ttisstds[i], fp);
- for (i = 0; i < typecnt; ++i)
- if (writetype[i])
- (void) putc(ttisgmts[i], fp);
- }
- (void) fprintf(fp, "\n%s\n", string);
- if (ferror(fp) || fclose(fp))
- errx(EXIT_FAILURE, _("error writing %s"), fullname);
- if (chmod(fullname, mflag) < 0)
- err(EXIT_FAILURE, _("cannot change mode of %s to %03o"),
- fullname, (unsigned)mflag);
- if ((uflag != (uid_t)-1 || gflag != (gid_t)-1)
- && chown(fullname, uflag, gflag) < 0)
- err(EXIT_FAILURE, _("cannot change ownership of %s"),
- fullname);
-}
-
-static void
-doabbr(abbr, format, letters, isdst, doquotes)
-char * const abbr;
-const char * const format;
-const char * const letters;
-const int isdst;
-const int doquotes;
-{
- register char * cp;
- register char * slashp;
- register int len;
-
- slashp = strchr(format, '/');
- if (slashp == NULL) {
- if (letters == NULL)
- (void) strcpy(abbr, format);
- else (void) sprintf(abbr, format, letters);
- } else if (isdst) {
- (void) strcpy(abbr, slashp + 1);
- } else {
- if (slashp > format)
- (void) strncpy(abbr, format,
- (unsigned) (slashp - format));
- abbr[slashp - format] = '\0';
- }
- if (!doquotes)
- return;
- for (cp = abbr; *cp != '\0'; ++cp)
- if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL &&
- strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL)
- break;
- len = strlen(abbr);
- if (len > 0 && *cp == '\0')
- return;
- abbr[len + 2] = '\0';
- abbr[len + 1] = '>';
- for ( ; len > 0; --len)
- abbr[len] = abbr[len - 1];
- abbr[0] = '<';
-}
-
-static void
-updateminmax(x)
-const int x;
-{
- if (min_year > x)
- min_year = x;
- if (max_year < x)
- max_year = x;
-}
-
-static int
-stringoffset(result, offset)
-char * result;
-long offset;
-{
- register int hours;
- register int minutes;
- register int seconds;
-
- result[0] = '\0';
- if (offset < 0) {
- (void) strcpy(result, "-");
- offset = -offset;
- }
- seconds = offset % SECSPERMIN;
- offset /= SECSPERMIN;
- minutes = offset % MINSPERHOUR;
- offset /= MINSPERHOUR;
- hours = offset;
- if (hours >= HOURSPERDAY) {
- result[0] = '\0';
- return -1;
- }
- (void) sprintf(end(result), "%d", hours);
- if (minutes != 0 || seconds != 0) {
- (void) sprintf(end(result), ":%02d", minutes);
- if (seconds != 0)
- (void) sprintf(end(result), ":%02d", seconds);
- }
- return 0;
-}
-
-static int
-stringrule(result, rp, dstoff, gmtoff)
-char * result;
-const struct rule * const rp;
-const long dstoff;
-const long gmtoff;
-{
- register long tod;
-
- result = end(result);
- if (rp->r_dycode == DC_DOM) {
- register int month, total;
-
- if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY)
- return -1;
- total = 0;
- for (month = 0; month < rp->r_month; ++month)
- total += len_months[0][month];
- (void) sprintf(result, "J%d", total + rp->r_dayofmonth);
- } else {
- register int week;
-
- if (rp->r_dycode == DC_DOWGEQ) {
- week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
- if ((week - 1) * DAYSPERWEEK + 1 != rp->r_dayofmonth)
- return -1;
- } else if (rp->r_dycode == DC_DOWLEQ) {
- if (rp->r_dayofmonth == len_months[1][rp->r_month])
- week = 5;
- else {
- week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
- if (week * DAYSPERWEEK - 1 != rp->r_dayofmonth)
- return -1;
- }
- } else return -1; /* "cannot happen" */
- (void) sprintf(result, "M%d.%d.%d",
- rp->r_month + 1, week, rp->r_wday);
- }
- tod = rp->r_tod;
- if (rp->r_todisgmt)
- tod += gmtoff;
- if (rp->r_todisstd && rp->r_stdoff == 0)
- tod += dstoff;
- if (tod < 0) {
- result[0] = '\0';
- return -1;
- }
- if (tod != 2 * SECSPERMIN * MINSPERHOUR) {
- (void) strcat(result, "/");
- if (stringoffset(end(result), tod) != 0)
- return -1;
- }
- return 0;
-}
-
-static void
-stringzone(result, zpfirst, zonecount)
-char * result;
-const struct zone * const zpfirst;
-const int zonecount;
-{
- register const struct zone * zp;
- register struct rule * rp;
- register struct rule * stdrp;
- register struct rule * dstrp;
- register int i;
- register const char * abbrvar;
-
- result[0] = '\0';
- zp = zpfirst + zonecount - 1;
- stdrp = dstrp = NULL;
- for (i = 0; i < zp->z_nrules; ++i) {
- rp = &zp->z_rules[i];
- if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX)
- continue;
- if (rp->r_yrtype != NULL)
- continue;
- if (rp->r_stdoff == 0) {
- if (stdrp == NULL)
- stdrp = rp;
- else return;
- } else {
- if (dstrp == NULL)
- dstrp = rp;
- else return;
- }
- }
- if (stdrp == NULL && dstrp == NULL) {
- /*
- ** There are no rules running through "max".
- ** Let's find the latest rule.
- */
- for (i = 0; i < zp->z_nrules; ++i) {
- rp = &zp->z_rules[i];
- if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear ||
- (rp->r_hiyear == stdrp->r_hiyear &&
- rp->r_month > stdrp->r_month))
- stdrp = rp;
- }
- if (stdrp != NULL && stdrp->r_stdoff != 0)
- return; /* We end up in DST (a POSIX no-no). */
- /*
- ** Horrid special case: if year is 2037,
- ** presume this is a zone handled on a year-by-year basis;
- ** do not try to apply a rule to the zone.
- */
- if (stdrp != NULL && stdrp->r_hiyear == 2037)
- return;
- }
- if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_stdoff != 0))
- return;
- abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
- doabbr(result, zp->z_format, abbrvar, FALSE, TRUE);
- if (stringoffset(end(result), -zp->z_gmtoff) != 0) {
- result[0] = '\0';
- return;
- }
- if (dstrp == NULL)
- return;
- doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE);
- if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR)
- if (stringoffset(end(result),
- -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) {
- result[0] = '\0';
- return;
- }
- (void) strcat(result, ",");
- if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
- result[0] = '\0';
- return;
- }
- (void) strcat(result, ",");
- if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
- result[0] = '\0';
- return;
- }
-}
-
-static void
-outzone(zpfirst, zonecount)
-const struct zone * const zpfirst;
-const int zonecount;
-{
- register const struct zone * zp;
- register struct rule * rp;
- register int i, j;
- register int usestart, useuntil;
- register zic_t starttime, untiltime;
- register long gmtoff;
- register long stdoff;
- register int year;
- register long startoff;
- register int startttisstd;
- register int startttisgmt;
- register int type;
- register char * startbuf;
- register char * ab;
- register char * envvar;
- register int max_abbr_len;
- register int max_envvar_len;
-
- max_abbr_len = 2 + max_format_len + max_abbrvar_len;
- max_envvar_len = 2 * max_abbr_len + 5 * 9;
- startbuf = emalloc(max_abbr_len + 1);
- ab = emalloc(max_abbr_len + 1);
- envvar = emalloc(max_envvar_len + 1);
- INITIALIZE(untiltime);
- INITIALIZE(starttime);
- /*
- ** Now. . .finally. . .generate some useful data!
- */
- timecnt = 0;
- typecnt = 0;
- charcnt = 0;
- /*
- ** Thanks to Earl Chew
- ** for noting the need to unconditionally initialize startttisstd.
- */
- startttisstd = FALSE;
- startttisgmt = FALSE;
- min_year = max_year = EPOCH_YEAR;
- if (leapseen) {
- updateminmax(leapminyear);
- updateminmax(leapmaxyear + (leapmaxyear < INT_MAX));
- }
- for (i = 0; i < zonecount; ++i) {
- zp = &zpfirst[i];
- if (i < zonecount - 1)
- updateminmax(zp->z_untilrule.r_loyear);
- for (j = 0; j < zp->z_nrules; ++j) {
- rp = &zp->z_rules[j];
- if (rp->r_lowasnum)
- updateminmax(rp->r_loyear);
- if (rp->r_hiwasnum)
- updateminmax(rp->r_hiyear);
- }
- }
- /*
- ** Generate lots of data if a rule can't cover all future times.
- */
- stringzone(envvar, zpfirst, zonecount);
- if (noise && envvar[0] == '\0') {
- register char * wp;
-
-wp = ecpyalloc(_("no POSIX environment variable for zone"));
- wp = ecatalloc(wp, " ");
- wp = ecatalloc(wp, zpfirst->z_name);
- warning(wp);
- ifree(wp);
- }
- if (envvar[0] == '\0') {
- if (min_year >= INT_MIN + YEARSPERREPEAT)
- min_year -= YEARSPERREPEAT;
- else min_year = INT_MIN;
- if (max_year <= INT_MAX - YEARSPERREPEAT)
- max_year += YEARSPERREPEAT;
- else max_year = INT_MAX;
- }
- /*
- ** For the benefit of older systems,
- ** generate data from 1900 through 2037.
- */
- if (min_year > 1900)
- min_year = 1900;
- if (max_year < 2037)
- max_year = 2037;
- for (i = 0; i < zonecount; ++i) {
- /*
- ** A guess that may well be corrected later.
- */
- stdoff = 0;
- zp = &zpfirst[i];
- usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
- useuntil = i < (zonecount - 1);
- if (useuntil && zp->z_untiltime <= min_time)
- continue;
- gmtoff = zp->z_gmtoff;
- eat(zp->z_filename, zp->z_linenum);
- *startbuf = '\0';
- startoff = zp->z_gmtoff;
- if (zp->z_nrules == 0) {
- stdoff = zp->z_stdoff;
- doabbr(startbuf, zp->z_format,
- (char *) NULL, stdoff != 0, FALSE);
- type = addtype(oadd(zp->z_gmtoff, stdoff),
- startbuf, stdoff != 0, startttisstd,
- startttisgmt);
- if (usestart) {
- addtt(starttime, type);
- usestart = FALSE;
- } else if (stdoff != 0)
- addtt(min_time, type);
- } else for (year = min_year; year <= max_year; ++year) {
- if (useuntil && year > zp->z_untilrule.r_hiyear)
- break;
- /*
- ** Mark which rules to do in the current year.
- ** For those to do, calculate rpytime(rp, year);
- */
- for (j = 0; j < zp->z_nrules; ++j) {
- rp = &zp->z_rules[j];
- eats(zp->z_filename, zp->z_linenum,
- rp->r_filename, rp->r_linenum);
- rp->r_todo = year >= rp->r_loyear &&
- year <= rp->r_hiyear &&
- yearistype(year, rp->r_yrtype);
- if (rp->r_todo)
- rp->r_temp = rpytime(rp, year);
- }
- for ( ; ; ) {
- register int k;
- register zic_t jtime, ktime;
- register long offset;
-
- INITIALIZE(ktime);
- if (useuntil) {
- /*
- ** Turn untiltime into UTC
- ** assuming the current gmtoff and
- ** stdoff values.
- */
- untiltime = zp->z_untiltime;
- if (!zp->z_untilrule.r_todisgmt)
- untiltime = tadd(untiltime,
- -gmtoff);
- if (!zp->z_untilrule.r_todisstd)
- untiltime = tadd(untiltime,
- -stdoff);
- }
- /*
- ** Find the rule (of those to do, if any)
- ** that takes effect earliest in the year.
- */
- k = -1;
- for (j = 0; j < zp->z_nrules; ++j) {
- rp = &zp->z_rules[j];
- if (!rp->r_todo)
- continue;
- eats(zp->z_filename, zp->z_linenum,
- rp->r_filename, rp->r_linenum);
- offset = rp->r_todisgmt ? 0 : gmtoff;
- if (!rp->r_todisstd)
- offset = oadd(offset, stdoff);
- jtime = rp->r_temp;
- if (jtime == min_time ||
- jtime == max_time)
- continue;
- jtime = tadd(jtime, -offset);
- if (k < 0 || jtime < ktime) {
- k = j;
- ktime = jtime;
- }
- }
- if (k < 0)
- break; /* go on to next year */
- rp = &zp->z_rules[k];
- rp->r_todo = FALSE;
- if (useuntil && ktime >= untiltime)
- break;
- stdoff = rp->r_stdoff;
- if (usestart && ktime == starttime)
- usestart = FALSE;
- if (usestart) {
- if (ktime < starttime) {
- startoff = oadd(zp->z_gmtoff,
- stdoff);
- doabbr(startbuf, zp->z_format,
- rp->r_abbrvar,
- rp->r_stdoff != 0,
- FALSE);
- continue;
- }
- if (*startbuf == '\0' &&
- startoff == oadd(zp->z_gmtoff,
- stdoff)) {
- doabbr(startbuf,
- zp->z_format,
- rp->r_abbrvar,
- rp->r_stdoff !=
- 0,
- FALSE);
- }
- }
- eats(zp->z_filename, zp->z_linenum,
- rp->r_filename, rp->r_linenum);
- doabbr(ab, zp->z_format, rp->r_abbrvar,
- rp->r_stdoff != 0, FALSE);
- offset = oadd(zp->z_gmtoff, rp->r_stdoff);
- type = addtype(offset, ab, rp->r_stdoff != 0,
- rp->r_todisstd, rp->r_todisgmt);
- addtt(ktime, type);
- }
- }
- if (usestart) {
- if (*startbuf == '\0' &&
- zp->z_format != NULL &&
- strchr(zp->z_format, '%') == NULL &&
- strchr(zp->z_format, '/') == NULL)
- (void) strcpy(startbuf, zp->z_format);
- eat(zp->z_filename, zp->z_linenum);
- if (*startbuf == '\0')
-error(_("can't determine time zone abbreviation to use just after until time"));
- else addtt(starttime,
- addtype(startoff, startbuf,
- startoff != zp->z_gmtoff,
- startttisstd,
- startttisgmt));
- }
- /*
- ** Now we may get to set starttime for the next zone line.
- */
- if (useuntil) {
- startttisstd = zp->z_untilrule.r_todisstd;
- startttisgmt = zp->z_untilrule.r_todisgmt;
- starttime = zp->z_untiltime;
- if (!startttisstd)
- starttime = tadd(starttime, -stdoff);
- if (!startttisgmt)
- starttime = tadd(starttime, -gmtoff);
- }
- }
- writezone(zpfirst->z_name, envvar);
- ifree(startbuf);
- ifree(ab);
- ifree(envvar);
-}
-
-static void
-addtt(starttime, type)
-const zic_t starttime;
-int type;
-{
- if (starttime <= min_time ||
- (timecnt == 1 && attypes[0].at < min_time)) {
- gmtoffs[0] = gmtoffs[type];
- isdsts[0] = isdsts[type];
- ttisstds[0] = ttisstds[type];
- ttisgmts[0] = ttisgmts[type];
- if (abbrinds[type] != 0)
- (void) strcpy(chars, &chars[abbrinds[type]]);
- abbrinds[0] = 0;
- charcnt = strlen(chars) + 1;
- typecnt = 1;
- timecnt = 0;
- type = 0;
- }
- if (timecnt >= TZ_MAX_TIMES) {
- error(_("too many transitions?!"));
- exit(EXIT_FAILURE);
- }
- attypes[timecnt].at = starttime;
- attypes[timecnt].type = type;
- ++timecnt;
-}
-
-static int
-addtype(gmtoff, abbr, isdst, ttisstd, ttisgmt)
-const long gmtoff;
-const char * const abbr;
-const int isdst;
-const int ttisstd;
-const int ttisgmt;
-{
- register int i, j;
-
- if (isdst != TRUE && isdst != FALSE) {
- error(_("internal error - addtype called with bad isdst"));
- exit(EXIT_FAILURE);
- }
- if (ttisstd != TRUE && ttisstd != FALSE) {
- error(_("internal error - addtype called with bad ttisstd"));
- exit(EXIT_FAILURE);
- }
- if (ttisgmt != TRUE && ttisgmt != FALSE) {
- error(_("internal error - addtype called with bad ttisgmt"));
- exit(EXIT_FAILURE);
- }
- /*
- ** See if there's already an entry for this zone type.
- ** If so, just return its index.
- */
- for (i = 0; i < typecnt; ++i) {
- if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
- strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
- ttisstd == ttisstds[i] &&
- ttisgmt == ttisgmts[i])
- return i;
- }
- /*
- ** There isn't one; add a new one, unless there are already too
- ** many.
- */
- if (typecnt >= TZ_MAX_TYPES) {
- error(_("too many local time types"));
- exit(EXIT_FAILURE);
- }
- if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) {
- error(_("UTC offset out of range"));
- exit(EXIT_FAILURE);
- }
- gmtoffs[i] = gmtoff;
- isdsts[i] = isdst;
- ttisstds[i] = ttisstd;
- ttisgmts[i] = ttisgmt;
-
- for (j = 0; j < charcnt; ++j)
- if (strcmp(&chars[j], abbr) == 0)
- break;
- if (j == charcnt)
- newabbr(abbr);
- abbrinds[i] = j;
- ++typecnt;
- return i;
-}
-
-static void
-leapadd(t, positive, rolling, count)
-const zic_t t;
-const int positive;
-const int rolling;
-int count;
-{
- register int i, j;
-
- if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) {
- error(_("too many leap seconds"));
- exit(EXIT_FAILURE);
- }
- for (i = 0; i < leapcnt; ++i)
- if (t <= trans[i]) {
- if (t == trans[i]) {
- error(_("repeated leap second moment"));
- exit(EXIT_FAILURE);
- }
- break;
- }
- do {
- for (j = leapcnt; j > i; --j) {
- trans[j] = trans[j - 1];
- corr[j] = corr[j - 1];
- roll[j] = roll[j - 1];
- }
- trans[i] = t;
- corr[i] = positive ? 1L : eitol(-count);
- roll[i] = rolling;
- ++leapcnt;
- } while (positive && --count != 0);
-}
-
-static void
-adjleap(void)
-{
- register int i;
- register long last = 0;
-
- /*
- ** propagate leap seconds forward
- */
- for (i = 0; i < leapcnt; ++i) {
- trans[i] = tadd(trans[i], last);
- last = corr[i] += last;
- }
-}
-
-static int
-yearistype(year, type)
-const int year;
-const char * const type;
-{
- static char * buf;
- int result;
-
- if (type == NULL || *type == '\0')
- return TRUE;
- buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type)));
- (void) sprintf(buf, "%s %d %s", yitcommand, year, type);
- result = system(buf);
- if (WIFEXITED(result)) switch (WEXITSTATUS(result)) {
- case 0:
- return TRUE;
- case 1:
- return FALSE;
- }
- error(_("wild result from command execution"));
- warnx(_("command was '%s', result was %d"), buf, result);
- for ( ; ; )
- exit(EXIT_FAILURE);
-}
-
-static int
-lowerit(a)
-int a;
-{
- a = (unsigned char) a;
- return (isascii(a) && isupper(a)) ? tolower(a) : a;
-}
-
-static int
-ciequal(ap, bp) /* case-insensitive equality */
-register const char * ap;
-register const char * bp;
-{
- while (lowerit(*ap) == lowerit(*bp++))
- if (*ap++ == '\0')
- return TRUE;
- return FALSE;
-}
-
-static int
-itsabbr(abbr, word)
-register const char * abbr;
-register const char * word;
-{
- if (lowerit(*abbr) != lowerit(*word))
- return FALSE;
- ++word;
- while (*++abbr != '\0')
- do {
- if (*word == '\0')
- return FALSE;
- } while (lowerit(*word++) != lowerit(*abbr));
- return TRUE;
-}
-
-static const struct lookup *
-byword(word, table)
-register const char * const word;
-register const struct lookup * const table;
-{
- register const struct lookup * foundlp;
- register const struct lookup * lp;
-
- if (word == NULL || table == NULL)
- return NULL;
- /*
- ** Look for exact match.
- */
- for (lp = table; lp->l_word != NULL; ++lp)
- if (ciequal(word, lp->l_word))
- return lp;
- /*
- ** Look for inexact match.
- */
- foundlp = NULL;
- for (lp = table; lp->l_word != NULL; ++lp)
- if (itsabbr(word, lp->l_word)) {
- if (foundlp == NULL)
- foundlp = lp;
- else return NULL; /* multiple inexact matches */
- }
- return foundlp;
-}
-
-static char **
-getfields(cp)
-register char * cp;
-{
- register char * dp;
- register char ** array;
- register int nsubs;
-
- if (cp == NULL)
- return NULL;
- array = (char **) (void *)
- emalloc((int) ((strlen(cp) + 1) * sizeof *array));
- nsubs = 0;
- for ( ; ; ) {
- while (isascii((unsigned char) *cp) &&
- isspace((unsigned char) *cp))
- ++cp;
- if (*cp == '\0' || *cp == '#')
- break;
- array[nsubs++] = dp = cp;
- do {
- if ((*dp = *cp++) != '"')
- ++dp;
- else while ((*dp = *cp++) != '"')
- if (*dp != '\0')
- ++dp;
- else {
- error(_("odd number of quotation marks"));
- exit(EXIT_FAILURE);
- }
- } while (*cp != '\0' && *cp != '#' &&
- (!isascii(*cp) || !isspace((unsigned char) *cp)));
- if (isascii(*cp) && isspace((unsigned char) *cp))
- ++cp;
- *dp = '\0';
- }
- array[nsubs] = NULL;
- return array;
-}
-
-static long
-oadd(t1, t2)
-const long t1;
-const long t2;
-{
- register long t;
-
- t = t1 + t2;
- if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
- error(_("time overflow"));
- exit(EXIT_FAILURE);
- }
- return t;
-}
-
-static zic_t
-tadd(t1, t2)
-const zic_t t1;
-const long t2;
-{
- register zic_t t;
-
- if (t1 == max_time && t2 > 0)
- return max_time;
- if (t1 == min_time && t2 < 0)
- return min_time;
- t = t1 + t2;
- if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
- error(_("time overflow"));
- exit(EXIT_FAILURE);
- }
- return t;
-}
-
-/*
-** Given a rule, and a year, compute the date - in seconds since January 1,
-** 1970, 00:00 LOCAL time - in that year that the rule refers to.
-*/
-
-static zic_t
-rpytime(rp, wantedy)
-register const struct rule * const rp;
-register const int wantedy;
-{
- register int y, m, i;
- register long dayoff; /* with a nod to Margaret O. */
- register zic_t t;
-
- if (wantedy == INT_MIN)
- return min_time;
- if (wantedy == INT_MAX)
- return max_time;
- dayoff = 0;
- m = TM_JANUARY;
- y = EPOCH_YEAR;
- while (wantedy != y) {
- if (wantedy > y) {
- i = len_years[isleap(y)];
- ++y;
- } else {
- --y;
- i = -len_years[isleap(y)];
- }
- dayoff = oadd(dayoff, eitol(i));
- }
- while (m != rp->r_month) {
- i = len_months[isleap(y)][m];
- dayoff = oadd(dayoff, eitol(i));
- ++m;
- }
- i = rp->r_dayofmonth;
- if (m == TM_FEBRUARY && i == 29 && !isleap(y)) {
- if (rp->r_dycode == DC_DOWLEQ)
- --i;
- else {
- error(_("use of 2/29 in non leap-year"));
- exit(EXIT_FAILURE);
- }
- }
- --i;
- dayoff = oadd(dayoff, eitol(i));
- if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {
- register long wday;
-
-#define LDAYSPERWEEK ((long) DAYSPERWEEK)
- wday = eitol(EPOCH_WDAY);
- /*
- ** Don't trust mod of negative numbers.
- */
- if (dayoff >= 0)
- wday = (wday + dayoff) % LDAYSPERWEEK;
- else {
- wday -= ((-dayoff) % LDAYSPERWEEK);
- if (wday < 0)
- wday += LDAYSPERWEEK;
- }
- while (wday != eitol(rp->r_wday))
- if (rp->r_dycode == DC_DOWGEQ) {
- dayoff = oadd(dayoff, (long) 1);
- if (++wday >= LDAYSPERWEEK)
- wday = 0;
- ++i;
- } else {
- dayoff = oadd(dayoff, (long) -1);
- if (--wday < 0)
- wday = LDAYSPERWEEK - 1;
- --i;
- }
- if (i < 0 || i >= len_months[isleap(y)][m]) {
- if (noise)
- warning(_("rule goes past start/end of month--\
-will not work with pre-2004 versions of zic"));
- }
- }
- if (dayoff < min_time / SECSPERDAY)
- return min_time;
- if (dayoff > max_time / SECSPERDAY)
- return max_time;
- t = (zic_t) dayoff * SECSPERDAY;
- return tadd(t, rp->r_tod);
-}
-
-static void
-newabbr(string)
-const char * const string;
-{
- register int i;
-
- if (strcmp(string, GRANDPARENTED) != 0) {
- register const char * cp;
- register char * wp;
-
- /*
- ** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics
- ** optionally followed by a + or - and a number from 1 to 14.
- */
- cp = string;
- wp = NULL;
- while (isascii((unsigned char) *cp) &&
- isalpha((unsigned char) *cp))
- ++cp;
- if (cp - string == 0)
-wp = _("time zone abbreviation lacks alphabetic at start");
- if (noise && cp - string > 3)
-wp = _("time zone abbreviation has more than 3 alphabetics");
- if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN)
-wp = _("time zone abbreviation has too many alphabetics");
- if (wp == NULL && (*cp == '+' || *cp == '-')) {
- ++cp;
- if (isascii((unsigned char) *cp) &&
- isdigit((unsigned char) *cp))
- if (*cp++ == '1' &&
- *cp >= '0' && *cp <= '4')
- ++cp;
- }
- if (*cp != '\0')
-wp = _("time zone abbreviation differs from POSIX standard");
- if (wp != NULL) {
- wp = ecpyalloc(wp);
- wp = ecatalloc(wp, " (");
- wp = ecatalloc(wp, string);
- wp = ecatalloc(wp, ")");
- warning(wp);
- ifree(wp);
- }
- }
- i = strlen(string) + 1;
- if (charcnt + i > TZ_MAX_CHARS) {
- error(_("too many, or too long, time zone abbreviations"));
- exit(EXIT_FAILURE);
- }
- (void) strcpy(&chars[charcnt], string);
- charcnt += eitol(i);
-}
-
-static int
-mkdirs(argname)
-char * argname;
-{
- register char * name;
- register char * cp;
-
- if (argname == NULL || *argname == '\0' || Dflag)
- return 0;
- cp = name = ecpyalloc(argname);
- while ((cp = strchr(cp + 1, '/')) != 0) {
- *cp = '\0';
-#ifndef unix
- /*
- ** DOS drive specifier?
- */
- if (isalpha((unsigned char) name[0]) &&
- name[1] == ':' && name[2] == '\0') {
- *cp = '/';
- continue;
- }
-#endif /* !defined unix */
- if (!itsdir(name)) {
- /*
- ** It doesn't seem to exist, so we try to create it.
- ** Creation may fail because of the directory being
- ** created by some other multiprocessor, so we get
- ** to do extra checking.
- */
- if (mkdir(name, MKDIR_UMASK) != 0
- && (errno != EEXIST || !itsdir(name))) {
- warn(_("can't create directory %s"), name);
- ifree(name);
- return -1;
- }
- }
- *cp = '/';
- }
- ifree(name);
- return 0;
-}
-
-static long
-eitol(i)
-const int i;
-{
- long l;
-
- l = i;
- if ((i < 0 && l >= 0) || (i == 0 && l != 0) || (i > 0 && l <= 0))
- errx(EXIT_FAILURE, _("%d did not sign extend correctly"), i);
- return l;
-}
-
-#include <grp.h>
-#include <pwd.h>
-
-static void
-setgroup(flag, name)
- gid_t *flag;
- const char *name;
-{
- struct group *gr;
-
- if (*flag != (gid_t)-1)
- errx(EXIT_FAILURE, _("multiple -g flags specified"));
-
- gr = getgrnam(name);
- if (gr == 0) {
- char *ep;
- unsigned long ul;
-
- ul = strtoul(name, &ep, 10);
- if (ul == (unsigned long)(gid_t)ul && *ep == '\0') {
- *flag = ul;
- return;
- }
- errx(EXIT_FAILURE, _("group `%s' not found"), name);
- }
- *flag = gr->gr_gid;
-}
-
-static void
-setuser(flag, name)
- uid_t *flag;
- const char *name;
-{
- struct passwd *pw;
-
- if (*flag != (gid_t)-1)
- errx(EXIT_FAILURE, _("multiple -u flags specified"));
-
- pw = getpwnam(name);
- if (pw == 0) {
- char *ep;
- unsigned long ul;
-
- ul = strtoul(name, &ep, 10);
- if (ul == (unsigned long)(gid_t)ul && *ep == '\0') {
- *flag = ul;
- return;
- }
- errx(EXIT_FAILURE, _("user `%s' not found"), name);
- }
- *flag = pw->pw_uid;
-}
-
-/*
-** UNIX was a registered trademark of The Open Group in 2003.
-*/
diff --git a/usr.sbin/zic/zic/Makefile b/usr.sbin/zic/zic/Makefile
index 3f3bc70..f473da5 100644
--- a/usr.sbin/zic/zic/Makefile
+++ b/usr.sbin/zic/zic/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/..
+.PATH: ${.CURDIR}/../../../contrib/tzcode/zic
PROG= zic
MAN= zic.8
@@ -9,6 +9,8 @@ SRCS= zic.c ialloc.c scheck.c
CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS
CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"/usr/share/zoneinfo\" -Demkdir=mkdir
CFLAGS+= -DHAVE_STRERROR -DHAVE_UNISTD_H
-CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../lib/libc/stdtime
+CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../contrib/tzcode/stdtime
+
+WARNS?= 2
.include <bsd.prog.mk>
OpenPOWER on IntegriCloud